java架构之路-(Redis专题)Redis的主从、哨兵和集群

  我们使用的 redis,单机的绝对做不到高可用的,万一单机的 redis 宕机了,就没有备用的了,我们可以采用集群的方式来保证我们的高可用操作。

主从架构

  

  大致就是这样的,一个主节点,两个从节点(一般两个就可以了)

主从工作原理

   如果你为 master 配置了一个 slave,不管这个 slave 是否是第一次连接上 Master,它都会发送一个 SYNC 命 令 (redis2.8 版本之前的命令) 给 master 请求复制数据。 master 收到 SYNC 命令后,会在后台进行数据持久化通过 bgsave 生成最新的 rdb 快照文件,持久化期间, master 会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以 后,master 会把这份 rdb 文件数据集发送给 slave,slave 会把接收到的数据进行持久化生成 rdb,然后再加载到内存中。然后 master 再将之前缓存在内存中的命令发送给 slave。 当 master 与 slave 之间的连接由于某些原因而断开时,slave 能够自动重连 Master,如果 master 收到了多 个 slave 并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送 给多个并发连接的 slave。 当 master 和 slave 断开重连后,一般都会对整份数据进行复制。但从 redis2.8 版本开始,master 和 slave 断开重连后支持部分复制。

  我们在上述文字中可以得出,我们的 master 得到了 SYNC 命令以后,还是会继续接收我们客户端的命令的,或者说,我们的 slave 第一次全量复制了,而第二次就不再需要全量复制了,那么就提到了我们的数据部分复制

数据部分复制

  从 2.8 版本开始,slave 与 master 能够在网络连接断开重连后只进行部分数据复制。 master 会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master 和它所有的 slave 都维护了复制的数据下标 offset 和 master 的进程 id,因此,当网络连接断开后,slave 会请求 master 继续进行未完成的复制,从所记录的数据下标开始。如果 master 进程 id 变化了,或者从节点数据下标 offset 太旧,已经不在 master 的缓存队列里了,那么将会进行一次全量数据的复制。

  那么我们实际搭建一下我们的 redis 主从架构。

1. 首先我们准备三台已经安装好 redis 的服务器,不会安装的小伙伴可以回到我以后的博客去看一下,超详细https://www.cnblogs.com/cxiaocai/p/11674716.html

2. 修改我们的主节点和从节点配置,将 protected-mode yes 修改为 no,大概在 88 行,将我们 bind 127.0.0.1 修改为 bind 0.0.0.0,启动一下我们的主节点,然后分别测试一下从节点的服务器是否可以连接我们的主节点(我怕你们防火墙开着),输入 $ redis-cli -h  主节点 IP   -p  主节点 redis 端口 。

[root@iZm5ec3zn3tzdvp7ttnnosZ redis-5.0.5]# ./src/redis-cli -h 47.104.129.103 -p 6379
47.104.129.103:6379> 

注意:我们需要保证主节点和从节点是可以互通的

3. 确保可以连接了,我们来配置从节点,我们全局搜索一下 replica-read-only 改为 replica-read-only yes(搜不到自己写上 replica-read-only yes)大概在 326 行,表示从节点只读不写。在 replica‐read‐only yes 上面设置 replicaof 47.104.129.103 6379。

# administrative / dangerous commands.
replicaof 47.104.129.103 6379
replica-read-only yes
# Replication SYNC strategy: disk or socket.

4. 启动从节点,在主节点写入,查看从节点是否得到数据。

 配置完成,over~!

哨兵架构

  其实我们的主从架构只保证了数据的一致性,但是还是解决不了我们的高可用,我们的 master 节点宕机了,我们的服务还是不可用的。没有 Zookeeper 的选举机制,我们来看看我们的哨兵架构。

哨兵就是保证我们的 master 不会宕机,当 master 宕机以后,他会主动选举出来一个节点作为我们的 master。


  sentinel 哨兵是特殊的 redis 服务,不提供读写服务,主要用来监控 redis 实例节点。 哨兵架构下 client 端第一次从哨兵找出 redis 的主节点,后续就直接访问 redis 的主节点,不会每次都通过 sentinel 代理访问 redis 的主节点,当 redis 的主节点发生变化,哨兵会第一时间感知到,并且将新的 redis 主节点通知给 client 端 (这里面 redis 的 client 端一般都实现了订阅功能,订阅 sentinel 发布的节点变动消息)

  配置起来也是很简单的,还是我们上一次的主从架构,然后加上我们的哨兵集群。

1. 准备好我们刚才搭建完成的主从架构

2. 准备三个以上的服务器(推荐奇数个服务器,有内部选举),安装我们的 Redis,需要服务器之间都相通,上面主从说过

3. 修改我们的 sentinel.conf 文件

