Redis有哪些集群方案

65次阅读
没有评论

共计 10363 个字符,预计需要花费 26 分钟才能阅读完成。

Redis 有哪些集群方案,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

1. 基本原理

主从复制模式中包含一个主数据库实例(master)与一个或多个从数据库实例(slave),如下图

客户端可对主数据库进行读写操作,对从数据库进行读操作,主数据库写入的数据会实时自动同步给从数据库。

具体工作机制为:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

 slave 启动后,向 master 发送 SYNC 命令,master 接收到 SYNC 命令后通过 bgsave 保存快照(即上文所介绍的 RDB 持久化),并使用缓冲区记录保存快照这段时间内执行的写命令

 master 将保存的快照文件发送给 slave,并继续记录执行的写命令

 slave 接收到快照文件后,加载快照文件,载入数据

 master 快照发送完后开始向 slave 发送缓冲区的写命令,slave 接收命令并执行,完成复制初始化

  此后 master 每次执行一个写命令都会同步发送给 slave,保持 master 与 slave 之间数据的一致性

2. 部署示例

本示例基于 Redis 5.0.3 版。

redis.conf 的主要配置

### 网络相关 ### # bind 127.0.0.1 #  绑定监听的网卡 IP,注释掉或配置成 0.0.0.0 可使任意 IP 均可访问  protected-mode no #  关闭保护模式,使用密码访问  port 6379 #  设置监听端口,建议生产环境均使用自定义端口  timeout 30 #  客户端连接空闲多久后断开连接,单位秒,0 表示禁用  ### 通用配置### daemonize yes #  在后台运行  pidfile /var/run/redis_6379.pid # pid 进程文件名  logfile /usr/local/redis/logs/redis.log #  日志文件的位置  ###RDB 持久化配置### save 900 1 # 900s 内至少一次写操作则执行 bgsave 进行 RDB 持久化  save 300 10 save 60 10000 #  如果禁用 RDB 持久化,可在这里添加  save   rdbcompression yes # 是否对 RDB 文件进行压缩,建议设置为 no,以(磁盘)空间换(CPU)时间  dbfilename dump.rdb # RDB 文件名称  dir /usr/local/redis/datas # RDB 文件保存路径,AOF 文件也保存在这里  ###AOF 配置 ### appendonly yes #  默认值是 no,表示不使用 AOF 增量持久化的方式,使用 RDB 全量持久化的方式  appendfsync everysec #  可选值  always, everysec,no,建议设置为 everysec ### 设置密码### requirepass 123456 #  设置复杂一点的密码 

部署主从复制模式只需稍微调整 slave 的配置,在 redis.conf 中添加

replicaof 127.0.0.1 6379 # master 的 ip,port masterauth 123456 # master 的密码  replica-serve-stale-data no #  如果 slave 无法与 master 同步,设置成 slave 不可读,方便监控脚本发现问题 

本示例在单台服务器上配置 master 端口 6379,两个 slave 端口分别为 7001,7002,启动 master,再启动两个 slave

[root@dev-server-1 master-slave]# redis-server master.conf [root@dev-server-1 master-slave]# redis-server slave1.conf [root@dev-server-1 master-slave]# redis-server slave2.conf

进入 master 数据库,写入一个数据,再进入一个 slave 数据库,立即便可访问刚才写入 master 数据库的数据。如下所示

[root@dev-server-1 master-slave]# redis-cli 127.0.0.1:6379  auth 123456 OK 127.0.0.1:6379  set site blog.jboost.cn OK 127.0.0.1:6379  get site  blog.jboost.cn  127.0.0.1:6379  info replication # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=7001,state=online,offset=13364738,lag=1 slave1:ip=127.0.0.1,port=7002,state=online,offset=13364738,lag=0 ... 127.0.0.1:6379  exit [root@dev-server-1 master-slave]# redis-cli -p 7001 127.0.0.1:7001  auth 123456 OK 127.0.0.1:7001  get site  blog.jboost.cn

执行 info replication 命令可以查看连接该数据库的其它库的信息,如上可看到有两个 slave 连接到 master

3. 主从复制的优缺点

优点:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

 master 能自动将数据同步到 slave,可以进行读写分离,分担 master 的读压力

 master、slave 之间的同步是以非阻塞的方式进行的,同步期间,客户端仍然可以提交查询或更新请求

缺点:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  不具备自动容错与恢复功能,master 或 slave 的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端 IP 才能恢复

 master 宕机,如果宕机前数据没有同步完,则切换 IP 后会存在数据不一致的问题

  难以支持在线扩容,Redis 的容量受限于单机配置

Sentinel(哨兵)模式

1. 基本原理

哨兵模式基于主从复制模式,只是引入了哨兵来监控与自动处理故障。如图

