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

Redis架构深度剖析,带你一步步看懂分布式存储到底咋回事

主要参考自知乎专栏“Redis设计与实现”以及官方文档的核心思想,并结合了常见的分布式系统知识进行阐述)

咱们今天就来聊聊Redis这个“快”出名的家伙,它到底是怎么工作的,尤其是当数据多到一台机器放不下的时候,它又是怎么通过“分布式”来解决这个问题的,我们不扯那些难懂的专业词,就用大白话把它讲明白。

第一部分:先弄明白单机的Redis为啥这么快

在你考虑怎么把东西分到多个仓库之前,你得先搞清楚自家这个仓库为啥效率这么高,Redis的单机版之所以快,核心在于三点,这就像一个小超市的高效运营秘诀:

第一,所有货品都摆在柜台上(内存存储),Redis直接把数据放在电脑的内存里,而不是像传统数据库那样存在硬盘上,从内存里拿东西比从硬盘上拿要快成千上万倍,这是它快的根本原因,东西都放桌上容易丢(断电数据就没了),所以Redis也有办法定期把内存里的数据“抄写”一份到硬盘上(持久化),做个备份。

第二,一个超级熟练的售货员(单线程处理命令),你可能会想,多雇几个售货员(多线程)不是更快吗?但Redis反其道而行,它只用一个人,这样做的好处是,完全没有“多个售货员同时整理货架导致混乱”(即线程切换和锁竞争)的开销,这个售货员手脚极其麻利,而且它只干最重要的活儿:帮你取货、存货,那些打扫卫生、整理仓库的杂活(比如把数据备份到硬盘),它会找几个帮手(子进程)在后台悄悄干,不耽误前台服务。

Redis架构深度剖析,带你一步步看懂分布式存储到底咋回事

第三,精心设计的货架和取货流程(高效的数据结构和I/O模型),Redis货架(数据结构)种类多且好用,比如有能快速排队(列表)、快速查成员(集合)、快速查键值对(哈希)的货架,这个售货员不是傻站着等顾客,而是用一个“呼叫铃”机制(I/O多路复用),他坐在柜台后,看着一堆呼叫铃,哪个铃响了(代表哪个客户有请求),他就去处理哪个,处理完立刻回来等着,这样能同时服务很多人,还不会闲着。

第二部分:当一个小仓库不够用了,怎么办?——走向分布式

单机Redis就像一个小超市,东西少的时候非常高效,但当你的商品(数据)多到爆仓,或者顾客(并发请求)多到挤破门的时候,一个小超市就顶不住了,这时候,你就需要开“分店”了,这就是分布式存储。

分布式核心要解决两个问题:1. 数据怎么分到不同的店里? 2. 怎么知道我要的数据在哪家店?

Redis最主要、最经典的分布式方案叫 分片(Sharding),也叫数据分片,想象一下,你有一个超大的图书馆,书多到放不下,你决定开三家分馆。

Redis架构深度剖析,带你一步步看懂分布式存储到底咋回事

怎么分书?(数据分片策略)

你不能胡乱分,得有个规则,常见规则有俩:

  • 范围分片:就像按书名首字母分,A-F的书放一号馆,G-M放二号馆,N-Z放三号馆,简单易懂,但万一写“S”开头的作家特别多,那三号馆就会特别挤(数据倾斜),其他馆却闲着。
  • 哈希分片:这是Redis更常用的方法,给每本书名(数据的键)算一个“身份证号”(哈希值),然后把这个身份证号对分馆总数取余数,比如算出来余数是1,就放一号馆;余数是2,放二号馆……这样做的好处是,只要书名(键)是随机分布的,书就能比较均匀地分散到各个分馆,不容易出现一个馆特别忙的情况。

谁来做导引?(分片的实现方式)

书分好了,读者来了问“《三体》在哪?”,谁告诉他去三号馆呢?这又有两种方式:

  • 客户端分片:相当于给每个读者发一张规则表(分片逻辑写在客户端代码里),读者自己根据规则算出《三体》应该在三分馆,然后直接去三分馆找,好处是直接,不用经过中间人;坏处是规则一旦要变(比如新开四号馆),你得通知所有读者更新手里的规则表,非常麻烦。
  • 代理分片:这是更常用的方式,我在总台设一个“问讯处”(代理中间件,比如Twemproxy, Codis),读者不用记规则,直接到总台问“《三体》在哪?”,问讯处的工作人员根据规则算出位置,告诉你“去三号馆”,或者甚至帮你把书从三号馆取来给你,这样,客户端变简单了,分片规则的变更也只需要在问讯处处理就行。

第三部分:开分店的高级挑战——Redis Cluster的解决方案

Redis架构深度剖析,带你一步步看懂分布式存储到底咋回事

上面说的代理分片挺好,但那个“问讯处”可能成为新的单点瓶颈,如果问讯处排队的人太多,或者问讯处本身瘫痪了,整个图书馆就乱套了。

Redis官方推出了一个更“去中心化”的终极解决方案:Redis Cluster(Redis集群),它相当于什么呢?

它相当于取消了总问讯处,让每个分馆都变得“智能”起来,每个分馆(集群中的每个节点)不仅存着一部分书(数据),还知道整个图书馆的“地图”(集群的元数据,即哪个键范围由哪个节点负责)。

当一个读者走进一号馆问“《三体》在哪?”时,一号馆的工作人员一看自己的地图,发现这本书不归自己管,在三分馆,他不会简单地告诉读者“去三号馆”,而是会非常贴心地说:“您稍等,我直接打电话让三号馆把书送过来,您在我这儿坐着等就行”(返回重定向指令,引导客户端直接连接正确的节点),下次这个读者就知道直接去三号馆了。

Redis Cluster还通过共识算法让这些“智能分馆”之间自动保持沟通,如果一个分馆着火了(节点宕机),其他分馆会很快知道,并共同推举一个“副馆长”顶上来(故障转移),保证服务不中断,增加新分馆(扩容)时,数据迁移的过程也是自动化的。

总结一下

看懂分布式存储,其实就是看懂如何从“单兵作战”到“团队协作”,单机Redis靠内存、单线程和高效模型做到极致性能,分布式Redis则通过分片解决数据量大的问题,通过代理或去中心化的集群解决寻址和管理的复杂度,再通过复制和故障转移来保证高可用,它本质上是一种“分而治之”的思想,把巨大的压力和庞大的数据集,分摊到一群相互配合的普通服务器上,共同完成一项巨大的任务,理解了这套逻辑,你再看其他分布式系统,比如Elasticsearch、HDFS等,就会发现它们的思想内核都是相通的。