Redis不正确使用姿势指南

Redis当对象存储系统

先来展示一段我司日常常见代码:

……………………

Abc = redisTemplate.opsValues().get(“******”);

if(null==Abc){

abc=………………一堆逻辑

redisTemplate.opsValues().set(“******”,Abc);

}

Return Abc;

 

从逻辑上来说这段代码并没有错误

但这样最终导致的结果是把所有外部的压力都转移到了redis上来了,极有可能导致把redis打爆,从而击穿数据库导致整个系统崩溃

Redis当集群内存用

另一种情况是,redis当共享内存用:

比如我们的zuul部件,每次都把用户的请求完整的set进redis,然后当下一个同session的转发进来后去redis去get,具体表现是redis看到日志是每当一个请求进来会出发两位数到三位数的redis请求(流量极端放大),尽管是zuul部件本身做到了无状态,但其实是用了redis做了共享状态。

这样依旧是把所有压力都放在了redis上面。引发问题更糟糕的是,我们的session内容存了太大的对象redis的并发能力遭到了限制,在少量用户下就已经会引发内部系统的崩溃。

总结一下:

正确的姿势是redis类似与一个单机系统里面不同进程的buffer/channel,在考虑上网络IO的重量级后,我们应该尽可能减少进程之间的通信,在这里的语境下应该是减少集群内之间的通信,从而避免把buffer/channel本身给弄挂了。

在第一种用法下,其实应该是将Abc的状态保存在redis但是Abc本身应该要存在当前结点上,这样就改变了集群内部通过redis传递对象,转而是传递信息了,比如我用时间作为Abc的特征,那么集群内部只需要传递特征时间就能够保持集群内部操作的幂等性,从原有的可能几kb的通讯变为几bit的通讯

第二种用法下,优化的手段就要更多了,首先第一点是减少session保存的数据,将不同业务之间的session分割开来减少session的大小。接着将请求按照一致性hash原理,同一个请求只从zuul集群的同一台服务器走,将保存的信息转换成本地内存,或者将用户-》集群的映射关系存入redis从而减少redis的使用量。