哨兵顾名思义,就是来为 Redis 集群站哨的,一旦发现问题能做出相应的应对处理。其功能包括

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  监控 master、slave 是否正常运行

  当 master 出现故障时,能自动将一个 slave 转换为 master(大哥挂了,选一个小弟上位)

  多个哨兵可以监控同一个 Redis,哨兵之间也会自动监控

哨兵模式的具体工作机制:

在配置文件中通过 sentinel monitor 来定位 master 的 IP、端口,一个哨兵可以监控多个 master 数据库,只需要提供多个该配置项即可。哨兵启动后,会与要监控的 master 建立两条连接:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  一条连接用来订阅 master 的_sentinel_:hello 频道与获取其他监控该 master 的哨兵节点信息

  另一条连接定期向 master 发送 INFO 等命令获取 master 本身的信息

与 master 建立连接后,哨兵会执行三个操作:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  定期(一般 10s 一次,当 master 被标记为主观下线时,改为 1s 一次)向 master 和 slave 发送 INFO 命令

  定期向 master 和 slave 的_sentinel_:hello 频道发送自己的信息

  定期(1s 一次)向 master、slave 和其他哨兵发送 PING 命令

发送 INFO 命令可以获取当前数据库的相关信息从而实现新节点的自动发现。所以说哨兵只需要配置 master 数据库信息就可以自动发现其 slave 信息。获取到 slave 信息后,哨兵也会与 slave 建立两条连接执行监控。通过 INFO 命令,哨兵可以获取主从数据库的最新信息,并进行相应的操作,比如角色变更等。

接下来哨兵向主从数据库的 sentinel:hello 频道发送信息与同样监控这些数据库的哨兵共享自己的信息,发送内容为哨兵的 ip 端口、运行 id、配置版本、master 名字、master 的 ip 端口还有 master 的配置版本。这些信息有以下用处:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  其他哨兵可以通过该信息判断发送者是否是新发现的哨兵,如果是的话会创建一个到该哨兵的连接用于发送 PING 命令。

  其他哨兵通过该信息可以判断 master 的版本,如果该版本高于直接记录的版本,将会更新

  当实现了自动发现 slave 和其他哨兵节点后,哨兵就可以通过定期发送 PING 命令定时监控这些数据库和节点有没有停止服务。

如果被 PING 的数据库或者节点超时(通过 sentinel down-after-milliseconds master-name milliseconds 配置)未回复,哨兵认为其主观下线(sdown,s 就是 Subjectively mdash; mdash; 主观地)。如果下线的是 master,哨兵会向其它哨兵发送命令询问它们是否也认为该 master 主观下线,如果达到一定数目(即配置文件中的 quorum)投票,哨兵会认为该 master 已经客观下线(odown,o 就是 Objectively mdash; mdash; 客观地),并选举领头的哨兵节点对主从系统发起故障恢复。若没有足够的 sentinel 进程同意 master 下线,master 的客观下线状态会被移除,若 master 重新向 sentinel 进程发送的 PING 命令返回有效回复,master 的主观下线状态就会被移除

哨兵认为 master 客观下线后,故障恢复的操作需要由选举的领头哨兵来执行,选举采用 Raft 算法:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  发现 master 下线的哨兵节点(我们称他为 A)向每个哨兵发送命令,要求对方选自己为领头哨兵

  如果目标哨兵节点没有选过其他人,则会同意选举 A 为领头哨兵

  如果有超过一半的哨兵同意选举 A 为领头,则 A 当选

  如果有多个哨兵节点同时参选领头,此时有可能存在一轮投票无竞选者胜出,此时每个参选的节点等待一个随机时间后再次发起参选请求,进行下一轮投票竞选,直至选举出领头哨兵

选出领头哨兵后,领头者开始对系统进行故障恢复,从出现故障的 master 的从数据库中挑选一个来当选新的 master, 选择规则如下:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  所有在线的 slave 中选择优先级最高的,优先级可以通过 slave-priority 配置

  如果有多个最高优先级的 slave,则选取复制偏移量最大(即复制越完整)的当选

  如果以上条件都一样,选取 id 最小的 slave

挑选出需要继任的 slave 后,领头哨兵向该数据库发送命令使其升格为 master,然后再向其他 slave 发送命令接受新的 master,最后更新数据。将已经停止的旧的 master 更新为新的 master 的从数据库,使其恢复服务后以 slave 的身份继续运行。

2. 部署演示

本示例基于 Redis 5.0.3 版。

哨兵模式基于前文的主从复制模式。哨兵的配置文件为 sentinel.conf,在文件中添加

