ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

选译:Reids 集群规格

2021-10-21 01:04:04  阅读:599  来源: 互联网

标签:副本 重定向 选译 Reids 写入 集群 节点 客户端


Redis 集群目标

  • 高性能:可线性伸缩到1000个节点,无代理通信,使用异步复制,不对值执行merge操作。

  • 一致性:可接受程度内的写安全。对于连接到主节点中”大多数“的客户端,系统会最大程度保留他们的写入。

  • 可用性:当主节点中”大多数“可达,且每个不可达的主节点至少有一个可达的副本,集群能够在分区中存活。

    副本迁移:一个副本都没有的主节点,可以从其他拥有多个副本的主节点接收一个副本。

子集实现

Reids 单机版支持的单键命令,Reids 集群也支持。

对于复杂的多键命令,如果这些键都被哈希到相同的槽,Reids 集群也支持。

Reids 集群支持"hash tag"的概念,用来强制某些键存储到同一个哈希槽。

Reids 集群不支持多个数据库,只有0号数据库。

服务端和客户端在 Reids 集群中扮演的角色

  • 集群节点负责承载集群的数据和状态,包括把键映射到正确的节点。
  • 集群节点可以相互发现,探测不能工作的节点。当故障发生时,为了能够继续操作集群,集群节点可以把副本提升为主节点。
  • 集群节点使用 TCP 总线、二进制协议相互通信,也叫集群总线。
  • 为了发现新节点,集群节点之间使用 gossip 协议广播集群信息。使用 ping 包确认其他节点正常工作,使用集群消息通知特定的条件。
  • Pub/Sub 消息通过集群总线广播到整个集群。
  • 系统管理员执行手动故障转移也是通过集群总线编排实现。
  • 集群节点不代理请求,使用重定向错误-MOVE或-ASK可以把客户端重定向到其他节点。理论上,客户端可以向任意集群节点发送请求,但根据需要,客户端可能会被重定向。客户端不必须保存集群的状态,但客户端可以缓存键和节点之间的映射关系,合理地提升性能。

写安全

  • 集群节点之间使用异步复制,以最后被选中的主节点数据集为准,覆盖其他副本的数据(如果有差异)。发生分区的期间,会有一个时间窗口,期间的写入可能会丢失。

  • 被分区中的大多数所接受、确认的写入,在故障期间,写入丢失的例子:

    1. 写入已经被主节点接受,客户端收到回复(确认),但写入异步复制到副本失败。等待足够久的时间后,其中一个副本被提升为主节点。

    2. 主节点因为分区而不可达,被其中一个副本代替,一段时候后恢复可达,然后旧的主节点被转换为副本。客户端因为缓存了路由表(键-节点),在旧的主节点被转换为副本之前,向它写入了数据。

  • 当一个主节点不能被主节点中的大多数访问,持续时间达到 NODE_TIMEOUT,主节会被其副本替换。如果在 NODE_TIMEOUT 之前分区被解决,没有写入丢失,否则期间的写入会丢失。(因为分区)如果主节点中的少数在持续 NODE_TIMEOUT 时间之后,仍然无法连接上主节点中的大多数,主节点中的少数进入拒接写入的状态。

性能

  • redis 集群节点不会把命令转发到负责该命令键的节点,但是会重定向客户端到正确的节点。
  • 客户端最终可以得到键和节点之间的正确映射关系,直接向正确的节点发送命令。
  • 因为使用了异步复制,客户端不会等待其他节点的写入确认,除非使用WAIT命令。
  • 集群性能根据主节点的数量线性伸缩。通常客户端和节点保持持久链接,延迟也不会增加。
  • 高性能,高伸缩性,弱数据安全,弱可用性,是 redis 集群的主要目标。

键分布式模型

键空间被划分为16384个槽,集群中的每个主节点负责16384个槽中的一个子集。

HASH_SLOT = CRC16(key) mod 16384

键 hash tag

hash tag 保证多个键被哈希到同一个槽。

def HASH_SLOT(key)
    s = key.index "{"
    if s
        e = key.index "}",s+1
        if e && e != s+1
            key = key[s+1..e-1]
        end
    end
    crc16(key) % 16384
end

重定向和重分片

MOVED 重定向

  • redis 客户端可以向任意节点发送请求,包括副本节点。如果请求是可接受的(单键请求,或者是多键请求但键都在同一个槽),节点会去查找负责(键所属)哈希槽的节点。如果哈希槽正好由当前节点负责,直接处理请求,否则查找内部映射表(槽->节点),回复 MOVED 错误:

    GET x
    -MOVED 3999 127.0.0.1:6381
    

    3999为键所属槽,127.0.0.1:6381为能处理此请求的实例IP和端口。

  • 客户端需要重新发送请求到对应的实例。

  • 客户单应该记住3999号槽由127.0.0.1:6381实例负责。下次要发送请求时,计算键所在哈希槽,有更大几率直接选中正确的节点。

  • 另一个方案是,当收到MOVED重定向时,使用 CLUSTER NODES 或者 CLUSTER SLOTS 命令查询集群内所有槽->节点的映射关系。

ASK 重定向

  • 案例:8号槽由节点A负责,现在要把所有属于8号槽的键(可能有很多),由节点A迁移到节点B,键迁移过程中,8号槽仍然由节点A负责,直至所有键迁移完成后,8号槽开始由节点B负责。
  • 键迁移过程中,可能一部分键还在旧节点A上,一部分键已经在新节点B上。
  • 客户端向节点A请求8号槽的foo键,此时迁移还在进行中,但foo键已经迁移到新节点B,A节点给客户端返回ASK重定向,重定向至节点B。
  • 客户单收到至节点B的ASK重定向后,先向节点B发送ASKING命令,随后重新向节点B发送foo键的请求。
  • 如果节点B收到8号槽foo键的请求,但是前面没有ASKING命令,节点B不作处理,给客户端返回MOVED重定向,重定向至节点A。因为迁移还未完成,8号槽仍然由节点A负责。
  • 客户端不应该更新本地槽->节点的映射,错误地认为8号槽已经由节点B负责。随后关于8号槽其他键的请求,客户端仍要先发送到节点A,收到明确的ASK重定向后才能重新发送(到节点B)。
  • 所有键迁移完成后,8号槽开始由节点B负责,客户端向节点A请求8号槽键,会被MOVED重定向到节点B。

客户端首次连接&重定向的处理

下列情况下,客户端通常需要完整地获取所有槽->节点的映射:

  • 启动初始化
  • 收到MOVED重定向

参考 CLUSTER SLOTS 命令。

多键操作

当某个槽正处于重新分片的过程中,属于此槽的键是不可用的。

用副本节点伸缩读操作

连接可以开启只读模式,暗示客户端可以接受“过时”的数据,对正在进行中的写入不感兴趣。

参考 READONLY 命令。

标签:副本,重定向,选译,Reids,写入,集群,节点,客户端
来源: https://www.cnblogs.com/roy2220/p/15431520.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有