daemonize yes #允许后台启动
sentinel monitor mymaster 192.168.0.60 6379 2 # 设置连接我们的 redis 主从 master 2 表示服务器的数目 /2 取整数 +1

4. 输入 src/redis‐sentinel sentinel.conf 启动我们的程序,这时我们的端口是 26379。注意:这里的启动不再是 src/redis‐server。

5. 输入 src/redis‐cli 进入客户端,输入 info,即可查看我们的 sentinel 信息。

  哨兵模式也就很简单的配置好了,是在主从的基础之上搭建的,我们之前的主从架构,当我们的 master 宕机以后,redis 也就算是宕机了,不会有任何选举机制,但是我们的哨兵会有一个选举机制,当我们的 master 宕机以后,我们的哨兵集群会主动选举一个 master,然后告知我们的客户端,哪个是新的 master。即使我们的曾经的 master 重新启动了,那也恢复不到主节点了,只能当做从节点(redis 集群会详细说这个选举)

Redis 集群架构

   我们的哨兵架构,几乎可以做到了我们的要实现的高可用,但是哨兵的选举还是需要时间的,而且中间会阻塞客户端的请求,假如我们的选举消耗了 1 秒(实际可能几秒,高则几十秒),就在这 1 秒的时候来了客户端的请求,那个请求也是不可用的,并且我们的读写的节点实际还是单节点的,这时我们有了更好的方案,我们的 Redis 集群架构,并且现在 Redis 的集群架构做的也很成熟了。

   也就是我们 Redis 的集群其实就是一个个小的主从结合在一起(官方建议小于 1000 个小主从),变成了我们的 Redis 集群,每个小主从也就是我们的 Redis 数据分片,每个小主从的数据存储是不一样的,内部是有一套他自己的运算规则的。我们还是先来看一下如何配置,上文提过的简单的我就直接过了啊。

  1. 准备 9 台服务器,保证互通,下载解压。

  2. 编辑我们的 redis.conf 文件

    (1)daemonize yes # 设置后台启动,大概在 136 行

    (2)cluster-enabled yes # 是否开启集群模式,大概在 832 行

    (3)cluster-config-file nodes‐8001.conf #集群节点信息文件,这里 800x 最好和 port 对应上,方便后期查找。大概在 840 行

    (4)cluster-node-timeout 5000 # 节点离线超时时间,5000 毫秒,大概在 846 行

    (5)bind 0.0.0.0 #去掉 bind 绑定访问 ip 信息,大概在 69 行

    (6)protected-mode no #关闭保护模式,大概在 88 行

    (7)appendonly yes # 打开 AOF,大概在 699 行

    (8)requirepass xiaocai #设置 redis 访问密码,大概在 507 行

    (9)masterauth xiaocai # 设置集群节点间访问密码,跟上面一致,大概在 293 行

  3. 配置完成全部启动./src/redis-server redis.conf 检查是否启动成 ps -ef|grep redis。我们会看到这样的信息

 这里显示 cluster,说到这我们只差最后一步了。

  4. 我们在任意服务器输入./src/redis-cli -a xiaocai --cluster create --cluster-replicas 2 172.31.179.185:6379 172.31.179.178:6379 172.31.179.184:6379 172.31.179.183:6379 172.31.179.180:6379 172.31.179.181:6379 172.31.179.182:6379 172.31.179.179:6379 172.31.179.177:6379 命令,意思是要组建我们的集群环境了,-a 后面是密码 xiaocai,--cluster-replicas 2 这个数字 2 表示我们每个主节点有几个从节点,一般来说前三个 IP 会设置为 master,输入之后会有确认信息。我们会看到这样的信息,我们输入 yes 继续

   静静等待一会(时间也不会太久,时间太久的,你去检查一下网络之间互通吗),当我们出现【ok】的画面也就是成功了。

    5. 我们随便找一个客户端输入./src/redis-cli -a xiaocai,进入我们的客户端,输入 cluster info,就可以查看到节点信息

 我们看到 cluster_known_nodes:9 就是我们一共拥有多少节点,cluster_size:3 就是我们拥有多少组主从架构。配置完成 ~!

扩展:输入 cluster nodes 还可以查看我们的节点关联信息。

  我们在刚才输入我们的 cluster info 时,我们看到了一个 16384,其实就是一个 Redis 集群的片区,我们在单节点来执行 set 命令时,并不一定会成功,你可以尝试不同的 key 试一下,这就是我们的 Redis 分片区的存储,当你的 key 属于那个片区下,就会存储到哪个小主从内,其余的并不需要重复存储。在输入 cluster nodes 时会返回我们的片区信息。片区是从 0 开始计算,最大到 16383 的。

  今天就说到这里吧,下次我们说下 java 代码来操作我们的 Redis。

 

最进弄了一个公众号,小菜技术,欢迎大家的加入