redis
2020-05-20 17:51:01 2 举报
AI智能生成
登录查看完整内容
redis学习笔记
作者其他创作
大纲/内容
redis
集群知识
单点的问题
单点故障
容量有限
压力大(CPU,链接)
AKF
x轴:备份数据。全量、镜像
y轴:按业务、功能进行划分,将数据存到不同节点
z轴:对同个业务的数据进行分片
图片
C一致性
数据一致性问题
写操作时,所有节点写操作成功后,再给client返回---强一致性。但如果强一致,又会破坏可用性
弱一致性,主节点异步向从节点同步数据
子主题
A高可用
主从 and 主备
主从,从节点会有读请求
主备,备机单纯备份数据
HA
通过监控,将备机节点切换成主节点
监控节点至少要3个且为奇数,发生问题时至少要一半以上监控节点确诊
P分区容错性
以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
replica-serve-state-data yes
redis刚启动,要追随主时:决定是否要同步完数据,才允许读取旧数据
replica-read-only yes
备机是否只支持查询
repl-diskless-sync no
向从节点同步数据的方式。改成no时默认走2次磁盘,yes则直接走网络
三种集群模型(只适合缓存)
hash取模法
缺点:新增节点时需全部重置
random lpush + rpop
场景特殊,适用队列
一致性哈希算法(倾向于缓存而不是数据库,并且实现在client)
适合数据库的,也是redis自带的
对数据key分slot(槽位)存放,每个节点只存一部分slot的数据
每次拿数据,都随机请求一节点,如果该数据不再该节点上,则告诉客户端去请求哪个节点
缺点:不支持跨节点对多key求交集等操作。解决方案:对key打tag,可使他们再同一个slot上
redis代理
predixy
twemproxy
codis
redis-cerberus
缓存三个问题
缓存击穿
数据库有,缓存没有
步骤
解决办法(由第一个请求去加载数据,其他请求等待)
1.get key
2.setnx key1//枷锁
3.1去数据库查数据
3.2 sleep下,然后回到1
问题点
第一个请求挂了?设置锁的超时时间
没挂,但是锁超时了?
多线程一个线程取DB一个线程监控是否取回来。更新锁时间
缓存穿透
缓存没有,数据库也没有
布隆过滤器
问题点:只能增不能删
又换着空key
布谷鸟过滤器
缓存雪崩
大批缓存数据同时过期,大量请求到数据库,导致数据库压力过大
过期时间随机化
redis如何做分布式锁?
1.setnx
2.过期时间
3.多线程(守护线程)延长过期时间
value数据类型
String
整型
秒杀计数等
常用命令
INCR key 执行原子加1操作
INCRBY key increment 执行原子增加一个整数
INCRBYFLOAT key increment 执行原子增加一个浮点数
bitmaps位图
用途
统计文章点赞数
bitcount key [start end]
统计被标记为1的bit数
SETBIT key offset value
设置或者清空key的value(字符串)在offset处的bit值
GETBIT key offset
BITOP operation destkey key [key ...]
对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上
BITOP AND dest key1 key2
BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中
BITPOS key bit [start] [end]
返回字符串里面第一个被设置为1或者0的bit位
BITPOS mykey 1 2 # 查找字符串里面bit值为1从第2个字节(12)开始的位置
SETNX key value
将key设置值为value,如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做。
SETEX key seconds value
设置key对应字符串value,并且设置key在给定的seconds时间之后超时过期
MGET key [key ...] 一次获取多个key值
MSET key value [key value ...]
对应给定的keys到他们相应的values上
MSETNX key value [key value ...]
对应给定的keys到他们相应的values上。只要有一个key已经存在,MSETNX一个操作都不会执行。
GETRANGE key start end
获取存储在key上的值的一个子字符串
strlen key 获取指定key值的长度
SETRANGE key offset value
这个命令的作用是覆盖key对应的string的一部分,从指定的offset处开始,覆盖value的长度。如果offset比当前key对应string还要长,那这个string后面就补0以达到offset。不存在的keys被认为是空字符串,所以这个命令可以确保key有一个足够大的字符串,能在offset处设置value
hashes
HGET key field 获取hash中field的值
HMGET key field [field...]获取hash里面指定字段的值
HVALS key 获取hash的所有值
HSET key field value 设置hash里面一个字段的值
HSETNX key field value 设置一个hash的一个子弹,只有当这个字段不存在时有效
HMSET key field value [field value ...]
设置 key 指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联
HDEL key field [field...] 删除一个或多个hash的field
HEXISTS key field 判断field是否存在于hash中
HGETALL key 从hash中读取全部的域和值
HINCRBY key field increment
将hash中指定域的值增加给定的数字
HINCRBYFLOAT key field increment
将hash中指定域的值增加给定的浮点数
HKEYS key 获取hash的所有字段
HLEN key 获取hash里所有字段的数量
HSTRLEN key field 获取field值的长度
list
BLPOP key [key ...] timeout
删除,并获得该列表中的第一元素,或阻塞,直到有一个可用
BRPOP key [key ...] timeout
删除,并获得该列表中的最后一个元素,或阻塞,直到有一个可用
BRPOPLPUSH source destination timeout
BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本。 当 source 包含元素的时候,这个命令表现得跟 RPOPLPUSH 一模一样。 当 source 是空的时候,Redis将会阻塞这个连接,直到另一个客户端 push 元素进入或者达到 timeout 时限。 timeout 为 0 能用于无限期阻塞客户端
LINDEX key index
通过索引获取一个元素
LINSERT key BEFORE|AFTER pivot value
把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。当 key 不存在时,这个list会被看作是空list,任何操作都不会发生。当 key 存在,但保存的不是一个list的时候,会返回error。
LLEN key
获取队列的长度
LPOP key
从队列左边出队一个元素
LPUSH key value [value ...]
从队列的左边入队一个或多个元素
LPUSHX key value
当队列存在时,从队列左入队一个元素
LRANGE key start stop
从列表中获取指定返回的元素
LREM key count vale
从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作:count > 0: 从头往尾移除值为 value 的元素。count < 0: 从尾往头移除值为 value 的元素。count = 0: 移除所有值为 value 的元素
LSET key index value
设置队列里面一个索引的值
LTRIM key start stop
修剪(trim)一个已存在的 list,这样 list 就会只包含指定范围的指定元素。start 和 stop 都是由0开始计数的, 这里的 0 是列表里的第一个元素(表头),1 是第二个元素,以此类推。例如: LTRIM foobar 0 2 将会对存储在 foobar 的列表进行修剪,只保留列表里的前3个元素
RPOP key
从队列右边出队一个元素
原子性地返回并移除存储在 source 的列表的最后一个元素(列表尾部元素), 并把该元素放入存储在 destination 的列表的第一个元素位置(列表头部)。
RPOPLPUSH source destination
原子性地返回并移除存储在 source 的列表的最后一个元素(列表尾部元素), 并把该元素放入存储在 destination 的列表的第一个元素位置(列表头部)
RPUSH key value [value ...]
从队列的右边入队一个元素
RPUSHX key value
从队列的右边入队一个元素,仅队列存在时有效
可用于消息队列
set
SADD key member [member ...]
添加一个或多个元素到set里
SCARD key
获取集合里面的元素数量
SDIFF key [key ...]
返回一个集合与给定集合的差集的元素.
SDIFFSTORE destination key [key ...]
SINTER key [key ...]
获取两个集合的交集
SINTERSTORE destination key [key ...]
SISMEMBER key member
返回成员 member 是否是存储的集合 key的成员.
SMEMBERS key
获取集合里的所有元素
SMOVE source destination member
SPOP key [count]
从存储在key的集合中移除并返回一个或多个随机元素。此操作与SRANDMEMBER类似,它从一个集合中返回一个或多个随机元素,但不删除元素。count参数将在更高版本中提供,但是在2.6、2.8、3.0中不可用
SRANDMEMBER key [count]
仅提供key参数,那么随机返回key集合中的一个元素.Redis 2.6开始,可以接受 count 参数,如果count是整数且小于元素的个数,返回含有 count 个不同的元素的数组,如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,当count是负数,则会返回一个包含count的绝对值的个数元素的数组,如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.仅提供key参数时,该命令作用类似于SPOP命令,不同的是SPOP命令会将被选择的随机元素从集合中移除,而SRANDMEMBER仅仅是返回该随记元素,而不做任何操作.
SREM key member [member ...]
SUNION key [key ...]
返回给定的多个集合的并集中的所有成员.
SUNIONSTORE destination key [key ...]
sort set
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
XX: 仅仅更新存在的成员,不添加新成员。NX: 不更新存在的成员。只添加新成员。CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。
ZCARD key
获取集合中的元素个数
ZCOUNT min max
返回集合中分数在min和max之间的元素个数
ZINCRBY key increment member
增加一名成员的分数
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [SUM|MIN|MAX]
计算给定的numkeys个有序集合的交集,并且把结果放到destination中。 在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。默认情况下,结果中一个元素的分数是有序集合中该元素分数之和,前提是该元素在这些有序集合中都存在。因为交集要求其成员必须是给定的每个有序集合中的成员,结果集中的每个元素的分数和输入的有序集合个数相等。
zlexcount zset [member1 [member5
ZLEXCOUNT 命令用于计算有序集合中指定成员之间的成员数量。
ZPOPMAX key [count]
删除并返回有序集合key中的最多count个具有最高得分的成员
ZPOPMIN key [count]
删除并返回有序集合key中的最多count个具有最低得分的成员。
ZRANGE key start stop [WITHSCORES]
返回存储在有序集合key中的指定范围的元素。 返回的元素可以认为是按得分从最低到最高排列。 如果得分相同,将按字典排序。
ZRANGEBYLEX key min max [LIMIT offset count]
ZREVRANGEBYLEX key max min [LIMIT offset count]
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回key的有序集合中的分数在min和max之间的所有元素(包括分数等于max或者min的元素)。元素被认为是从低分到高分排序的。
可选参数WITHSCORES会返回元素和其分数,而不只是元素。这个选项在redis2.0之后的版本都可用。##区间及无限min和max可以是-inf和+inf,这样一来,你就可以在不知道有序集的最低和最高score值的情况下,使用ZRANGEBYSCORE这类命令。默认情况下,区间的取值使用闭区间(小于等于或大于等于),你也可以通过给参数前增加(符号来使用可选的开区间(小于或大于)。
ZRANK key member
返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。排名以0为底,也就是说,score值最小的成员排名为0。
ZREM key member [member ...]
删除元素
ZREMRANGEBYLEX key min max
ZREMRANGEBYRANK key start stop
移除有序集key中,指定排名(rank)区间内的所有成员。下标参数start和stop都以0为底,0处是分数最小的那个元素。这些索引也可是负数,表示位移从最高分处开始数。例如,-1是分数最高的元素,-2是分数第二高的,依次类推。
ZREMRANGEBYSCORE key min max
移除有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。
ZREVRANGE key start stop [WITHSCORES]
返回有序集key中,指定区间内(索引0,1,2,3)的成员。其中成员的位置按score值递减(从大到小)来排列。具有相同score值的成员按字典序的反序排列。
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
ZREVRANGEBYSCORE 返回有序集合中指定分数区间内的成员,分数由高到低排序。
ZREVRANK key member
返回有序集key中成员member的排名,其中有序集成员按score值从大到小排列。排名以0为底,也就是说,score值最大的成员排名为0。使用ZRANK命令可以获得成员按score值递增(从小到大)排列的排名
ZSCORE key member
返回有序集key中,成员member的score值。如果member元素不是有序集key的成员,或key不存在,返回nil。
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [SUM|MIN|MAX]
计算给定的numkeys个有序集合的并集,并且把结果放到destination中。在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。 默认情况下,结果集中某个成员的score值是所有给定集下该成员score值之和。使用WEIGHTS选项,你可以为每个给定的有序集指定一个乘法因子,意思就是,每个给定有序集的所有成员的score值在传递给聚合函数之前都要先乘以该因子。如果WEIGHTS没有给定,默认就是1。使用AGGREGATE选项,你可以指定并集的结果集的聚合方式。默认使用的参数SUM,可以将所有集合中某个成员的score值之和作为结果集中该成员的score值。如果使用参数MIN或者MAX,结果集就是所有集合中元素最小或最大的元素。如果key destination存在,就被覆盖。
发布订阅
命令
SUBSCRIBE foo
PUBLISH second Hello
UNSUBSCRIBE
只要订阅了,每个订阅者都会收到消息
事务
以最先提交的事务为准
一个客户端的事务,不会阻碍(阻塞)另一个事务
事务失败时不会进行回滚,redis命令只会因为“人为”的语法错误失败
内存回收策略
介绍:maxmemory配置指令用于配置Redis存储数据时指定限制的内存大小,当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置
配置指令
maxmemory 100mb
如果设置为0,则表示为无限制
maxmemory-policy noeviction
算法知识点
可选策略
noeviction
返回错误
allkeys-lru
尝试回收最少使用的key(LRU)
volatile-lru
尝试回收过期集合中的key(即有设置过期时间的)
allkeys-random
随机回收key
volatile-random
随机回收过期集合中的key
volatile-ttl:
回收过期集合中的key,并且优先回收TTL(剩余有效时间)较短的key
策略选择
将redis作为数据库时,建议选择noeviction策略,因为数据不能丢!
将redis作为缓存使用时,则建议在allkeys-lru和volatile-lru之间选择。
若带有效期的key比较多时,使用volatile-lru
模块module
除了redis本身的功能外,还能添加额外的模块扩展功能
例如布隆过滤器redisbloom.so
作为缓存与数据库的区别
缓存
热点数据,而不是全量数据
数据应该随着访问变化
内存优先,依赖业务来淘汰冷数据
数据库
数据绝对不能丢,速度+持久性
key的有效期
注意点
不会随着访问延长过期时间
发生写操作时,会剔除过期时间
有效期的设置方式除了倒计时,还有定时的方式(命令EXPIREAT)
如何淘汰过期的keys
被动:key被访问时会被发现过期并淘汰
主动,每秒做10次的事
测试随机的20个keys进行过期检测(增量)
删除其中所有过期的keys
如果有多于25%的key过期,重复步骤1
渐进式哈希
https://baijiahao.baidu.com/s?id=1663870339713597715&wfr=spider&for=pc
持久化
RDB
时点性:定时触发快照,例如8点进行了快照,快照里面是没有8点10分数据的
如何快速快照当时的数据?
通过fork子进程来快照。fork子进程,只是复制了一份数据指针,之后如果进程要修改原数据,该修改操作会是写时复制
触发方式
人为手动触发
前台阻塞方式:save
使用场景:关机维护
fork子进程方式:bgsave
配置文件触发bgsave的规则:save这个标识
save <seconds> <changs> 经过了seconds秒后,写次数达到了change是,则进行rdb
弊端
不支持拉链,只有一个dump.rdb
丢数据相对多一些,时点与时点之间窗口数据容易丢失。8点得到一个rdb,9点刚要落一个rdb,挂机了
优点
类似java中的序列化,恢复速度快
AOF
redis的写操作记录到文件中
丢失数据少
rdb和aof可以同时开启
但如果开启了AOF,只会用AOF恢复数据
4.0以后,AOF中包含RDB全量,增加记录的写操作
开启AOF:appendonly no 改为appendonly yes
设置刷新磁盘缓存策略
appendfsync no 内存buffer满了才刷新到磁盘
appendfsync everysec 每秒钟调一次flush
appendfsunc always 每次写操作都flush
AOF文件重写
4.0前
重写
删除抵消的命令,合并重复的命令
最终也是一个纯指令的日志文件
4.0后
将老的数据RDb到AOF文件中,后续指令将增量的以指令的方式Append到AOF
配置项:aof-use-rdb-preamble yes
命令:BGREWRITEAOF
配置自动rewrite:
auto-aof-rewrite-percentage
auto-aof-rewrite-min-size
当aof文件大小达到auto-aof-rewrite-min-size*auto-aof-rewrite-percentage % 后,就会触发一次rewrite
4.0之前,假如redis运行了10年,AOF文件会无限变大
恢复慢
管道pipe
(printf \"PING\\PING\\PING\\\"; sleep 1) | nc localhost 6379
一次性将多个命令发送到服务器,而不用等待回复,等到最后一个步骤读取回复(减少网络IO)
linux使用管道时,每块命令都是单独一个进程
使用场景
大量数据插入,一个redis实例刚起来时,需要从数据加载大量的数据
文档:http://redis.cn/topics/mass-insert.html
cat data.txt | redis-cli --pipe
0 条评论
回复 删除
下一页