redis 开启lazy-free机制后,有些操作会在另一个线程执行,那么对于有些共享且可修改的数据,是不是就要使用同步机制(比如加锁)。
如果使用了同步机制,那单线程还有意义吗,直接支持多线程得了。
redis 开启lazy-free机制后,有些操作会在另一个线程执行,那么对于有些共享且可修改的数据,是不是就要使用同步机制(比如加锁)。
如果使用了同步机制,那单线程还有意义吗,直接支持多线程得了。
什么情况才会真正异步释放内存?这和 key 的类型、编码方式、元素数量都有关系(详见 lazyfreeGetFreeEffort 函数):
a) 当 Hash/Set 底层采用哈希表存储(非 ziplist/int 编码存储)时,并且元素数量超过 64 个
b) 当 ZSet 底层采用跳表存储(非 ziplist 编码存储)时,并且元素数量超过 64 个
c) 当 List 链表节点数量超过 64 个(注意,不是元素数量,而是链表节点的数量,List 底层实现是一个链表,链表每个节点是一个 ziplist,一个 ziplist 可能有多个元素数据)
只有满足以上条件,在释放 key 内存时,才会真正放到「后台线程」中执行,其它情况一律还是在主线程操作。
也就是说 String(不管内存占用多大)、List(少量元素)、Set(int 编码存储)、Hash/ZSet(ziplist 编码存储)这些情况下的 key,在释放内存时,依旧在「主线程」中操作。
引用自极客时间《Redis 源码剖析与实战》- Lazy Free会影响缓存替换吗?评论区大神:Kaito
6 回答4.8k 阅读✓ 已解决
12 回答5.9k 阅读
2 回答7.4k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
3 回答6.9k 阅读✓ 已解决
1 回答5.2k 阅读✓ 已解决
3 回答3k 阅读✓ 已解决
没有锁。
4.0 引入 Lazy Free 时为了避免锁机制带来的性能下降,直接就干掉了共享对象,换成了数据拷贝,这样就不需要锁了。也就是说,表面上看起来这只是个影响删除操作的新特性,实际上整个底层的存储和数据结构都发生了变化。
P.S. 6.0 真的就引入多线程 I/O 了哟。