查看“Redis:集群教程”的源代码
←
Redis:集群教程
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Redis]] == 关于 == 参考:[https://redis.io/topics/cluster-tutorial https://redis.io/topics/cluster-tutorial] 以下包含了有关如何设置集群、测试和操作集群的说明,而不涉及Redis 集群规范中涵盖的细节。 == Redis 集群 == Redis Cluster 提供了一种运行 Redis 安装的方法,其中'''数据在多个 Redis 节点之间自动分片'''。 Redis Cluster 还在'''分区期间'''提供了'''一定程度的可用性''',这实际上是在某些节点出现故障或无法通信时继续操作的能力。但是,如果发生较大的故障(例如,当大多数主节点不可用时),集群将停止运行。 那么在实践中,您从 Redis Cluster 中得到了什么? # 在多个节点之间自动拆分数据集的能力。 # 当部分节点出现故障或无法与集群的其余部分通信时继续操作的能力。 === Redis 集群:TCP 端口 === 每个 Redis Cluster 节点都需要打开两个 TCP 连接: # 用于为客户端提供服务的普通 Redis TCP 端口(如:6379); # 以及名为“集群总线端口”(Cluster Bus Port)的第二个端口。 #* 集群总线端口:将数据端口+10000(如:16379)添加10000;或使用集群端口配置覆盖。 第二个高端口用于集群总线,即使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测、配置更新、故障转移授权等。 客户端永远不要尝试与集群总线端口通信,而应始终与正常的 Redis 命令端口通信,但请确保'''在防火墙中打开这两个端口''',否则 Redis 集群节点将无法通信。 请注意,要使 Redis 集群正常工作,您需要为每个节点: # 用于与客户端通信的普通客户端通信端口(通常为6379)将向需要到达群集的所有客户端以及所有其他群集节点(使用客户端端口进行密钥迁移)开放。 # 集群总线端口必须可以从所有其他群集节点访问。 * 如果您不同时打开两个 TCP 端口,您的集群将无法按预期工作。 集群总线使用一种不同的二进制协议进行节点到节点的数据交换,这种协议更适合于使用较少的带宽和处理时间在节点之间交换信息。 === Redis集群 和 Docker === 目前,Redis Cluster 不支持 NATED 环境,也不支持 IP 地址或 TCP 端口重新映射的一般环境。 Docker 使用了一种称为'''端口映射'''的技术:运行在 Docker 容器中的程序可能会使用不同的端口公开,而该端口与程序认为正在使用的端口不同。这对于在同一服务器上同时使用相同端口运行多个容器非常有用。 为了使 Docker 与 Redis 群集兼容,您需要使用 Docker 的'''主机网络模式'''。 * 有关更多信息,请查看 Docker 文档中的“--net=host”选项。 === Redis集群:数据分片 === Redis Cluster 不使用[[http://wiki.eijux.com/%E5%85%B3%E4%BA%8E%EF%BC%9A%E4%B8%80%E8%87%B4%E6%80%A7%E5%93%88%E5%B8%8C%E7%AE%97%E6%B3%95 一致哈希(consistency hashing)]],而是一种不同形式的分片,其中每个键在概念上都是我们所称的'''散列槽'''的一部分。 Redis 集群中有 '''16384'''(2 ^ 14)个哈希槽,使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。 Redis 集群中的'''每个节点负责哈希槽的子集'''。 : 因此,例如,您可能有一个包含3个节点的集群,其中: :# 节点 A 包含从 0 到 5500 的哈希槽。 :# 节点 B 包含从 5501 到 11000 的哈希槽。 :# 节点 C 包含从 11001 到 16383 的哈希槽。 这允许在集群中轻松地添加和删除节点。 : 例如,如果我想添加一个新节点 D,我需要将一些哈希槽从节点 A、B、C 移动到 D。类似地,如果我想从集群中删除节点 A,我可以只将由 A 提供服务的哈希槽移动到 B 和 C。当节点 A 为空时,我可以将其完全从集群中删除。 * 由于将哈希槽从一个节点移动到另一个节点不需要停止操作,因此添加和删除节点,或更改节点持有的哈希槽的百分比,不需要任何停机时间。 '''Redis Cluster 支持多个键操作,只要单个命令执行'''(或整个事务,或 Lua 脚本执行)'''中涉及的所有键都属于同一个哈希槽'''。 用户可以使用名为'''哈希标记(hash tags)'''的概念强制多个键成为同一哈希槽的一部分。 哈希标记记录在 Redis 集群规范中,其要点:如果在一个键的“'''{}'''”括号之间有一个子字符串,则'''只对字符串括号“{}”内的内容进行哈希处理'''。 : 例如“''this{foo}key''”和“''another{foo}key''”保证位于同一个哈希槽中,并且可以在具有多个键作为参数的命令中一起使用。 === Redis集群:主从模型 === 为了在主节点子集出现故障或无法与大多数节点通信时保持可用,Redis Cluster 使用主从模型,其中每个哈希槽具有1个(主节点本身)到 N 个副本(N-1 个附加副本节点)。 在具有节点 A、B、C 的示例集群中,如果节点 B 出现故障,集群将无法继续,因为我们不再能够提供 5501-11000 范围内的哈希槽。 但是,在创建集群时(或稍后),我们会向每个主节点添加一个副本节点,这样最终的集群就由:主节点 A、B、C,从节点 A1、B1、C1 组成。 这样,如果节点 B 出现故障,系统就能够继续:节点 B1 复制 B,如果 B 失败,集群将提升节点 B1 作为新的主节点,并将继续正常运行。 * 但是,请注意,如果节点 B 和 B1 同时出现故障,Redis 群集将无法继续运行。 === Redis集群:一致性保证 === '''Redis Cluster 无法保证强一致性(strong consistency)'''。实际上,这意味着在某些情况下,Redis Cluster 可能会丢失系统已向客户端确认的写入。 Redis Cluster 会丢失写入的第一个原因是因为它使用'''异步复制'''。 : 这意味着在写入期间会发生以下情况: :# 您的客户端写入主 B。 :# 主 B 向您的客户端回复 OK。 :# 主 B 将写入传播到其副本 B1、B2 和 B3。 : 如您所见,B 在回复客户端之前不会等待来自 B1、B2、B3 的确认,因为这对 Redis 来说是一个令人望而却步的延迟惩罚,因此如果您的客户端写入某些内容,B 会确认写入,但如果在将写入发送到其副本之前崩溃,其中一个副本(未收到写入)可以提升为主,那么写入的内容将永远丢失。 这与大多数配置为“每秒将数据刷新到磁盘”的数据库发生的情况非常相似 您可以通过强制数据库在回复客户端之前将数据刷新到磁盘来提高一致性,但这通常会导致效率过低。在 Redis Cluster 的情况下,这相当于同步复制。 基本上,需要在性能和一致性之间进行权衡。 Redis 集群在绝对需要时支持同步写入,通过 '''WAIT''' 命令实现。这使得丢失写入的可能性大大降低。但是,请注意,即使使用同步复制,Redis Cluster 也没有实现强一致性:在更复杂的故障场景下,始终有可能将无法接收写入的副本选为 master。 还有一个值得注意的场景是 Redis 集群将丢失写入,这发生在'''网络分裂'''期间,客户端与少数实例(至少包括一个主实例)隔离。 : 以我们的 6 个节点集群为例,它由 A、B、C、A1、B1、C1 组成,有 3 个主节点和 3 个副本节点。还有一个客户端,我们将其称为 Z1。 : 分区发生后,可能在分区的一侧有 A、C、A1、B1、C1,而在另一侧有 B 和 Z1。 : Z1 仍然能够写入 B,B 将接受其写入。如果分区在很短的时间内恢复,集群将继续正常运行。但是,如果分区持续足够的时间让 B1 在分区的多数侧提升为 master,则 Z1 同时发送给 B 的写入将丢失。 :* 请注意,Z1 能够发送到 B 的写入量有一个最大窗口:如果分区的多数侧已经有足够的时间来选举一个副本作为主节点,则少数侧的每个主节点都将停止接受写入。 这个时间量是 Redis Cluster 的一个非常重要的配置指令,称为'''节点超时'''。 : 节点超时后,主节点被视为发生故障,并且可以由其副本之一替换。类似地,在节点超时后,主节点无法感知大多数其他主节点,它会进入错误状态并停止接受写入。 == Redis集群配置参数 == Redis Cluster 在 redis.conf 文件中引入的配置参数: * '''cluster-enabled <yes/no>''':如果 yes,则在特定 Redis 实例中启用 Redis Cluster 支持。否则,该实例像往常一样作为独立实例启动。 * '''cluster-config-file <filename>''':注意,尽管这个选项的名称,'''这不是一个用户可编辑的配置文件''',而是一个 Redis Cluster 节点在每次有变化时自动持久化集群配置(状态,基本上)的文件,以便能够在启动时重新读取它。 ** 该文件列出了集群中的其他节点、它们的状态、持久变量等内容。 ** 由于某些消息接收,此文件通常会被重写并刷新到磁盘上。 * '''cluster-node-timeout <milliseconds>''':节点超时值,Redis 集群节点不可用而不被视为失败的最长时间。 *: 如果主节点在指定的时间内无法访问,它将由其副本进行故障转移。 ** 该参数控制 Redis Cluster 中的其他重要事项。 ** 值得注意的是,在指定的时间内无法访问大多数主节点的每个节点都将停止接受查询。 * '''cluster-slave-validity-factor <factor>''': *# 如果设置为 0,副本将始终认为自己有效,因此无论主服务器和副本之间的链接保持断开连接的时间长短,将始终尝试故障转移主服务器。 *# 如果值为正,则将节点超时值乘以此选项提供的因子,作为最大断开时间,并且如果节点是副本,在主链接断开的时间超过指定的时间,它不会尝试启动故障转移。 *: 例如,如果节点超时设置为 5 秒且有效性因子设置为 10,则与主服务器断开连接超过 50 秒的副本将不会尝试对其主服务器进行故障转移。 ** 请注意,如果没有用于故障转移的副本,则任何非零值都可能导致 Redis 集群在主节点故障后不可用。在这种情况下,只有当原始主节点重新加入集群时,集群才会恢复可用。 * '''cluster-migration-barrier <count>''':一个 master 将保持连接的最小副本数,以便另一个副本迁移到不再被任何副本覆盖的 master。【?】 * '''cluster-require-full-coverage <yes/no>''': *# 如果将其设置为 yes(默认),如果任何节点都没有覆盖一定百分比的 key space,则集群将停止接受写入。 *# 如果该选项设置为 no,即使只能处理关于 key 子集的请求,集群仍将提供查询服务。 * '''cluster-allow-reads-when-down <yes/no>''': *# 如果设置为 no(默认),当集群被标记为失败时,Redis 集群中的节点将停止服务所有流量,无论是当节点数量无法达到主机的 quorum配置,还是没有达到全覆盖。 *#* 这可以防止从不知道集群中的变化的节点读取可能不一致的数据。 *# 可以将此选项设置为 yes 以允许在失败状态期间从节点读取,这对于希望优先考虑读取可用性但仍希望防止不一致写入的应用程序非常有用。 *#* 它也可以用于使用只有一个或两个分片的 Redis Cluster 时,因为它允许节点在主节点发生故障但无法自动故障转移时继续提供写入服务。 == 创建并使用Redis群集 ==
返回至“
Redis:集群教程
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息