feat: redis过期策略

master
old-tom 3 years ago
parent d333d05b19
commit 1afb05ab36

@ -47,6 +47,7 @@ index可以为负数index=-1表示倒数第一个元素同理index=-2表
### 2.2底层数据结构quicklist
实际上Redis的list并不是一个简单的linkedlist而是quicklist快速链表
在元素较少情况下会使用一块连续的内存存储这个结构是ziplist压缩列表。将所有的元素彼此紧挨着存储也可以看作是数组结构。当数据量比较多的时间才会变成quicklist因为普通的链表需要的附加指针空间前后指针所以Redis将链表和ziplist结合组成quicklist将多个ziplist使用双向指针连接使用。
quicklist内部默认单个ziplist长度为8kb超过这个字节数就会另启一个ziplist
![[Snipaste_2023-02-22_16-10-55.png]]
## 3.hash
Redis字典相当于Java的HashMap属于无序字典在数据结构上使用的是数组+链表也就是散列表结构。
@ -100,3 +101,6 @@ hash结构可以结构化存储用户信息相比于json存储可以单独
### 5.2 底层数据结构(跳跃列表)
查看数据结构相关文档
### 5.3 假如元素score值相同
zset的排序元素不只看score值如果score相同还会比较value值字符串比较

@ -0,0 +1,3 @@
redis并不是总将空闲内存立即归还给操作系统。
操作系统是以页为单位来回收内存这个页上只要有一个Key在使用那么它就不能被回收。Redis虽然删除了1GB的key但是这些key被分散到了很多页中每个页有其他key存在这就导致了内存不会被立即回收。
可以执行flushdb删除所有的key这个操作很危险且能有效回收内存。

@ -6,3 +6,14 @@ Redis的ziplist是一个紧凑的字节数组结构每个元素之间都是
+ 如果set里存储的是字符串那么sadd会升级为hashtable结构HashSet
# 存储界限
当集合对象的元素不断增加或者某个value值过大这种小对象存储也会被升级为标准结构
| 序号 | 规则 |
| ---- | ------------------------------------- |
| 1 | hash的元素个数超过512 |
| 2 | hash的任意元素的key/value的长度超过64 |
| 3 | list 的元素个数超过512 |
| 4 | list的任意元素的长度超过64 |
| 5 | zset 的元素个数超过128 |
| 6 | zset的任意元素的长度超过64 |
| 7 | set 的整数元素个数超过512 |

@ -0,0 +1,19 @@
Redis会将设置了过期时间的key放入一个独立字典中由定时任务及惰性删除策略来删除过期key。
所谓惰性删除就是在客户端访问这个Key的时候Redis对key的过期时间进行校验如果过期了就删除
# 一、定期扫描
redis默认每秒进行10次过期扫描它不会遍历字典中的所有Key而是采用了贪心策略步骤
1. 从过期字典中随机选出20个key
2. 删除这20个key中已经过期的
3. 如果过期key的比例超过1/4那就重复步骤1
为了保证过期扫描不会出现循环过度导致线程卡死算法还增加了扫描时间的上线默认不超过25ms。
Redis会持续扫描过期字典直到字典中的过期Key变得稀疏不超过1/4才会停止。这就导致线上读写出现明显的卡顿这种卡顿的另外一种原因是内存管理器需要频繁回收内存页产生了CPU消耗。
所以如果有大批量的key过期要给过期时间设置一个随机范围而不能全部在同一时间过期。
## 1.1 从节点的过期策略
从节点不会进行过期扫描从节点对过期的处理是被动的。主节点在Key到期时会在AOF日志中添加del命令同步到所有从节点从节点通过执行命令进行删除这就导致了主从数据不一致。
# 二、惰性删除
大部分情况下del命令执行很快如果删除一个包含成千上万元素的Hash那么删除会导致单线程卡顿。
Redis为了解决这个问题引入了unlink指令它能对删除操作进行懒惰处理交给后台其他线程来异步回收内存。
这个命令不会导致线程安全问题可以将整个Redis内存里面的有效数据想象成一颗树当使用unlink时它只是把其中一个树枝剪断了扔到旁边在离开树的一瞬间它就再也无法被主线程中的其他指令访问。
Loading…
Cancel
Save