1、关于是否执行bgsave时负载因子不同
没执行**bgsave** 或 **bgrewriteaof** 时,负载因子 = 1;
执行**bgsave** 或 **bgrewriteaof** 时,负载因子 = 5;
因为当执行执行**bgsave** 或 **bgrewriteaof** 时,redis 会fok 出一个子进程,如果这时候进行resize 操作,由于 fork 使用COW(写时复制),会导致父进程产生大量写内存操作,复制大量的数据,造成内存资源浪费
2、渐进式rehash 的过程
当需要rehash 的时候,redis 不会一下子将所有的dictEntry rehash,因为如果数据量很大很大,肯定会需要大量的CPU计算,可能导致程序一段时间内停止服务。
渐进式rehash 是将ht[0] 中的数据分批的rehash 到ht[1] 中。
dict 数据结构中维护了一个索引计数器 rehashidx,初始是-1,当进行rehash时,变成0,期间,除了对字典的增删改查操作之外,还会根据rehashidx 的值,将ht[0]->table[rehashidx] 中所有的entry 全部rehash 到ht[1],然后rehashidx++。
直到ht[0]->table 所有的enty全部rehash 完成,rehashidx 重置为-1。
如果这样,在rehash 期间,对一个dict 增删该查的时候,先判断 idx 是否大于等于 rehashidx,如果小于,说明所在的ht[0]->table[idx] 已经全部rehash 到ht[1]中,无需在ht[0]操作,直接操作ht[1]。
3、主从模式时,如果从服务器到某个key 过期,客户端访问从服务器,仍然可以获取到value,从服务到过期key,只能等主服务器同步del key 命令删除
这不就有很大问题吗,访问从服务器的过期键,还能正常取值,肯定会对业务逻辑造成影响,最直接的就是分布式锁,本来锁都应该过期了,却因为是访问从服务器导致业务逻辑认为锁还被其他线程持有。
难怪老东家的旧代码里面,访问key 要先ttl 操作,防止上诉问题。
像这种问题,我觉得应该很好解决才对:访问从服务器的key 时,检查key 的过期时间,如果过期了返回null,然后不对键做任何处理就行。
果然。通过查资料,发现这个问题在redis 3.2 解决了,解决方式就是上面这样的。