redis 设置timeout_Redis集群(cluster)-上:Redis集群介绍

本文简述Redis集群的自动数据分片、主从模式保证服务连续性,以及配置参数如`node timeout`的重要作用。Redis 3.0引入集群功能,通过16384个哈希槽实现数据分布,并使用主从复制应对节点故障。集群在部分节点故障时仍能提供服务,但不保证强一致性。
摘要由CSDN通过智能技术生成

Redis集群简述

本篇文章对Redis集群做一个简单的了解,并介绍如何快速部署一套Redis集群,测试以及操作集群,对Redis的深入介绍将会留在下一篇文章.

这里需要注意的是,Redis集群是在Redis Version 3.0新推出的功能,老的版本并不支持.

Redis集群提供了一种数据会自动切片到多个节点上的部署方式,想象一张表,假设这张表有一亿行数据,那么切片相当于将该表分成N份,每一个节点都保存该表的数据的1/N,Redis的切片就是将数据切割分散到集群中各个节点中,每个节点都会维护Redis数据中的一部分,每个节点都是不可分割的.

Redis集群同时也提供了在部分集群节点故障时集群的可靠性,这也意味着在集群部分节点宕机后集群仍然可以正常提供服务,然而这也不代表集群是一劳永逸的,因为一旦大规模的集群宕机发生后,例如机柜断电跳闸等,集群依旧会出现服务不可用的现象.

综上所述,Redis集群主要提供以下功能:

  • 自动将数据切片并分散到多个集群节点.
  • 集群中部分节点宕机后不影响集群正常提供服务.

Redis集群TCP端口号

Redis集群中的每个节点需要两个tcp端口,一个是6379,该端口主要服务于客户端的连接,另一个端口是16379,即在服务客户端的端口号默认加10000,如TCP5000端口号用来服务客户端,那么另外一个端口就是TCP15000.

第二个端口号用来实现集群的bus功能,bus的意思是集群所有节点都是通过该端口来,就像一根总线将各个节点串起来一样,Redis bus是一种通过二进制协议点到点的通道,集群节点通过Redis bus进行故障探测,配置更新,故障转移授权等等.客户端不会尝试连接该bus端口.

Redis数据分片

Redis集群不使用一致性哈希,而是不同形式的分片,这可以确保每个key都可以存入到一个我们称之为哈希槽(hash slot)中

Redis集群中共有16384个哈希槽(hash slot),通过CRC16算法可以计算出一个给定的key属于哪个哈希槽中.集群中的每个节点都负责处理这16384个哈希槽的一部分.

例如,在一个三个节点组成的集群中:

  • 节点A负责处理0到5500个哈希槽
  • 节点B负责处理5501到11000个哈希槽
  • 节点C负责处理11001到16383个哈希槽

通过这种方法我们可以很方便的向集群添加或者移除节点.例如我们想添加一个节点D到集群,只需要从节点A或B或C负责的哈希槽中转移一部分到节点D上,节点D即可以上线提供服务.又例如节点A因硬件性能问题需要退役,我们只需要将节点A负责的哈希槽转移到其他节点上,即可将A节点从集群剔除.

从集群节点移动哈希槽到另一个节点不需要停止服务,增加或者移除节点,修改一个集群节点负责处理的哈希槽的百分比等等也不需要宕机时间.

Redis集群支持多键操作,前提是单个命令执行(事务或者lua脚本)中所涉及的键都属于同一个哈希槽,这里可以通过使用成为哈希标记(hash tag)的方式来强制所有的键被分配到统一个槽.

所谓的hash tag,例如在如下key中通过CRC16算法计算后会属于不同的槽

user_id_12389_username

user_id_12389_age

user_id_12389_address

但是我们通过将键的关键字user_id_12389使用花括号括起来时,只有花括号中的部分才会被CRC16算法哈希,这样它们的计算结果是一样的,所以都会被分配到一个哈希槽.

{user_id_12389}_username

{user_id_12389}_age

{user_id_12389}_address

Redis集群的主从模式

前面提到过,Redis集群支持在部分集群节点宕机后仍然可以向外提供服务,这个功能依赖于集群节点的主从模式,Redis集群使用主从模式确保在每个Master节点负责处理的哈希槽能够复制到它的从节点.

传统Redis集群架构

fdc706c0313cd57fc3ed0941de479ce4.png

传统Redis集群架构

引入主从模式的Redis集群架构

2f4207ea8544f24000634daf639ff37d.png

引入主从模式的Redis集群架构

如上图所示,在Redis集群中没有引入主从模式之前,如果节点B因为故障导致下线,那么节点B负责的5501~11000哈希槽也会进入下线状态,并没有其他节点负责处理这些哈希槽,因此会导致整个集群无法提供服务.

Redis集群引入主从模式(就是在每个提供服务的节点添加一个从节点)后,集群变成了三主三从(假设集群有6个节点),那么当节点B宕机后,它的从节点B1会被集群授权并选举为主节点接管节点B的5501~11000哈希槽并继续接收服务请求.

这里需要注意的是,如果节点B和它的从节点B1同时宕机,那么集群也会服务不可用,但是这种现象出现的概率还是比较低的.

Redis集群一致性保证

Redis集群没有严格意义的一致性,这也意味着在特定的条件下,Redis集群可能会丢失系统已经反馈客户端写入成功的部分写操作.

