什么是 Redis?图解深入了解 Redis 高性能、高可用的秘密

  • 单个 Redis 实例
  • Redis 高可用性
  • Redis 哨兵
  • Redis 集群

根据你的用例和规模,决定使用哪一种设置。

单个 Redis 实例

什么是 Redis?图解深入了解 Redis 高性能、高可用的秘密

单个 Redis 实例是最直接的 Redis 部署方式。它允许用户设置和运行小型实例,从而帮助他们快速发展和加速服务。但是,这种部署并非没有缺点。例如,如果此实例失败或不可用,则所有客户端对 Redis 的调用都将失败,从而降低系统的整体性能和速度。

如果有足够的内存和服务器资源,这个实例可以很强大。主要用于缓存的场景可能会以最少的设置获得显著的性能提升。给定足够的系统资源,你可以在应用程序运行的同一机器上部署此 Redis 服务。

在管理系统内的数据方面,了解一些 Redis 概念是必不可少的。发送到 Redis 的命令首先在内存中处理。然后,如果在这些实例上设置了持久性,则在某个时间间隔上会有一个fork进程,来生成数据持久化 RDB(Redis 数据的非常紧凑的时间点表示)快照或 AOF(仅附加文件)。

这两个流程可以让 Redis 拥有长期存储,支持各种复制策略,并启用更复杂的拓扑。如果 Redis 未设置为持久化数据,则在重新启动或故障转移时数据会丢失。如果在重启时启用了持久化,它会将 RDB 快照或 AOF 中的所有数据加载回内存,然后实例可以支持新的客户端请求。

话虽如此,让我们看看你可能会用到的更多分布式 Redis 设置。

Redis 高可用性

什么是 Redis?图解深入了解 Redis 高性能、高可用的秘密

Redis 的另一个流行设置是主从部署方式,从部署保持与主部署之间数据同步。当数据写入主实例时,它会将这些命令的副本发送到从部署客户端输出缓冲区,从而达到数据同步的效果。从部署可以有一个或多个实例。这些实例可以帮助扩展 Redis 的读取操作或提供故障转移,以防 main 丢失。

我们现在已经进入了一个分布式系统,因此需要在此拓扑中考虑许多新事物。以前简单的事情现在变得复杂了。

Redis 复制

Redis 的每个主实例都有一个复制 ID 和一个偏移量。这两条数据对于确定副本可以继续其复制过程的时间点或确定它是否需要进行完整同步至关重要。对于主 Redis 部署上发生的每个操作,此偏移量都会增加。

更明确地说,当 Redis 副本实例仅落后于主实例几个偏移量时,它会从主实例接收剩余的命令,然后在其数据集上重放,直到同步完成。如果两个实例无法就复制 ID 达成一致,或者主实例不知道偏移量,则副本将请求全量同步。这时主实例会创建一个新的 RDB 快照并将其发送到副本。

在此传输之间,主实例会缓冲快照截止和当前偏移之间的所有中间更新指令,这样在快照同步完后,再将这些指令发送到副本实例。这样完成后,复制就可以正常继续。

如果一个实例具有相同的复制 ID 和偏移量,则它们具有完全相同的数据。现在你可能想知道为什么需要复制 ID。当 Redis 实例被提升为主实例或作为主实例从头开始重新启动时,它会被赋予一个新的复制 ID。

这用于推断此新提升的副本实例是从先前哪个主实例复制出来的。这允许它能够执行部分同步(与其他副本节点),因为新的主实例会记住其旧的复制 ID。

例如,两个实例(主实例和从实例)具有相同的复制 ID,但偏移量相差几百个命令,这意味着如果在实例上重放这些偏移量后面的命令,它们将具有相同的数据集。现在,如果复制 ID 完全不同,并且我们不知道新降级(或重新加入)从节点的先前复制 ID(没有共同祖先)。我们将需要执行昂贵的全量同步。

相反,如果我们知道以前的复制 ID,我们就可以推断如何使数据同步,因为我们能够推断出它们共享的共同祖先,并且偏移量对于部分同步再次有意义。

Redis 哨兵(Sentinel)

什么是 Redis?图解深入了解 Redis 高性能、高可用的秘密

Sentinel 是一个分布式系统。与所有分布式系统一样,Sentinel 有几个优点和缺点。Sentinel 的设计方式是,一组哨兵进程协同工作以协调状态,从而为 Redis 提供高可用性。毕竟,你不希望保护你免受故障影响的系统有自己的单点故障。

Sentinel 负责一些事情。首先,它确保当前的主实例和从实例正常运行并做出响应。这是必要的,因为哨兵(与其他哨兵进程)可以在主节点和/或从节点丢失的情况下发出警报并采取行动。其次,它在服务发现中发挥作用,就像其他系统中的 Zookeeper 和 Consul 一样。所以当一个新的客户端尝试向 Redis 写东西时,Sentinel 会告诉客户端当前的主实例是什么。

因此,哨兵不断监控可用性并将该信息发送给客户端,以便他们能够在他们确实进行故障转移时对其做出反应。

以下是它的职责:

  • 监控——确保主从实例按预期工作。
  • 通知——通知系统管理员 Redis 实例中的事件。
  • 故障转移管理——如果主实例不可用并且足够多的(法定数量)节点同意这是真的,Sentinel 节点可以启动故障转移。
  • 配置管理——Sentinel 节点还充当当前主 Redis 实例的发现服务。

以这种方式使用 Redis Sentinel 可以进行故障检测。此检测涉及多个哨兵进程同意当前主实例不再可用。这个协议过程称为 Quorum。这可以提高鲁棒性并防止一台机器行为异常导致无法访问主 Redis 节点。

此设置并非没有缺点,因此我们将在使用 Redis Sentinel 时介绍一些建议和最佳实践。

你可以通过多种方式部署 Redis Sentinel。老实说,要提出任何明智的建议,我需要有关你的系统的更多背景信息。作为一般指导,我建议在每个应用程序服务器旁边运行一个哨兵节点(如果可能的话),这样你也不需要考虑哨兵节点和实际使用 Redis 的客户端之间的网络可达性差异。

你可以将 Sentinel 与 Redis 实例一起运行,甚至可以在独立节点上运行,只不过它会按照别的方式处理,从而会让事情变得更复杂。我建议至少运行三个节点,并且至少具有两个法定人数(quorum)。这是一个简单的图表,分解了集群中的服务器数量以及相关的法定人数和可容忍的可持续故障。

Number of Servers Quorum Number Of Tolerated Failures
1 1 0
2 2 0
3 2 1
4 3 1
5 3 2
6 4 2
7 4 3