美文网首页
Redis集群mget优化

Redis集群mget优化

作者: 秃秃少年小猪 | 来源:发表于2020-03-29 22:50 被阅读0次

    写在前面

    哈哈哈哈哈,这次又来到了redis,redis对于大家来说,想必都已经熟悉了吧,笔者最近在做高并发的时候碰到一个问题,就是一个http接口,里面携带一个list<string> ~ a,然后通过a从redis中获取数据,考虑到数据量比较大,后来增加了redis集群,但是在访问的时候,使用的是 redisTemplate的mget,无论怎么优化,性能都是在秒级,对于缓存的读取,这个量级基本上算是废废的了,于是从其他地方入手。

    性能测试背景    

    通过项目提供的数据插入接口向redis-cluster 插入1000条记录,然后在通过key的集合从redis-cluster中获取数据。

    效果对比

       优化前

    redisTemplate.mget

    好像一次查询1000条数据2245ms返回没有啥问题,单个平均也就2245ms/1000=2.245ms,还算行吧,但是对于一个高并发的场景,http接口而言,就是个垃圾,完全不可用。一般的互联网公司对于,如果是To C的产品的接口,要求的RT都是200内,很果断的放弃这种。

    优化后

    重写了jedis的get,并且加入pipeline 返回数据

    原因分析

    对于redisTeplate的实现原理,这里就不赘述了,接下来从根儿上分析下改造后的实现原理,在这之前,我们先了解下redis集群的一个重要属性 slot

    在redis集群中,数据的主要存储单元,每一个key都要对应到一个slot中去,具体的算法是CRC16(key)算法,流程如下图,参见

    redis.clients.util.JedisClusterCRC16#getSlot(java.lang.String)

    CRC16算法

    实现源码分析

    思路:先找出哪些key在哪一个slot中,然后再通过jedispool获取到jedis,这里每个jedispool对应一个redis实例,从jedis中通过pipeline的方式获取,拿到结果,再做merge

    下面以图的方式展示

    1:将keys映射到jedispool,com.zcc.testrediscluster.jedis.SelfDefJedisSlotBasedConnectionHandler#getJedisPoolFromSlot这个方法在原生的jedis中是没有,我们重写了。

    keys映射到jedispool

    2:重写原生jedisHandler

    添加一个getJedisPoolFromSlot方法

    3:将这个handler托管到spring

    bean托管

    4:接口调用

    从redis中获取值

    获取jedis-pipeline

    数据合并

    数据整理

    总结

    上述结果充分说明了阅读源码的重要性,在做高并发的时候,就凸显源码是多么的重要,如果没有深入源码的话,在做性能优化的时候,也是很头疼的事情,以上的实现参考了搜狐开源的cache-cloud设计思想,在实践的同时,把cache-cloud的源码也撸了一遍,收获颇多,会从别人的身上汲取很多的经验,突然想起了牛顿说的那句话 "如果我看得更远一点的话,是因为我站在巨人的肩膀上"  共勉~

    相关文章

      网友评论

          本文标题:Redis集群mget优化

          本文链接:https://www.haomeiwen.com/subject/tjdpuhtx.html