redis笔记08-redis集群

目录

【Redis集群简介】

【Redis Cluster集群】

具体实现过程:

Redis Cluster 是怎么解决高可用问题的?

Redis主从复制的注意点

Redis主从同步与故障切换有哪些坑?

数据同步:主从库如何实现数据一致?

【哨兵机制】

master挂了手动切换方法

使用sentinel监控主从服务器

相关问题


【Redis集群简介】

redis集群的作用:

  • 主从备份,防止主机宕机;
  • 读写分离,分担master的任务;
  • 任务分离,主从服务器分别负责备份工作与计算工作。

redis集群的实现方案列举:

1.官方cluster方案:

从redis 3.0版本开始支持redis-cluster集群,redis-cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他节点连接。官方推荐的方案是将node配置成主从结构,即一个master主节点,挂n个slave从节点。如果主节点失效,redis cluster会根据选举算法从slave节点中选择一个上升为master节点,整个集群继续对外提供服务。Redis Cluster 是通过分片 的方式,把数据分布到集群的多个节点上。

2.twemproxy代理方案:

Redis代理中间件twemproxy是一种利用中间件做分片的技术。客户端不直接访问redis服务器,而是通过twemproxy代理中间件间接访问。降低了客户端直连后端服务器的连接数量。twemproxy是一个单点,很容易对其造成很大的压力,所以通常会结合keepalived来实现twemproy的高可用。

3.哨兵模式Sentinel:

是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器以及这些主服务器下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

4.codis:

codis是一个分布式的Redis解决方案,对于上层的应用来说,连接codis proxy和连接原生的redis server没什么明显的区别,上层应用可以像使用单机的redis一样使用,codis底层会处理请求的转发,不停机的数据迁移等工作,所有后边的事情,对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的redis服务。

5.客户端分片:

分区的逻辑在客户端实现,由客户端自己选择请求到哪个节点。方案可参考一致性哈希,这种方案通常适用于用户对客户端的行为有完全控制能力的场景。

【综上分析】Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

【Redis Cluster集群】

◆ 无中心的结构,数据分散在各个节点上,并且保存了整个集群的状态,每个节点都和其它节点相连
◆ 官方规定最小需要6个节点, 3个主节点和3个从节点
◆ 各个节点是通过gossip协议交换数据的,数据分布采用哈希槽算法实现:crc16(key) % 16384。Redis 集群有 16384 个 哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

◆ Redis 集群目前无法做数据库选择,默认在 0 数据库。

redis笔记08-redis集群_第1张图片

把主节点上全部的数据都复制到从节点上。通过 replicaof(Redis 5.0 之前使用 slaveof)命令形成主库和从库的关系。如果某个分片的主节点宕机了,集群中的其他节点会选举出新的主节点。Redis Cluster 也支持读写分离,在从节点上读取数据。

redis笔记08-redis集群_第2张图片

左边的:星形,所有的slave都围着master

右边的:线性,后面的slave作为前面slave的slave。这样的好处是:master宕机后,可以直接切换到slave1

Redis主从复制的注意点:一个master可以有多个slave,一个slave只能有一个master。配置了主从复制之后,主机可读可写,但从机只能读不能写(可以通过修改redis.conf 中 slave-read-only 的值让从机也可写)。  

Redis主从同步与故障切换有哪些坑:主从库间的命令复制是异步进行的,因此有可能从库读到的是旧值。

解决办法1:保证硬件配置和网络连接稳定。

解决办法2:可以开发一个外部程序来监控主从库间的复制进度。

具体实现过程:

【第一步:修改配置文件】将 redis.conf 复制两份,分别为redis6380.conf 和 redis6381.conf。因为默认的端口是6379.

① 主服务器redis.conf 的修改:

master 禁掉rdb,打开aof

redis笔记08-redis集群_第3张图片

如果需要加密码(一般不建议设置密码,因为主从服务器是在内网),搜索“password”找到如下:

改为:(123456就是密码)

如果设置了密码,连接进去后就要密码:

redis笔记08-redis集群_第4张图片

