1.背景介绍
现象:
从图中可以看到,我这是一个三主三从的集群,15和16是一对主从,从节点的内存使用率是高于主节点的,但是他们的数据量又是差不多的
可能原因:
1.key在主节点删除,还没同步到从节点
2.主从节点repl配置不一致,
3.从节点在monitor,
4.读写分离,从节点client output buffer开销过大,
5.从节点还有从节点并发生psync等然而今天分析的这种情况,上边的所有条件都不满足
2.分析过程
经过查证redis的各个信息之后,发现我的问题不满足上边的任何一种情况,查看info memory 信息后,查看内存这一部分的数值,会发现主要是的内存是在overhead这块存在差异,而overhead这部分内存主要是redis为了维护数据集的内部机制所需要的内存开销,包含客户端输出缓冲区,查询缓冲区,aof重写缓冲区和主从复制的backlog。而我的集群上是未开启aof的,查看info client 及client list也并没有过大的缓存,然后突然想到这个现象是从上一次集群发生rehash的时候开始的。
于是在主从节点上冒险执行了一次 debug htstats 0 (注:命令可能会引起主从切换,可能会超时,谨慎执行)此命令主要是为了查看主节点的hash table size占用的大小
有了这个结果一切就解释的通了,从节点的hash table size的大小刚好是主节点的2倍,此时从节点的内存也是比主节点大了2G
3.结论分析
汇总一下我的分析结果:
1.分析得出从节点内存大于主节点内存主要原因是从节点的hash table size大于了主节点的hash table size
2.为什么主从的hash table size不一样,很明显是发生了rehash,主节点rehash之后收缩了,而从节点的没有收缩,而rehash的收缩条件是(key的数量 除以 hash的 size)< 10%,从节点不满足条件了
3.主从数据量差不多为什么从节点不满足收缩条件?悄悄告诉你们,这是我导致的,因为发生rehash的那个时候,我发现数据的内存上涨了,就把hz的数值增大为原来的30倍,主要是为了加快回收速度降低内存使用,这样就导致了,rehash的时候,主节点大量的数据再回收,而从节点的数据删除要依靠主节点通知才会删除,这样导致的主节点已经满足条件而从节点没有满足
4.这种情况还可以修复吗?首先收缩是不能手动触发的,10%的大小是在代码写死的,但是我觉得是没什么影响的,从节点会一直保持大于主节点2个G的大小,下一次rehash的发生就可以回收这部分的内存了