sentinel monitor mymaster 127.0.0.1 6379 1 # mymaster 定义一个 master 数据库的名称,后面是 master 的 ip, port,1 表示至少需要一个 Sentinel 进程同意才能将 master 判断为失效,如果不满足这个条件,则自动故障转移(failover)不会执行  sentinel auth-pass mymaster 123456 # master 的密码  sentinel down-after-milliseconds mymaster 5000 # 5s 未回复 PING,则认为 master 主观下线,默认为 30s sentinel parallel-syncs mymaster 2 #  指定在执行故障转移时,最多可以有多少个 slave 实例在同步新的 master 实例,在 slave 实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长  sentinel failover-timeout mymaster 300000 #  如果在该时间(ms)内未能完成故障转移操作,则认为故障转移失败,生产环境需要根据数据量设置该值 

一个哨兵可以监控多个 master 数据库,只需按上述配置添加多套

分别以 26379,36379,46379 端口启动三个 sentinel

[root@dev-server-1 sentinel]# redis-server sentinel1.conf --sentinel [root@dev-server-1 sentinel]# redis-server sentinel2.conf --sentinel [root@dev-server-1 sentinel]# redis-server sentinel3.conf --sentinel

也可以使用 redis-sentinel sentinel1.conf 命令启动。此时集群包含一个 master、两个 slave、三个 sentinel,如图,

我们来模拟 master 挂掉的场景,执行 kill -9 3017 将 master 进程干掉,进入 slave 中执行 info replication 查看,

[root@dev-server-1 sentinel]# redis-cli -p 7001 127.0.0.1:7001  auth 123456 OK 127.0.0.1:7001  info replication # Replication role:slave master_host:127.0.0.1 master_port:7002 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 #  省略  127.0.0.1:7001  exit [root@dev-server-1 sentinel]# redis-cli -p 7002 127.0.0.1:7002  auth 123456 OK 127.0.0.1:7002  info replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=7001,state=online,offset=13642721,lag=1 #  省略 

可以看到 slave 7002 已经成功上位晋升为 master(role:master),接收一个 slave 7001 的连接。此时查看 slave2.conf 配置文件,发现 replicaof 的配置已经被移除了,slave1.conf 的配置文件里 replicaof 127.0.0.1 6379 被改为 replicaof 127.0.0.1 7002。重新启动 master,也可以看到 master.conf 配置文件中添加了 replicaof 127.0.0.1 7002 的配置项,可见大哥(master)下位后,再出来混就只能当当小弟(slave)了,三十年河东三十年河西。

3. 哨兵模式的优缺点

优点:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  哨兵模式基于主从复制模式,所以主从复制模式有的优点,哨兵模式也有

  哨兵模式下,master 挂掉可以自动进行切换,系统可用性更高

缺点:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  同样也继承了主从模式难以在线扩容的缺点,Redis 的容量受限于单机配置

  需要额外的资源来启动 sentinel 进程,实现相对复杂一点,同时 slave 节点作为备份节点不提供服务

Cluster 模式

1. 基本原理

哨兵模式解决了主从复制不能自动故障转移,达不到高可用的问题,但还是存在难以在线扩容,Redis 容量受限于单机配置的问题。Cluster 模式实现了 Redis 的分布式存储,即每台节点存储不同的内容,来解决在线扩容的问题。如图

Cluster 采用无中心结构, 它的特点如下:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  所有的 redis 节点彼此互联 (PING-PONG 机制), 内部使用二进制协议优化传输速度和带宽

  节点的 fail 是通过集群中超过半数的节点检测失效时才生效

  客户端与 redis 节点直连, 不需要中间代理层. 客户端不需要连接集群所有节点, 连接集群中任何一个可用节点即可

Cluster 模式的具体工作机制:

    1.  在 Redis 的每个节点上,都有一个插槽(slot),取值范围为 0 -16383

    2.  当我们存取 key 的时候,Redis 会根据 CRC16 的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0 -16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作

    3.  为了保证高可用,Cluster 模式也引入主从复制模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点

    4.  当其它主节点 ping 一个主节点 A 时,如果半数以上的主节点与 A 通信超时,那么认为主节点 A 宕机了。如果主节点 A 和它的从节点都宕机了,那么该集群就无法再提供服务了

Cluster 模式集群节点最小配置 6 个节点 (3 主 3 从,因为需要半数以上),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。

2. 部署演示

本示例基于 Redis 5.0.3 版。

Cluster 模式的部署比较简单,首先在 redis.conf 中

port 7100 #  本示例 6 个节点端口分别为 7100,7200,7300,7400,7500,7600 daemonize yes # r 后台运行  pidfile /var/run/redis_7100.pid # pidfile 文件对应 7100,7200,7300,7400,7500,7600 cluster-enabled yes #  开启集群模式  masterauth passw0rd #  如果设置了密码,需要指定 master 密码  cluster-config-file nodes_7100.conf #  集群的配置文件,同样对应 7100,7200 等六个节点  cluster-node-timeout 15000 #  请求超时   默认 15 秒,可自行设置 