② 6380从服务器的修改:

vim redis6380.conf: 6380slave 打开rdb,禁掉aof

修改如下,主要是针对端口的修改:

slave的一些设置:

去掉注释,改为 slaveof localhost 6379 #6380服务器作为6379服务器的slave。

作为6379的slave服务器,保持只读状态。

③ 6381从服务器修改:

vim redis6381.conf:6381slave 禁掉rdb,禁掉aof

redis笔记08-redis集群_第5张图片

【第二步:分别打开三台服务器】

【第三步:master写入数据,slave查看数据】

# 在主服务器6379写入数据

#新的终端连接6380 和 6381从服务器并查看

#由于设置了只读,所以在从服务器无法写入

#备注:如果主服务器设置了密码,那么从服务器就获取不到主服务器的key了。那么就需要在所有的从服务器上也加上密码,其实上面说了,内网之间其实是不需要密码的。找到如下:

改为:(123456是上面master主服务器设置的密码)

然后再试就可以在从服务器上获取到主服务器的数据了。

Redis Cluster 是怎么解决高可用问题的?

增加从节点,做主从复制。Redis Cluster 支持给每个分片增加 一个或多个从节点,把主节点上全部的数据都复制到从节点上。如果某个分片的主节点宕机了,集群中的 其他节点会选举出新的主节点,集群中的所有节点都会感知到,默认情况下,集群的读写请求都是由主节点负责的,从节点只是起一 个热备的作用。当然了,Redis Cluster 也支持读写分离,在从节点上读取数据。

Redis主从复制的注意点

  • 一个master可以有多个slave,一个slave只能有一个master,数据流是单向的, master到slave。
  • 当一份数据落在了多个不同节点上,Redis采用主备复制的方式来保证一致性。
  • 如果主机已经运行了一段时间了,并且了已经存储了一些数据了,此时从机连上来,那么从机会将主机上所有的数据进行备份,而不是从连接的那个时间点开始备份。  
  • 配置了主从复制之后,主机上可读可写,但是从机只能读取不能写入(可以通过修改redis.conf中 slave-read-only 的值让从机也可以执行写操作)。  
  • 在整个主从结构运行过程中,如果主机不幸挂掉,重启之后,他依然是主机,主从复制操作也能够继续进行。

Redis主从同步与故障切换有哪些坑?

问题:主从库间的命令复制是异步进行的,因此有可能从库读到的是旧值。

解决办法1:在硬件环境配置方面,我们要尽量保证主从库间的网络连接状况良好。例如,要避免把主从库部署在不同的机房,或者是避免把网络通信密集的应用(例如数据分析应 用)和 Redis 主从库部署在一起。

解决办法2:还可以开发一个外部程序来监控主从库间的复制进度。

redis笔记08-redis集群_第6张图片

数据同步:主从库如何实现数据一致?

Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。读操作:主库、从库都可以接收;  写操作:首先到主库执行,然后,主库将写操作同步给从库。

主从库间如何进行第一次同步? 当启动多个 Redis 实例的时候,它们相互之间就可以通过 replicaof(Redis 5.0 之前 使用 slaveof)命令形成主库和从库的关系,之后会按照三个阶段完成数据的第一次同步。

【哨兵机制】

如果主库挂了,就需要运行一个新主库,比如说把一个从库切换为主库,把它当成主库。这就要提到哨兵机制了。在 Redis 主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的这三个问题。

也可以说哨兵是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移,它是实现主从库自动切换的关键机制。哨兵其实就是一个运行在特殊模式下的 Redis 进程,主从库实例运行的同时,它也在运行。

哨兵主要负责:监控、选主(选择主库)和通知。通过 pub/sub 机制,哨兵之间可以组成集群。

  • 监控:周期性测给各个主从库发送PING命令,超时未响应则认为已经挂掉;
  • 选择主从:监控到原来的主库挂掉了,会按照一定规则选择新的主库;
  • 通知:哨兵把新主库的连接信息发给其他从库,让它们执行 replicaof 命令,和新主库建立连接,并进行数据复制。同时, 哨兵会把新主库的连接信息通知给客户端,让它们把请求操作发到新主库上。

