redis中数据倾斜问题的产⽣和解决⽅案
在服务端系统服务开发中,缓存是⼀种常⽤的技术,它可以提⾼系统对请求的处理效率,⽽redis⼜是缓存技术栈中的⼀个佼佼者,⼴泛的应⽤于各种服务系统中。在⼤型互联⽹服务中,每天需要处理的请求和存储的缓存数据都是海量的,在这些⼤型系统中,使⽤单实例的redis,很难满⾜系统超⾼的并发请求以及海量数据缓存需求。⼤型的互联⽹服务中对于redis的使⽤,往往采⽤集架构,通过横向扩展redis实例规模的⽅式,以较低的成本,来提升缓存系统对数据请求的处理效率和数据存储容量。
redis集架构虽然有众多优点,但是事物往往都是有双⾯性的,在解决某些场景下的问题后,⼜会在另外的场景下有带来问题。当然redis 集模式,也是符合这个规律的。redis集模式下,会增加运维的复杂度,限制了redis中某些命令的使⽤(范围查询,事务操作的使⽤等),除了这些常见的问题外,数据倾斜问题,是redis集模式下⼀个⽐较隐蔽的问题,只有在⼀些特殊的场景下才会出现,但是该问题带来的影响确实巨⼤的。
⼀、什么是数据倾斜
在redis集模式下,数据会按照⼀定的分布规则分散到不同的实例上。如果由于业务数据特殊性,按照指定的分布规则,可能导致不同的实例上数据分布不均匀,如以下场景:有些切⽚实例上数据分布量较⼤,有些实例上数据分布量较少;有些实例上保存了热点数据,数据访问量较⼤,有些实例上保存数据
相对较"冷",⼏乎没有访问量。那么存储数据量⼤的实例,或者保存热点数据的实例,资源利⽤率会⽐较⾼,负载压⼒较⼤,导致其对数据请求响应变慢。此时就产⽣了数据倾斜。
⼆、有哪⼏种数据倾斜
通常来说,数据倾斜分为以下两种:数据量倾斜,数据访问倾斜。
三、数据量倾斜
数据量倾斜产⽣的根本原因是:数据在各个redis实例上分布不均匀。
产⽣数据分布不均匀的情况主要有以下三种。
1) 存在bigkey
当⼀个实例上存储了⼀个或者多个bigkey时,例如⼀个占⽤空间很⼤的string类型的数据,或者保存了⼀个包含很多数据元素的集合时,那么会导致该实例的内存资源消耗严重。⽽且对于bigkey的操作通常会造成实例IO线程阻塞,使该实例对数据请求处理效率严重下降。
redis支持的五种数据类型
对于bigkey造成的数据倾斜问题,⼀个根本的解决⽅案就是,避免bigkey的产⽣。常⽤的做法是对bigkey进⾏"化整为零",在业务层⾯⽣成数据的时候,尽量避免把过多的数据保存到同⼀个键中。具体可以参考。
2) HashTag使⽤不当
HashTag是使⽤redis的⼀个⼩技巧,使⽤⽅式是 在 key中添加⼀对花括号 {},这个 {} 可以将key的⼀部分内容包裹起来,⽽redis server 会对于加上{}的key进⾏识别,并进⾏特殊处理。使⽤HashTag可以增强业务层⾯对redis集模式下,key分区的控制。具体来说:正常情况下,客户端根据key的完整内容,按照CRC16算法⽣成⼀个CRC16值,redis-server按照这个CRC16值,给这个key分配slot,⽽是⽤HashTag后,客户端计算key的CRC16值,不在是整个key的内容,⽽是{}括起来的那部分部分。使⽤HashTag,可以让我们根据业务属性,在key的适当位置添加{},让业务相关的⼀些key存储到同⼀个slot中,同时也就分配到同⼀个实例上,当相关的数据全部分配到同⼀个实例上后,就可以执⾏实例
内事务操作(⽬前redis 集不⽀持跨实例事务操作)和范围查询等先关操作了。
虽然,HashTag,有利于实现跨实例的事务操作和范围查询,但是带来的风险就是,所有业务相关的的数据,都要放到同⼀个实例上,如果这个业务相关的数据量⽐较⼤的话,就会导致,业务所在实例的内存资源消耗严重。产⽣数据倾斜问题。如果使⽤ Hash Tag 进⾏切⽚的数据会带来较⼤的访问压⼒,就优先考虑避免数据倾斜,最好不要使⽤ Hash Tag 进⾏数据切⽚。因为事务和范围查询都还可以放在客户端来执⾏,⽽数据倾斜会导致实例不稳定,造成服务不可⽤
3)slot分配不均匀
在redis 集中,slot是数据在多个redis实例间分配的的基本单元。在⼀个redis集中,⼀共有16384个slot,这些slot会分配到集中的实例上。如果slot在实例上分配不均匀的话,使某个或者某些实例上分配过多的slot,那么这些实例上被分配数据量也会更多⼀些,也就会产⽣类似HashTag⼀样的数据倾斜问题。
对于由于slot分配不均导致的数据倾斜问题,可以在slot分配前,通过⼈⼯分配的⽅式,来避免多个slot分配到同⼀个实例的问题,如果⼀个集中slot已经分配完毕,可以通过redis提供的运维⼯具和相应的运维命令,来查看redis集中,slot的分配情况,如果存在某些实例上slot分配过多的情况,那么可以将这些过多的slot转移到其他实例上。
四、数据访问倾斜
除了数据量过多导致的数据倾斜问题外,如果实例上存在热点数据,如电商秒杀场景中的商品信息。那么会导致所在实例数据请求访问量远⾼于其他实例,产⽣数据访问倾斜。
对于热点数据问题,通常采⽤的解决⽅案是多副本冗余。具体做法:我们把热点数据复制多份,在每⼀个数据副本的 key 中增加⼀个随机前缀,让它和其它副本数据不会被映射到同⼀个 Slot 中。这样⼀来,热点数据既有多个副本可以同时服务请求,同时,这些副本数据的key ⼜不⼀样,会被映射到不同的 Slot 中。在给这些 Slot 分配实例时,我们也要注意把它们分配到不同的实例上,那么,热点数据的访问压⼒就被分散到不同的实例上了。这样可以有效解决数据访问倾斜问题。但是这种多副本的⽅
式,仅仅适⽤于对热点数据的读操作,⽽对于存在写操作的热点数据,就不太适⽤了,因为对于写操作需要保证多个副本的数据⼀致性,⽽保证数据⼀致性,是⼀个⽐较复杂的问题,业务上需要较⼤的额外开销。
五、总结
以集⽅式使⽤redis时,数据倾斜问题,是⼀个很难发现的问题,当出现数据请求响应变慢时,有可能是数据倾斜问题导致的,这个时候,可以参考上⽂提到的⼀些可能产⽣数据倾斜问题的场景进⾏排查,然后根据对应的⽅案进⾏问题的解决。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。