Redis 序列之四——Redis的Sharding(分片机制)

          Sharding机制:即通常所说的“分片”,允许数据存放在不同的物理机器上,以适应数据量过大的场景,克服单台机器内存或者磁盘空间的限制。而这种“离散式”地存放,对客户端来说是透明的,对客户端来讲,完全看不到这种差别。

          Redis的分片(Sharding或者Partitioning)技术:是指将数据分散到多个Redis实例中的方法,分片之后,每个redis拥有一部分原数据集的子集。在数据量非常大时,这种技术能够将数据量分散到若干主机的redis实例上,进而减轻单台redis实例的压力。分片技术能够以更易扩展的方式使用多台计算机的存储能力(这里主要指内存的存储能力)和计算能力:

          (1)从存储能力的角度,分片技术通过使用多台计算机的内存来承担更大量的数据,如果没有分片技术,那么redis的存储能力将受限于单台主机的内存大小。

          (2) 从计算能力的角度,分片技术通过将计算任务分散到多核或者多台主机中,能够充分利用多核、多台主机的计算能力。

          下面将以举例的方式说明分片技术及其存在的优势:

          示例1:未采用分片技术,有1000万条用户信息数据,以键值对:UsrID:UsrInfo的形式存储在一个redis实例中,此时所有的用户信息都会存储在一个redis实例中,对这1000万条数据的所有插、查、删、该操作压力都会集中在这个redis所在的主机上;此时所要考虑的问题不仅有存储和操作对该主机的压力,还有该主机失效时将导致所有操作都无法进行的问题。如下图1所示:

  
                               Redis 序列之四——Redis的Sharding(分片机制)
  

             示例2:采用分片技术;有1000万条用户信息数据,以键值对:UsrID:UsrInfo的形式存储于redis中,此时有4台主机,每台主机运行一个Redis实例:主机A (Redis1)、主机B(Redis2)、主机C(Redis3)、主机D(Redis4),分片时算法为:

             redis_index = 用户的ID % 4 + 1;

             例如ID为10000654则可得到到redis_index的值:10000654 % 4 + 1 = 1,即用户10000654的信息将被放到Redis1上,所有对用户1000654的操作也将被分片到Redis1上;假如用户ID以顺序方式出现,这1000万条用户信息将被平均分配到这四台主机的各Redis实例上,如下图2所示:

 
                   Redis 序列之四——Redis的Sharding(分片机制)
 

           采用分片之后,数据将被分散到4个redis实例中,对数据的操作也被分散到每个redis实例中,此时单台主机的压力将大大减轻。

           预分片技术(pre-sharding)技术:

           Redis目前不支持动态分片操作,扩容和缩容操作都会比较复杂,尤其分片操作部署在客户端时,需要重新配置和启动客户端。在使用过程中缩容用的不多,扩容可以采用预分片策略来缓解此问题。

           在正常运营环境中,一般所存储的数据会逐渐增加,可能今天只要10个redis实例就能应付,但是到了一年以后就需要50个redis实例才能支撑,因此,redis的扩容是经常用到的功能,在redis的分布式部署中,有预分片技术是非常好用的方法之一;

            预分片技术是指在开始时就启动足够多的redis实例(例如32或64个,估计一下够以后扩展用就行了),等到后续需要扩容的时候,只需要将其中一部分的redis实例转移到新增加的机子上即可,在redis实例迁移过程中使用redis的复制功能可以最大限度的降低redis的停工时间甚至可以做到没有停工时间。由于redis实例是轻量级的进程,而且占用内存较少,这里指单纯的空的redis实例,一个空的redis实例大约占用1M的内存;因此,这种方式即不会占用太多系统开销,又便于实现;

             Redis的预分片技术可以按照以下步骤进行实例迁移操作:

              (1)在新机子上启动新的redis实例;

              (2)将新redis实例作为slave将原redis实例作为master,将数据从原redis实例迁移到新redis实例上;

              (3)停止客户端(分片操作在客户端上时)或代理服务器(分片操作在代理上);

              (4)更新客户端或者代理服务器中的配置信息,去掉被迁移的原redis实例的ip和端口等信息,加上新启动redis实例的IP地址和端口;

              (5)向新启动的redis发送SLAVEOF NOONE命令,终止新redis实例对原redis实例的从属关系;

              (6)重启客户端程序或者代理程序,此时它们将会使用新的redis实例;

              (7)关掉被迁移走数据的原redis实例。

相关推荐