
前两篇是集群已经搭建起来了,现在正式投入应用中。而今天要分享的是在应用中遇到的hot key(热key)和容量倾斜。
hot key的含义是,在一段时间内,该key的访问流量远远大于其他key的流量,导致大部分的流量的请求都集中在一个节点上。严重造成各个节点的QPS不均衡。致使某个节点的负载过高,进而影响集群的稳定性。同时相对于整个集群来说,它的QPS的扩展性是比较差的。可能有的人会问哪些操作会造成hot key的出现呢?比如大的电商平台举办的促销活动,其中每个key都存储了每个商品的信息,假如在这次的促销活动中出现了一个爆款,价格很低又很受大家的喜欢,都点击进去查看,那么这个商品对应的key就会成为hot key。还有信息流中热门文章的板块,运营人员搞个推送或者加个红点,再者来一个运营活动,那么流量可想而知,所以那个key又成了hot key。其实工作中会出现很多这种情况,在有一定量的前提下哈。
那么hot key的出现,其实就容易造成服务的不可用。那么我们应该如何解决这种问题呢?其实很简单,就是把这个key打散到其他的节点上就好了,如何打散呢?听我娓娓道来,方法如下:
假设现在出现的hot key 为 hot_key_test,一共有3个节点,那么我们可以从 0到 n*3(其中n一般为偶数)随机出来一个数值,rand = random.randint(0,n*3),然后拼接到原来的key上,例如 rand=3,那么新key就是 hot_key_test_3。接下来,客户端先从 hot_key_test_3 中获取数据,如果获取不到数据,那么就从hot_key_test中get数据,假设get 到了,那么将数据set 到 hot_key_test_3中,如果从 hot_key_test中get不到数据,那么就从数据库中获取源数据,然后set 到hot_key_test 和 set 到 hot_key_test_3中。因为是短暂性的key,所以我们一般会加上过期时间,在这里我建议在原来的过期时间上+随机值(1-2分钟),避免大量的key是同时失效带来的雪崩,这种具有一定的坡度失效我还是挺建议大家这样做的,以防万一。一切以服务稳定为中心。
上面讲完了hot key一般出现的场景和解决方案,至于如何监控的话,那么这个就可以自己去思考下。接下来说说容量倾斜的问题。
容量倾斜的含义,在一段时间内,在某个节点上的某个或者某些key的value集中增长,速度过快。那么就会造成某个节点上的容量严重倾斜。其他节点的资源利用不均衡,闲置。存储的扩展能力比较差。
和上面一样,哪些场景会出现呢?比如数据结构是zset,list。zset的话,很容易想到的是排行榜,对的,存储了一个活动的排行榜信息,如果一旦活动被运营,活动的流量暴增,那么这个排行榜会越来越大,value会越来越大。而list 肯定是列表,存储的内容比如是贴吧里面那种盖楼抢楼活动。致使某个帖子对应的value越来越大。
同样出现容量倾斜的问题,我们应该如何解决呢?同样的想法,我们把big value 进行拆分。list的话,我们可以拆分成 list1,list2,list3,list4.然后对应的就是key1,value1,key2,value2等。这个是已经发生了容量倾斜的情况,那么我们可以用mset key1,value1,key2,value2。同时设置多对key-value。获取的话可以用mget 多个key。这样容量就分布到了其他节点上。但是如果这个key又是hot key 又是 big key呢?
刚才我上面说的都是已经发生了的情况,如何去解决。其实我们作为开发者,在设计这个的时候,就要去评估下,预计这个key的流量,预计这个key的容量等一些问题。然后进行一些合理的策略,把这个问题在源头就处理掉,而不是等到事情发生了再来补牢。多一些考虑,多一些思维的碰撞,会让后面的路走的更舒坦。还有就是刚才上面提到的监控是很重要的,解决问题不困难,难的是及早的发现问题。





