当前位置:首页 > 问答 > 正文

Redis缓存分片技术怎么用来加速访问,提升性能那些事儿

主要整合自Redis官方文档的分布式章节、多位资深后端工程师的博客分享,例如阿里云开发者社区的“Redis最佳实践”系列文章,以及《高性能缓存架构》一书中的相关论述)

Redis缓存分片技术,说白了就是一种“人多力量大”的思路,想象一下,你有一个超级大的仓库,里面堆满了各种货物,如果只有一个管理员负责所有货物的存取,那当很多人同时来取东西的时候,这个管理员肯定会忙得团团转,成为整个流程的瓶颈,大家都要排队等着,速度自然就慢下来了。

这个“超级大仓库”就是你的数据,“管理员”就是单个Redis服务器,当你的应用用户量越来越大,数据量暴增,或者读写请求变得极其频繁时,一个Redis实例(也就是一台服务器)可能就扛不住了,它的内存是有限的,迟早会被数据塞满;它的CPU处理能力也是有限的,面对海量请求可能会反应迟钝,这时候,我们就需要想办法把压力分散开,这就是分片技术要解决的问题。

分片具体是怎么做的呢?其实就是把原来放在一个Redis实例里的数据,像切蛋糕一样,分成好几份,然后每一份分别存到不同的Redis服务器上去,每一台服务器只负责保管整个数据集中的一部分,这样,原来由一个“管理员”干的活儿,现在由多个“管理员”分工协作了。

这样做的好处是立竿见影的,主要体现在两个方面来加速和提升性能:

第一,突破了单机内存的限制,单个服务器的内存可能只有64G或者128G,能缓存的数据量是有限的,如果你有1TB的数据想放进缓存,一台机器根本装不下,通过分片,你可以用10台64G内存的服务器组成一个集群,总内存容量就达到了640G,虽然每台机器只存了一部分数据,但整个集群却能缓存远超单机容量的数据,这就好比把货物分到10个不同的仓库里,总的仓储能力就大大增强了,数据都能放进缓存,查询时就不用总去慢吞吞的数据库里捞,访问速度自然就快了。

第二,分散了读写压力,提升了吞吐量,这是提升性能最核心的一点,以前所有读写请求都涌向一台服务器,它的网络带宽、CPU处理能力很快会达到上限,分片之后,请求也被分散了,根据用户ID把数据分到不同的片上,那么属于用户A的请求会被自动引导到负责这片数据的服务器A上,属于用户B的请求则被引导到服务器B上,这样,每台服务器处理的请求量都变少了,可以更快地响应,从整体上看,整个系统一秒钟内能处理的请求数量(也就是吞吐量)就大大增加了,响应时间也更短,整个应用就显得非常快。

具体是怎么决定一条数据该放到哪个“分片”上的呢?常见的办法有几种:

一种很简单的方法是范围分片,规定用户ID从1到10000的数据放在第一个分片,10001到20000的放在第二个分片,以此类推,这种方法好处是简单明了,但缺点是如果数据分布不均匀,可能会导致某些分片数据多、压力大,而其他分片很空闲,形成“热点”,没有完全实现负载均衡。

另一种更常用的方法是哈希分片,这是目前最主流、效果最好的方式,它的做法是,对数据的某个关键字段(比如用户ID、订单ID等,这个字段叫分片键)计算一个哈希值(可以理解成一个数字指纹),然后用这个哈希值对分片的总数量取模,根据得到的余数来决定数据落在哪个分片上,哈希值对3取模,余数可能是0、1、2,那么就对应三个分片,这种方法的好处是,只要分片键选得好,数据就能比较均匀地分布到各个节点上,有效地避免了热点问题,Redis Cluster模式内部就是采用了一种改进的哈希槽(Hash Slot)机制,可以理解为一种更智能、更灵活的哈希分片。

除了上述两种,还有像一致性哈希这样的算法,它能在增加或减少分片服务器时,最大限度地减少需要移动的数据量,保证了集群的弹性,但实现起来相对复杂一些。

分片也不是没有代价的,它让系统架构变得更复杂了,你的应用程序需要知道怎么把请求发送到正确的分片上(通常由客户端SDK或代理中间件帮忙完成);如果某个分片服务器宕机了,怎么保证高可用(通常需要配合主从复制);如果以后数据量又增长了,如何平滑地增加新的分片(扩容)等等,这些都是引入分片后需要考虑和解决的问题。

Redis缓存分片技术的核心思想就是“分而治之”,通过将数据和请求负载分布到多个廉价的普通服务器上,而不是依赖一台昂贵的高配服务器,从而以一种横向扩展的方式,极大地提升了缓存系统的整体数据容量和并发处理能力,最终达到加速数据访问、提升应用性能的目的,当你的应用面临性能瓶颈,而瓶颈又确实出在缓存这一层时,分片就是一个非常有效的解决方案。

Redis缓存分片技术怎么用来加速访问,提升性能那些事儿