redis出坑记

monitor未关闭

redis的monitor运维调试用,返回服务器处理的每一个命令,能了解在数据库上发生了什么操作,所以在性能上会有一些消耗。有3种操作方法进monitor模式。

1
2
3
4
5
6
7
8
9
10
11
12
[lavenderuni@~]# redis-cli monitor
...
[lavenderuni@~]# redis-cli
127.0.0.1:6379> monitor
...
[lavenderuni@~]# telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
monitor

在测试redis-cluster时候,吃午饭回来发现某node内存持续占用,比其他node要高,主node正常,如果在非常大的key-value,例如某个key的value存了近百万数据,会造成内存占用,但是不应该是某个node不正常。主从复制出问题应该体现在主node。

经过排查找到,是该node上开启了monitor模式,饭前忘了关掉,导致请求的操作log越来越多。这和很多工具都一样,测试模式不要轻易开启,用完请及时关闭。注意,Telnet连上了同样可以monitor,所以端口不要轻易对外开放,避免被人利用

大map

产品上面的用户数据超过700万,一些用户的附加信息需要在新功能上使用,并且新功能取数据很频繁,需要把用户这部分信息从mongo存到redis,供接口获取。
有三种方案:

  • key-value,key=uid,val=rank
  • hash,key=”userinfo”,val={uid:rank}
  • hash,key=to_int(uid)/60,val={to_int(uid)%60:rank}

通过测试发现,第三种的内存最小。
为什么呢?要从数据类型的内部存储方式说起,

  • hash-max-zipmap-entries 64
  • hash-max-zipmap-value 512

hash-max-zipmap-entries含义是当value这个Map内部不超过多少个成员时会采用线性紧凑格式存储,默认是64,即value内部有64个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的HashMap。

hash-max-zipmap-value 含义是当 value这个Map内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间。

以上2个条件任意一个条件超过设置值都会转换成真正的HashMap,也就不会再节省内存了。它们值不是越大越好,HashMap的各种动作的时间复杂度都是O(1),采用一维存储的时间复杂度O(n),成员数量一多,会严重影响性能。

因此遇到Redis的大map,要选择合理的数据结构和hash-max-zipmap参数解决实际问题,达到高效省内存的目的。