File tree 1 file changed +39
-0
lines changed
1 file changed +39
-0
lines changed Original file line number Diff line number Diff line change @@ -228,6 +228,45 @@ Zset的两种实现方式,ZipList和SkipList(跳表)
228
228
SkipList本质上是并行的有序链表,但它克服了有序链表插入和查找性能不高的问题,它的插入和查询时间复杂度都是O(logN)
229
229
230
230
231
+ #### LRU与LFU淘汰算法
232
+ Redis缓存淘汰策略与Redis键的过期删除策略并不完全相同,前者是在Redis内存使用超过一定阈值的时候使用淘汰策略。而后者是通过定时+惰性删除两者结合的方式进行内存淘汰的。
233
+ 不同触发的条件逻辑:
234
+
235
+ > - 当某个key被设置了过期时间后,客户端每次对该key的访问(读写)都会去检查一遍key是否过期,如果过期直接删除;
236
+ > - 如果过期的key不经常被访问,Redis会定时每秒检测10次,检测被设置有效期的所有key的集合,每次从集合中随机抽取20个key进行删除,如果删除后集合中过期key依然超过25%,那么会继续随机抽取20个key删除;
237
+
238
+ Redis内存不足时的缓存淘汰策略:
239
+
240
+ > - noeviction:当内存使用超过配置的时候会返回错误,不会删除任何key;
241
+ > - allkeys-lru: 加入key的时候,如果有限,首先通过LRU算法删除最久没有使用的key;
242
+ > - volatile-lru:加入key的时候如果有限,首先从设置了过期时间里删除最久没有使用的key;
243
+ > - allkeys-random:加入key的时候如果有限,从所有key中随机删除key;
244
+ > - volatile-random: 加入key的时候如果有限,从所有设置过期时间里随机删除key;
245
+ > - volatile-ttl:从配置了过期时间里,删除快过期的key;
246
+ > - volatile-lfu:从所有配置了过期时间里删除使用频率最少的key;
247
+ > - allkeys-lfu:从所有key中删除使用频率最少的key;
248
+
249
+
250
+ ** Redis中的LRU实现:**
251
+
252
+ Redis中的LRU和Java中的LRU实现不一样,它并不采用链表的方式存储。
253
+ Redis为每一个key维护了一个24位的时钟,同时也维护了一个全局的24位时钟,简单的理解就是当前系统的时间戳。如果要进行LRU,那么首先拿到当前全局的时钟,然后找到内部所有key时钟和全局时钟距离最久的key进行淘汰;
254
+
255
+ ** Redis中的LFU实现 :**
256
+
257
+ LRU是Redis4.0后出现的淘汰算法,LRU的最近最少使用实际上是不精确的,因为使用距离时间较最久的key,不代表是使用频率最少的key;
258
+ 如下图,按照LRU会淘汰A,因为B的访问时间比A更近,但是A的使用频率远超于B,理应淘汰B;
259
+ ``` asp
260
+ A~~A~~A~~A~~A~~A~~A~~A~~A~~A~~~|
261
+ B~~~~~B~~~~~B~~~~~B~~~~~~~~~~~B |
262
+ ```
263
+
264
+ LFU把原先的key对象内部的24位时钟分为了两个部分,前16位还代表时钟,后8位代表一个计数器。
265
+ 使用LFU淘汰时,会根据计数器中key使用的频率精准的淘汰最少使用频率的key。
266
+
267
+
268
+
269
+
231
270
232
271
233
272
You can’t perform that action at this time.
0 commit comments