这是因为Redis集群采用的是异步的复制,这就意味着,一个写操作会按照如下步骤发生.

  1. 客户端将数据写到节点B上.
  2. 节点B回复客户端写入完成.
  3. 节点B将写操作复制到B的从节点B1,B2,B3.

从上述写的步骤可以看到,节点B在回复客户端写入成功之前并不会等待从节点B1,B2,B3反馈确认写入从节点成功的回复.这会导致一个问题,例如节点B回复客户端写入成功后宕机了,恰好这个写操作还没有同步到从节点,其中一个从节点B1被授权并升级成主节点继续提供服务,但是B1已经丢失了同步失败的数据.

这和传统数据库中每秒将内存数据刷新到磁盘的操作相似,即使我们可以强制要求回复客户端写成功之前必须先确保数据已经写入到从节点,但是这会带来延迟的问题.

Redis集群也支持同步写操作,通过wait命令可以实现,这可以将写操作丢失的风险降到最低,这里需要注意的是Redis集群非强一致性,即使我们引入同步复制,可能会有更加复杂的情况会导致从节点会落后于主节点.

另外还一种情况会使Redis集群丢失部分写操作,例如在一个网络分区故障下,Redis集群被分割两个部分,而客户端连接的正好是这个集群中的一小部分(这个小部分至少包含一个Master节点).

Redis集群网络分区故障

eb77ff1ee357dbc52623824cb0f43690.png

Redis集群网络分区故障

例如在上述现象中,节点A因为网络分区故障导致和集群大多数节点隔离,恰巧此时客户端连接的是节点A,同时写入数据的哈希槽也是由节点A负责,那么客户端还是可以正常写入的,因为客户端并不知道集群已经出现网络故障,如果网络分区故障很快恢复后,那么集群仍然可以正常提供服务,然而如果网络分区故障超过特定的时间,导致从节点A1被集群授权并选举为新的主节点向外提供服务,那么之前客户端写入到节点A的操作都会丢失.

需要注意的是,在网络分区故障中,客户端写入数据到节点A有一个最大的时间窗口限制,如果超过最大时间限制后节点A仍然故障,那么集群中大多数节点会将从节点A1选举为新的主节点接替节点A的工作,处于网络故障的主节点A就会停止接收客户端的写入操作.

在Redis集群中这个最大时间窗口限制的配置参数称为"node timeout".

该超时参数的值非常重要,如果节点故障并超过该timeout的值,那么该节点会被集群认为故障,可以被它的从节点替换掉,相似的,如果发生故障的主节点超过该timeout的值后没有和集群大多数节点通信,也会认为自己处于故障状态,将自己进入错误状态并停止接收写入操作.

Redis集群配置参数

  • cluster-enabled : 是否启动Redis集群模式
  • cluster-config-file : 这里需要注意的是,该文件不是可编辑的,是由Redis集群自动去维护,Redis集群将集群状态,基本信息等持久化到该文件,每次集群配置变更时,都会同步到该文件,所以该文件会经常自动被覆盖,在下次Redis集群重启后会自动加载该文件,该文件包含集群其他节点的信息,状态,持久化的一些变量等.
  • cluster-node-timeout : 集群节点不可达的最大的超时时间,但并不会被认为是故障,如果一个主节点达到该超时时间后仍然不可达,该主节点将会被它的从节点执行故障转移,该参数也控制着Redis集群中其他重要的设置,尤其是当集群中的节点发现自己在超过timeout时间限制后仍然无法与集群中大多数节点通信,那么该节点将会停止接收客户端的查询等操作.
  • cluster-slave-validity-factor : 如果该值设置为0,从节点将会一直尝试故障转移主节点,而不管从节点与主节点之间的链路到底断开了多久,有没有超过cluster-node-timeout 的值的限制,如果该值是一个正数,那么该值乘以cluster-node-timeout的值得出来的时间就是一个节点断开的最大时间,如果该节点是从节点,那么主从节点之间的链路断开后,即使超过了该值,从节点也不会执行故障转移(这是因为从节点和主节点的链路断开,但是主节点和集群中的大部分节点链路是正常的).例如,如果cluster-node-timeout 的值为5000,即5秒,cluster-slave-validity-factor的值为10,那么从节点和主节点断开超过50秒后,从节点不被允许执行故障转移,这里需要注意的是,任何非0值都会导致没有从节点的主节点宕机后执行故障转移导致集群不可用,这种情况下只有当主节点重新加入集群后集群才会继续提供服务.
  • cluster-migration-barrier : 这是Redis集群特性“副本移动“(Replicas migration)的参数配置,该参数表明一个主节点最少的从节点数量,在副本移动的时候要保证原主节点至少有该参数指定的从节点数量的前提下才会将该主节点多余的从节点移动到其他没有从节点的主节点。
  • cluster-require-full-coverage : 默认是yes,如果哈希槽没有被任何节点负责处理,集群将会停止写入。如果设置为no,即使集群故障仍可以处理部分哈希槽数据,集群仍然可用。
  • cluster-allow-reads-when-down : 默认是no,当集群认为有节点出现故障时,该故障可能是因为网络分区导致该节点与集群隔离开,或者该节点无法得到集群大多数节点的认同时,此时该故障节点将会拒绝任何读写请求,这样的好处是将阻止客户端从该节点读取到不一致的数据。该参数也可以被配置为yes,即使该节点故障也允许读操作,这在应用要求优先进行读取操作但是可以阻止不一致性写入的情况下比较有用,当Redis集群仅有少量切片情况下且没有从节点执行故障转移时可以考虑使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值