redis笔记08-redis集群_第7张图片

特点:1、保证高可用;2、监控各个节点;3、自动故障迁移

缺点:主从模式,切换需要时间丢数据;没有解决 master 写的压力。

哨兵机制通常会采用多实例组成的集群模式进行部署,这也被称为哨兵集群。通过 pub/sub 机制,哨兵之间可以组成集群,同时哨兵又通过 INFO 命令,获得了从库连接信息,也能和从库建立连接,并进行监控了。哨兵就是一个运行在特定模式下的 Redis 实例,只不过它并不服务请求操作,只是完成监控、选主和通知的任务。

总结:支持哨兵集群的这些关键机制:

  • 基于 pub/sub 机制的哨兵集群组成过程;
  • 基于 INFO 命令的从库列表,这可以帮助哨兵和从库建立连接;
  • 基于哨兵自身的 pub/sub 功能,这实现了客户端和哨兵之间的事件通知。

【问题】如果想要应用程序不感知服务的中断,还需要哨兵或客户端再做些什么吗?
1. 一方面,客户端需要能缓存应用发送的写请求。只要不是同步写操作(Redis 应用场景一 般也没有同步写),写请求通常不会在应用程序的关键路径上,所以,客户端缓存写请求 后,给应用程序返回一个确认就行。
2. 另一方面,主从切换完成后,客户端要能和新主库重新建立连接,哨兵需要提供订阅频道,让客户端能够订阅到新主库的信息。同时,客户端也需要能主动和哨兵通信,询问新主库的信息。


master挂了手动切换方法

配置 redis.conf

redis笔记08-redis集群_第8张图片

复制redis.conf 为 redis6380.conf,在此基础上作如下修改

redis笔记08-redis集群_第9张图片

复制redis6380.conf 为 redis6381.conf,在此基础上作如下修改

redis笔记08-redis集群_第10张图片

同时启动三台服务器:

启动默认的6379客户端,使用 info replication 查看:

redis笔记08-redis集群_第11张图片

再来查看6380的info:

redis笔记08-redis集群_第12张图片

Config get 配置项

Config set 配置项 值 (特殊的选项,不允许用此命令设置,如slave-of, 需要用单独的slaveof命令来设置)

例如,查看6379的appendonly选项的值:

当前6379是master,6380和6381都是6379的slave。现在要做的事情就是假设6379挂了,让6380作为master,而6381变成6380的slave。

先对6379执行 shutdown命令:

再看6380的info(6381的也是一样的):

redis笔记08-redis集群_第13张图片

SLAVEOF 设为slave服务器

运行时更改master-slave,修改一台slave(设为A)为new master

① 命令该服务不做其他redis服务的slave,命令: slaveof no one

redis笔记08-redis集群_第14张图片

② 修改其readonly为no

redis笔记08-redis集群_第15张图片

其他的slave再指向new master A

① 命令该服务为new master A的slave,命令格式 slaveof IP port

redis笔记08-redis集群_第16张图片

以上是手动实现的过程。

使用sentinel监控主从服务器

redis笔记08-redis集群_第17张图片

sentinel监控配置

sentinel monitor def_master 127.0.0.1 6379 2
sentinel auth-pass def_master 012_345^678-90

# master被当前sentinel实例认定为“失效”的间隔时间
# 如果当前sentinel与master直接的通讯中,在指定时间内没有响应或者响应错误代码,那么
# 当前sentinel就认为master失效(SDOWN,“主观”失效)
#  
# 默认为30秒
sentinel down-after-milliseconds def_master 30000

# 当前sentinel实例是否允许实施“failover”(故障转移)
# no表示当前sentinel为“观察者”(只参与"投票".不参与实施failover),
# 全局中至少有一个为yes
sentinel can-failover def_master yes

# sentinel notification-script mymaster /var/redis/notify.sh

【命令操作开始】

复制redis安装包下的 sentinel.conf 到 redis运行目录下:

