四、redis之分区讲解

分区是将您的数据拆分为多个 Redis 实例的过程,本文档的第一部分将向您介绍分区的概念,第二部分将向您展示 Redis 分区的替代方案。

一、分区的概念


1.1 Redis 中的分区有两个主要目标:

  • 它允许使用多台计算机内存的总和来创建更大的数据库。如果不进行分区,您将受到单个计算机可以支持的内存量的限制。
  • 它允许将计算能力扩展到多核和多台计算机,并将网络带宽扩展到多台计算机和网络适配器。

1.2 分区基础

有不同的划分标准。想象一下,我们有四个 Redis 实例R0、R1、R2、R3和许多代表用户的键,如user:1、user:2、 … 等等,我们可以找到不同的方法来选择在哪个实例中存储给定的键。换句话说,有不同的系统可以将给定的键映射到给定的 Redis 服务器。

1.2.1 范围分区

执行分区的最简单方法之一是使用范围分区,它是通过将对象范围映射到特定 Redis 实例来实现的。例如,我可以说从 ID 0 到 ID 10000 的用户将进入实例R0,而从 ID 10001 到 ID 20000 的用户将进入实例R1等等。

该系统有效并在实际中使用,但是,它的缺点是需要一个将范围映射到实例的表。这个表需要管理,每种对象都需要一个表,因此Redis中的范围分区通常是不可取的,因为它比其他替代分区方法效率低得多。

1.2.2 散列分区(一致性分区)

范围分区的替代方法是散列分区。该方案适用于任何键,不需要表单中的键object_name:,并且非常简单:

获取键名并使用散列函数(例如,crc32散列函数)将其转换为数字。例如,如果键是foobar,crc32(foobar)将输出类似93024922.
对这个数字使用模运算,将它转换成一个 0 到 3 之间的数字,这样这个数字就可以映射到我的四个 Redis 实例之一。93024922 modulo 4equals 2,所以我知道我的密钥foobar应该存储到R2实例中。注意:模运算返回除法运算的余数,并%在许多编程语言中使用运算符实现。
还有许多其他方法可以执行分区,但是通过这两个示例,您应该明白了。哈希分区的一种高级形式称为一致性哈希,由一些 Redis 客户端和代理实现。

1.3 分区的不同实现

分区可以由软件堆栈的不同部分负责。

  • 客户端分区意味着客户端直接选择正确的节点来写入或读取给定的键。许多 Redis 客户端实现了客户端分区。
  • 代理辅助分区意味着我们的客户端将请求发送到能够使用 Redis 协议的代理,而不是直接将请求发送到正确的 Redis 实例。代理将确保根据配置的分区模式将我们的请求转发到正确的 Redis 实例,并将回复发送回客户端。Redis 和 Memcached 代理Twemproxy实现了代理辅助分区。
  • 查询路由意味着您可以将查询发送到随机实例,该实例将确保将您的查询转发到正确的节点。Redis Cluster 在客户端的帮助下实现了一种混合形式的查询路由(请求不是直接从 Redis 实例转发到另一个实例,而是客户端被重定向到正确的节点)。

1.4 分区的缺点

Redis 的一些特性在分区时不能很好地发挥作用:

  • 通常不支持涉及多个键的操作。例如,如果两个集合存储在映射到不同 Redis 实例的键中,则不能执行它们之间的交集(实际上有方法可以做到这一点,但不是直接的)。
  • 不能使用涉及多个键的Redis事务。
  • 分区粒度是关键,因此不可能像非常大的排序集那样使用单个巨大的键对数据集进行分片。
  • 使用分区时,数据处理更加复杂,例如您必须处理多个 RDB / AOF 文件,并且要备份您的数据,您需要聚合来自多个实例和主机的持久性文件。
  • 添加和删​​除容量可能很复杂。例如,Redis Cluster 支持大部分透明的数据重新平衡,能够在运行时添加和删除节点,但其他系统(如客户端分区和代理)不支持此功能。然而,一种称为预分片的技术在这方面有所帮助。

1.5 数据存储还是缓存?

