1. 前言
Redis 分区技术(又称 Redis Partition)指的是将 Redis 中的数据进行拆分,然后把拆分后的数据分散到多个不同的 Redis 实例(即服务器)中,每个实例仅存储数据集的某一部分(一个子集),我们把这个过程称之为 Redis 分区操作。
Redis 实例指的是一台安装了 Redis 服务器的计算机。
分区(Partition)不仅是 Redis 中的概念,几乎所有数据库管理系统都会涉及到“分区”的应用。因此本节重点介绍有关分区的知识。
2. 分区的优势
Redis 分区技术有两个方面的优势,一是提升服务器的性能,二是提高了服务器的数据存储能力。
一方面,单台机器的 Redis 服务器,其网络 IO 能力和计算资源都是非常有限的,但是如果我们将请求分散到多台机器上,那么就能充分利用多台计算机的算力和网络带宽,从而整体上提升 Redis 服务器的性能。另一方面,随着存储数据的不断增加,单台机器的存储容量会达到极限,若将数据分散存储到多台 Redis 服务器上,其存储能力也将得到大幅度提升。
注意,Redis 分区技术可以利用多台计算机的内存总和,从而创建出大型的 Redis 数据库。
3. 分区常用方法
分区技术有两种常用方法,分别是“范围分区”和“哈希分区”。
1) 范围分区
范围分区是最简单、最有效的分区方法之一。所谓范围分区指的是将特定范围的 key 映射到指定的 Redis 实例上。key 的命名格式如下:
object_name:<id>
比如:user:1、user:2 ...用来表示不同 id 的用户。下面通过一个示例了解范围分区的具体流程:
假设现在共有 3000 个用户,您可以把 id 从 0 到 1000 的用户映射到实例 R0 上,id 从 1001 到 2000 的用户映射到实例 R1 上,以此类推,将 id 从 2001 到 3000 的用户映射到实例 R2 上。
范围分区不仅简单,而且实用,适合许多的特定场景。但当存储的 key 不能按照范围划分时,那么范围分区就不再适用了,比如 key 是一组 uuid(通用唯一识别码)。如下所示:
9eb4d81b-31ec-4c69-a721-c7e1771413dd
此时范围分区就不再适用,就要用到另外一种分区方式——哈希分区。
2) 哈希分区
哈希分区与范围分区相比,它最显著的优势是适合任何形式的 key。哈希分区方法并不复杂比,id 表达式如下所示:
id=hash(key)%N
这里的 id 指的是 Redis 实例的编号,而 N 表示共有多少个 Redis 实例。
首先调用一个 crc32() 哈希函数,它可以将 key 转换为一个整数。 如下所示:
crc32(key)
假如转换后的整数是 93024922,此时共有 4 个 Redis 实例,对整数与实例的数量进行取模运算,就会得到一个 0 到 3 之间的整数,如下所示:
93024922 % 4 = 2
上述计算结果为 2 ,我们就把这个 key 映射到 R2 实例中,如果为 3 就映射到 R3实例中。以此类推,通过这种方式可以将所有的 key 分散到 4 个不同的 Redis 实例中。
4. 分区技术的不足
虽然 Redis 分区技术有诸多优势,但是它也存在一些不足之处。下面做简单介绍:
- 涉及操作多个 key 时,通常不被支持。这是由于批量操作的 key 会被映射到不同的 Redis 实例中,此时无法实现在一个实例中操作分散开的 key;
- 不支持包含多个 key 的 Redis 事务;
- 当使用分区的时候,数据的处理变的非常复杂,比如需要处理多个 .rdb 或者 .aof 存储文件,并且还需要从多个 Redis 实例中备份数据;
- 添加、删除实例变的复杂,比如 Redis 集群支持在运行时增加或减少实例,分区技术不支持这种功能。
5. 分区技术问题解决
我们知道,应用 Redis 分区技术时存在一些不足之处,比如在增加、删除 Redis 实例时会非常麻烦,但这种情况在实际应用中经常遇到。比如今天需要删除 10 台 Redis 实例,明天又要增加 20 台实例。那么对于这种问题,有没有一种较好的解决办法呢?下面进行简单介绍:
其实 Redis 是一种很轻量级的服务(每个实例仅占用 1 MB),针对它的这种特性,我们提出以下解决办法:
在一台机器上开启多个 Redis 实例,您可以从中选择一定数量的实例作为 Redis 工作集群。当集群中某一台机器存储不足时,您可以将一部分 Redis 实例移动到另外一台机器上,依次类推。这样就保证了 Redis 的实例总数不变,又达到了增加机器的目的。