然后进行如下编辑:

redis笔记08-redis集群_第18张图片

接下来,启动三台服务器:

使用 ./bin/redis-server ./sentinel.conf --sentinel 启动sentinel

redis笔记08-redis集群_第19张图片

可以看到上面的终端一直处于运行状态。接下来在6379客户端执行 shutdown ,故意让master宕机:

再回到刚才的sentinel界面,稍等片刻,看到如下信息:

redis笔记08-redis集群_第20张图片

master 由6379转移到了(switch) 6381:

redis笔记08-redis集群_第21张图片

分别查看6381和6380的 info replication:

redis笔记08-redis集群_第22张图片

redis笔记08-redis集群_第23张图片

那么问题来了,为什么把6381指定为了新的master,而不是6380?因为这只是凑巧。

可以通过设置配置文件制定6380为新的master,设置如下:

vim redis6380.conf: 找到slave-priority 100 (243行) #这个的意思是从服务器的优先级,数字越小优先级越高。

于是修改6380的优先级为10,保存。

然后继续上面的,分别启动三台服务器和sentinel:

redis笔记08-redis集群_第24张图片

继续,让6379宕机,再看sentinel的显示,已经将6380作为新的master了。

redis笔记08-redis集群_第25张图片

【总结】

Sentinel不断与master通信,获取master的slave信息.

监听master与slave的状态

如果某slave失效,直接通知master去除该slave.

如果master失效,,是按照slave优先级(可配置), 选取1个slave做 new master,把其他slave--> new slave

问题: sentinel与master通信,如果某次因为master IO操作频繁导致超时,加入此时认为master失效是不合理的。

解决: sentnel允许多个实例看守1个master, 当N台(N可设置) sentinel都认为master失效,才正式失效.

Sentinel选项配置

port 26379 # 端口
sentinel monitor mymaster 127.0.0.1 6379 2 ,

当2个sentinel实例都认为master失效时,正式失效

sentinel down-after-milliseconds mymaster 30000 多少毫秒后连接不到master认为断开
sentinel can-failover mymaster yes #是否允许sentinel修改slave->master. 如为no,则只能监控,无权修改./
sentinel parallel-syncs mymaster 1 , 一次性修改几个slave指向新的new master.
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh ,# 在重新配置new master,new slave过程,可以触发的脚本

相关问题

【问题】切片集群:数据增多了,是该加内存还是加实例?

【答案】切片集群,也叫分片集群,就是指启动多个 Redis 实例组成一个集群,然后按照一定的规则,把收到的数据划分成多份,每一份用一个实例来保存。如果把 25GB 的数据平均分成 5 份(当然,也可以不做均分),使用 5 个实例来保存,每个实 例只需要保存 5GB 数据。

【问题】数据切片后,在多个实例之间如何分布?

【答案】从 redis 3.0 开始,官方提供了一个 名为 Redis Cluster 的方案,用于实现切片集群。Redis Cluster 方案中就规定了数据和实 例的对应规则。Redis Cluster 方案采用哈希槽(Hash Slot), 来处理数据和实例之间的映射关系。

【问题】客户端怎么确定想要访问的数据在哪个实例上?

【答案】Redis 实例会把自己的哈希槽信息发给和它相连接的其它实例,来完成哈希槽分配信 息的扩散。当实例之间相互连接后,每个实例就有所有哈希槽的映射关系了。

【问题】为什么主从库间的复制不使用 AOF?

1. RDB 文件是二进制文件,无论是要把 RDB 写入磁盘,还是要通过网络传输 RDB,IO 效率都比记录和传输 AOF 的高。

2. 在从库端进行恢复时,用 RDB 的恢复效率要高于用 AOF。

【问题】在主从切换过程中,客户端能否正常地进行请求操作呢?

【答案】主从集群一般是采用读写分离模式,当主库故障后,客户端仍然可以把读请求发送给从库,让从库服务。但是,对于写请求操作,客户端就无法执行了。

你可能感兴趣的:(Redis,redis,服务器,数据库,运维)