尽管 Redis 中的分区在概念上是相同的,无论是将 Redis 用作数据存储还是缓存,但将其用作数据存储时存在重大限制。当 Redis 用作数据存储时,给定的键必须始终映射到同一个 Redis 实例。当Redis用作缓存时,如果给定节点不可用,使用不同的节点也不是大问题,改变key-instance映射,因为我们希望提高系统的可用性(即提高系统可用性的能力)系统回复我们的查询)。

如果给定键的首选节点不可用,则一致的散列实现通常能够切换到其他节点。同样,如果添加新节点,部分新密钥将开始存储在新节点上。

这里的主要概念如下:

如果将 Redis 用作缓存,则使用一致散列扩展和缩减是很容易的。
如果Redis用作存储,则使用固定的key-to-nodes映射,因此节点数必须固定且不能变化。否则,需要一个能够在添加或删除节点时在节点之间重新平衡键的系统,目前只有 Redis Cluster 能够做到这一点 - Redis Cluster已于 2015 年 4 月 1 日全面可用且可用于生产。

1.6 预分片

我们了解到分区的一个问题是,除非我们使用 Redis 作为缓存,否则添加和删除节点可能会很棘手,使用固定的键实例映射要简单得多。

然而,数据存储需求可能会随着时间的推移而变化。今天我可以使用 10 个 Redis 节点(实例),但明天我可能需要 50 个节点。

由于 Redis 占用空间极小且轻量级(一个备用实例使用 1 MB 内存),因此解决此问题的一个简单方法是从一开始就从大量实例开始。即使您只从一台服务器开始,您也可以决定从一开始就生活在分布式世界中,并使用分区在您的单个服务器上运行多个 Redis 实例。

并且您可以从一开始就选择此数量的实例非常大。例如,32 或 64 个实例可以满足大多数用户的需求,并提供足够的增长空间。

通过这种方式,随着您的数据存储需求增加并且需要更多 Redis 服务器,您只需将实例从一台服务器移动到另一台服务器即可。添加第一台附加服务器后,您需要将一半的​​ Redis 实例从第一台服务器移至第二台,依此类推。

使用 Redis 复制,您可能能够在用户停机时间最少或无需停机的情况下完成迁移:

在新服务器中启动空实例。
移动将这些新实例配置为源实例的从属实例的数据。
停止你的客户。 使用新的服务器 IP 地址更新已移动实例的配置。
将SLAVEOF NO ONE命令发送到新服务器中的从站。
使用新的更新配置重新启动客户端。 最后关闭旧服务器中不再使用的实例。

1.7 Redis 分区的实现

到目前为止,我们在理论上介绍了 Redis 分区,但是实践呢?你应该使用什么系统?

1.7.1 Redis 集群

Redis Cluster 是获得自动分片和高可用的首选方式。自2015 年 4 月 1 日起,它已普遍可用并可供生产。您可以在集群教程 中获取有关 Redis 集群的更多信息。

一旦 Redis Cluster 可用,并且如果您的语言有兼容 Redis Cluster 的客户端可用,Redis Cluster 将成为 Redis 分区的事实上的标准。

Redis Cluster 是查询路由和客户端分区的混合体。

1.7.2 Twemproxy

Twemproxy 是 Twitter为 Memcached ASCII 和 Redis 协议开发的代理。它是单线程的,是用 C 语言编写的,而且速度非常快。它是根据 Apache 2.0 许可条款发布的开源软件。

Twemproxy 支持在多个 Redis 实例之间自动分区,如果节点不可用,则可选择节点弹出(这将更改键实例映射,因此仅当您将 Redis 用作缓存时才应使用此功能)。

这不是单点故障,因为您可以启动多个代理并指示您的客户端连接到第一个接受连接的代理。

基本上 Twemproxy 是客户端和 Redis 实例之间的中间层,它将可靠地为我们处理分区,同时将额外的复杂性降至最低。

您可以在这篇 antirez 博客文章中阅读有关 Twemproxy 的更多信息。

1.7.3 支持一致性哈希的客户端

Twemproxy 的替代方案是使用通过一致散列或其他类似算法实现客户端分区的客户端。有多个 Redis 客户端支持一致性哈希,特别是Redis-rb、Predis和Jedis。

上一篇:三、 揭秘Redis持久化
下一篇:五、Redis 哨兵sentinel(主从复制)讲解与搭建(保姆式解析!!!)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿小许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值