Redis知识点总结
2020-10-15 16:55:06 1 举报
AI智能生成
Redis知识点总结(Redis深度历险)
作者其他创作
大纲/内容
基础数据结构
String(字符串)
基本使用
键值对方式
set
设置一个键值
get
通过名称获取一个键值
批量键值对
mset
批量设置键值对
mget
批量获取键值对
计数
当值是整数时,可以计数
incr
将整数+1
incrby
将整数-1
底层结构
SDS
长度小于44字节
Embstr
长度大于44字节
Raw
list(列表)
基本使用
队列
rpush
右边压入
lpop
左边出队
栈
rpush
右边压入
rpop
右边弹出
慢操作
lindex
时间复杂度O(n)
ltrim
截断list一部分
底层结构
元素少
ziplist(压缩列表)
元素多
quicklist(快速列表)
由linkedlist以及ziplist组合而成
hash(字典)
基本使用
hset
设置元素
hget
通过名称获取元素
底层结构
两个HashMap
当前使用的Map
扩容的缩容使用的Map
扩容
渐进式ReHash
同时保留旧数组与新数组
在定时任务中以及后续对hash的操作指令中渐渐将旧数组中的元素挂接到新数组中
set(集合)
基本使用
sadd
添加一个元素到set中
spop
从set中删除一个元素
scrad
统计元素个数
smembers
获取set中所有元素
底层结构
没有value的HashTable
zset(有序列表)
基本使用
zadd
添加一个value-score到zset中
zrange
统计一个段中的元素
zcard
获取元素个数
底层结构
元素少
ziplist(压缩列表)
元素多
skiplist(跳跃列表)
底层结构实现
基本对象
基本对象类型
SDS(字符串)
SDS结构
Embstr
当长度特别短时(小于44字节)
Embstr
Raw
当长度超过44字节时(64(分配小字符串的最大容量)- 16(对象头) - 3(SDS信息) - 1(字节数组结尾结束符))
Raw
扩容策略: 在1MB之前翻倍.1MB之后每次增加1MB;
ListPack(紧凑列表)
Redis5.0版本更新,ziplist升级版本
ListPack
SkipList(跳跃列表)
数据结构
注
对每一个节点由算法随机分配一个合理的层级
几率依次递减为上一次的1/4
几率依次递减为上一次的1/4
skiplist
HashTable(哈希表)
HashTable
扩容缩容
扩容
1.一般情况当Hash表的元素个数等于一维数组的长度时则会开始扩充.(除非Redis正在进行bgsave,为了避免过多分离Copy On Write,则会尽量不去扩容)
2.当元素个数超过一维数组长度的5倍,则会进行强制扩容.
2.当元素个数超过一维数组长度的5倍,则会进行强制扩容.
缩容
1.当元素个数少于一维数组长度的百分之10,则会进行缩容,缩容不会考虑bgsave.
搬迁
1.当字典处于搬迁过程中,将当前的元素挂到新的table中.
2.定时任务会导致字典的搬迁.
2.定时任务会导致字典的搬迁.
QuickList(快速列表)
注
ZipList的大小超过8KB时新开一个ZipList,并使用LinkedList创建一个节点储存.
(省去了一个节点需要一个前后指针16字节的空间)
(省去了一个节点需要一个前后指针16字节的空间)
可以使用LZF算法压缩,压缩深度可以设置,深度为1时,首尾一号元素不压缩,深度为2时,首尾1,2号元素不压缩.
quicklist
IntSet(整数集合)
IntSet
当set中放入非整数时,intset转换为hash结构
ZipList(压缩列表)
ziplist构成
结构
ziplist是一块连续的空间,中间没有任何冗余.
ziplist通过zltail_offset来打到双向遍历的目的,可以快速定为到最后元素.
当字符串长度小于254时,length用一个字节标识,当大于254时,用5个字节表示.
Encoding编码前缀
1.00XXXXXX:最大长度为63位的字符串.后面6位存储字符串的位数.剩余的字节则是字符串的内容.
2.01XXXXXX XXXXXXXX:中等长度字符串,后面存储字符串的内容.
3.10000000 ax8 bx8 cx8 dx8 : 特大字符串,需要使用4个字节来表示长度,起始位为10,剩下6位无效.
通常在压缩列表中不会使用特大字符串.
通常在压缩列表中不会使用特大字符串.
4.11000000: int16,后面跟2个字节表示整数.
5.11010000: int32,后面跟4个字节表示整数.
6.11100000: int64,后面跟8个字节表示整数.
7.11110000: int24,后面跟3个字节表示整数.
8.11111110: int8,后面跟1个字节表示整数.
9.11111111: ziplist结束符号.
10.1111XXXX : XXXX可去范围0001-1101 ,超小整数,以及内联到后四位.
ZipList
Redis应用
String
位图
setbit
通过位置设置bit
getbit
通过位置获取bit
bitcount
统计1的个数
一般用于类似统计登陆天数
bitfield
对段进行读写
一次最多处理64个连续的位
用于布隆过滤器
HyperLogLog
一种Redis的高级数据结构
用于粗略统计
布隆过滤器
对于见过的元素不会误判
原理
一个大型的位数组
几个无偏hash函数
用于
常用与邮件过滤系统
List
Set
Hash
zset
限流策略
滑动窗口限流
使用过程
1.记录时间戳到zset中,同时用户ID
2.判断当前时间与最早时间戳之间的差距
3.当超出阈值时,则需要限流
4.将超出时间的时间戳删除
限制
不适用于操作次数多的限流,浪费空间
同样不适用于时间长的限流
漏斗限流
参数设置
1.漏斗容量
2.漏斗流水速率
3.漏斗剩余空间
4.上次漏水时间
使用过程
1.计算上次漏水时间到现在时间的差
2.通过漏斗流水速率计算所需容量
3.当所需容量超过剩余空间则需要被限流
4.重新计算剩余容量,重置上次漏水时间
GeoHash地理查询
使用一维表示二维位置,精度有损失
常用于查看附近的人
Scan语法
基本使用
scan number match "前缀" count cnt
持久化机制
RDB(快照)
Copy On Write机制
Redis在持久化时会使用glibc函数fork一个子进程,持久化交给子进程处理
在子进程持久化的过程中,不会修改现有的数据结构,只是对数据结构进行遍历读取,此时就会使用COW机制
当父进程在对数据进行修改时,会辅助一份共享的数据出来,对复制出来的数据进行修改,在修改完成后再合并修改
当父进程在对数据进行修改时,会辅助一份共享的数据出来,对复制出来的数据进行修改,在修改完成后再合并修改
AOF(增量日志)
AOF日志存储了Redis服务器顺序执行的指令,当需要恢复数据时,可以通过日志对数据进行回放
缺点
在长时间使用Redis后产生的AOF日志过大,需要恢复的时间很长
解决方式
通过bgrewriteaof指令重写AOF日志
同步
通常Redis一秒钟会调用一次fsync函数将日志刷新到磁盘中
Redis提供了两种策略
永不使用fsync同步,让操作系统决定何时同步
来一个指令调用一次fsync(效率极低)
混合持久化
在Redis4.0之后支持混合持久化
总和RDB快照以及AOF日志,此时AOF并不是全量日志,而是在进行RDB快照的期间进行的增量日志,通常该部分的AOF日志较少
Redis集群
CAP原理
一致性
数据保持一致
可用性
服务保持可用
分区容忍性
主从同步
保证最终一致性
原理
增量同步
主节点将对自身状态产生修改性影响的指令记录并保存到本地的buffer,然后异步将buffer中的内容同步到从节点中
从节点一边同步,一边向主节点反馈自身同步的进度
从节点一边同步,一边向主节点反馈自身同步的进度
快照同步
快照同步非常消耗资源
首先会在主节点进行一次bgsave,将当前内存中的所有数据同步到磁盘,然后将快照文件全部传送到从节点
从节点接收完成数据后,立刻进行一次全量加载,在全量加载的过程中主节点中buffer仍在移动
如果buffer快照同步时间过长,会导致再次发起快照同步,极有可能陷入死循环
从节点接收完成数据后,立刻进行一次全量加载,在全量加载的过程中主节点中buffer仍在移动
如果buffer快照同步时间过长,会导致再次发起快照同步,极有可能陷入死循环
过期策略
Redis每秒进行十次过期扫描
定时扫描策略
1.从过期字典中随机选出20个Key
2.删除20个Key中过期的Key
3.如果过期的Key超过1/4,则重复步骤1
从节点过期策略
主节点在Key到期时会在AOF日志中加入一条del指令,同步到所有从节点,从节点根据del指令删除Key
淘汰算法
LRU算法
过期策略
1.no-enviction(驱逐):禁止驱逐数据,默认策略,禁止写,可读
2.allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
3.allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
4.volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
5.volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
6.volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
LRU具体实现
在LRU模式下,对象头存储的是Redis的server.lrulock时钟
Redis实现 : 近似LRU算法
当Redis发现写操作内存不够时,会随机采样5个Key,并删除其中访问时间最晚的Key
在Redis每个对象头中有24bit的字段用于记录最近一次访问的时间戳
LFU算法
在Redis每个对象头中有16bit的字段用于记录最近一次访问的时间戳
8bit存储访问次数的对数,这个数据只有在懒惰删除时才会被更新
懒惰删除
使用unlink指令对删除进行懒处理
0 条评论
下一页