分别以端口 7100,7200,7300,7400,7500,7600 启动六个实例 (如果是每个服务器一个实例则配置可一样)

[root@dev-server-1 cluster]# redis-server redis_7100.conf [root@dev-server-1 cluster]# redis-server redis_7200.conf ...

然后通过命令将这个 6 个实例组成一个 3 主节点 3 从节点的集群,

redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7100 127.0.0.1:7200 127.0.0.1:7300 127.0.0.1:7400 127.0.0.1:7500 127.0.0.1:7600 -a passw0rd

执行结果如图

可以看到 7100,7200,7300 作为 3 个主节点,分配的 slot 分别为 0-5460,5461-10922,10923-16383,7600 作为 7100 的 slave,7500 作为 7300 的 slave,7400 作为 7200 的 slave。

我们连接 7100 设置一个值

[root@dev-server-1 cluster]# redis-cli -p 7100 -c -a passw0rd Warning: Using a password with  -a  or  -u  option on the command line interface may not be safe. 127.0.0.1:7100  set site blog.jboost.cn -  Redirected to slot [9421] located at 127.0.0.1:7200 OK 127.0.0.1:7200  get site  blog.jboost.cn  127.0.0.1:7200

注意添加 -c 参数表示以集群模式,否则报 (error) MOVED 9421 127.0.0.1:7200 错误,以 -a 参数指定密码,否则报 (error) NOAUTH Authentication required 错误。

从上面命令看到 key 为 site 算出的 slot 为 9421,落在 7200 节点上,所以有 Redirected to slot [9421] located at 127.0.0.1:7200,集群会自动进行跳转。因此客户端可以连接任何一个节点来进行数据的存取。

通过 cluster nodes 可查看集群的节点信息

127.0.0.1:7200  cluster nodes eb28aaf090ed1b6b05033335e3d90a202b422d6c 127.0.0.1:7500@17500 slave c1047de2a1b5d5fa4666d554376ca8960895a955 0 1584165266071 5 connected 4cc0463878ae00e5dcf0b36c4345182e021932bc 127.0.0.1:7400@17400 slave 5544aa5ff20f14c4c3665476de6e537d76316b4a 0 1584165267074 4 connected dbbb6420d64db22f35a9b6fa460b0878c172a2fb 127.0.0.1:7100@17100 master - 0 1584165266000 1 connected 0-5460 d4b434f5829e73e7e779147e905eea6247ffa5a2 127.0.0.1:7600@17600 slave dbbb6420d64db22f35a9b6fa460b0878c172a2fb 0 1584165265000 6 connected 5544aa5ff20f14c4c3665476de6e537d76316b4a 127.0.0.1:7200@17200 myself,master - 0 1584165267000 2 connected 5461-10922 c1047de2a1b5d5fa4666d554376ca8960895a955 127.0.0.1:7300@17300 master - 0 1584165268076 3 connected 10923-16383

我们将 7200 通过 kill -9 pid 杀死进程来验证集群的高可用,重新进入集群执行 cluster nodes 可以看到 7200 fail 了,但是 7400 成了 master,重新启动 7200,可以看到此时 7200 已经变成了 slave。

3. Cluster 模式的优缺点

优点:

    1.  无中心架构,数据按照 slot 分布在多个节点。

    2.  集群中的每个节点都是平等的关系,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

    3.  可线性扩展到 1000 多个节点,节点可动态添加或删除

    4.  能够实现自动故障转移,节点之间通过 gossip 协议交换状态信息,用投票机制完成 slave 到 master 的角色转换

缺点:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

  客户端实现复杂,驱动要求实现 Smart Client,缓存 slots mapping 信息并及时更新,提高了开发难度。目前仅 JedisCluster 相对成熟,异常处理还不完善,比如常见的“max redirect exception”

  节点会因为某些原因发生阻塞(阻塞时间大于 cluster-node-timeout)被判断下线,这种 failover 是没有必要的

  数据通过异步复制,不保证数据的强一致性

 slave 充当“冷备”,不能缓解读压力

  批量操作限制,目前只支持具有相同 slot 值的 key 执行批量操作,对 mset、mget、sunion 等操作支持不友好

 key 事务操作支持有线,只支持多 key 在同一节点的事务操作,多 key 分布不同节点时无法使用事务功能

  不支持多数据库空间,单机 redis 可以支持 16 个 db,集群模式下只能使用一个,即 db 0

Redis Cluster 模式不建议使用 pipeline 和 multi-keys 操作,减少 max redirect 产生的场景。

关于 Redis 有哪些集群方案问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-03发表,共计10363字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)