redis 主从
持久化的开启与主从集群是否生效无关系
Slave Server 同样是以非阻塞的方式完成数据同步. 在同步期间, 如果有客户端提交查询请求, Redis 则返回同步之前的数据(注意初次同步则会阻塞).
Replication 的工作原理:
如果 Master 和 Slave 之间的链接出现断连现象, Slave 可以自动重连 Master, 但是在连接成功之后, 一次完全同步将被自动执行.
缺点主节点挂了, 那么就只能提供读操作了.
应用示例:
这里我们假设 Master-Slave 已经建立.
- # 启动 master 服务器.
- [root@Stephen-PC redis]# redis-cli -p 6379
- redis 127.0.0.1:6379>
- #清空 Master 当前数据库中的所有 Keys.
- redis 127.0.0.1:6379> flushdb
- OK
- #在 Master 中创建新的 Keys 作为测试数据.
- redis 127.0.0.1:6379> set mykey hello
- OK
- redis 127.0.0.1:6379> set mykey2 world
- OK
- #查看 Master 中存在哪些 Keys.
- redis 127.0.0.1:6379> keys *
- 1) "mykey"
- 2) "mykey2"
- #启动 slave 服务器.
- [root@Stephen-PC redis]# redis-cli -p 6380
- #查看 Slave 中的 Keys 是否和 Master 中一致, 从结果看, 他们是相等的.
- redis 127.0.0.1:6380> keys *
- 1) "mykey"
- 2) "mykey2"
- #在 Master 中删除其中一个测试 Key, 并查看删除后的结果.
- redis 127.0.0.1:6379> del mykey2
- (integer) 1
- redis 127.0.0.1:6379> keys *
- 1) "mykey"
- #在 Slave 中查看是否 mykey2 也已经在 Slave 中被删除.
- redis 127.0.0.1:6380> keys *
- 1) "mykey"
哨兵模式
哨兵模式就是监控 redis 系统的运行情况, 主要功能有两点:
1, 监控主数据库和从数据库是否正常运行.
2, 主数据库出现故障时, 可以自动将从数据库转换为主数据库, 实现自动切换.
实现步骤
在其中一台从服务器 (比如 192.168.19.131) 中配置 sentinel.conf
- vi sentinel.conf
- sentinel monitor name(监控的主从集群的名称) 192.168.19.131 8089 1 #名称, ip, 端口(主从集群中 master 的地址), 投票选举次数
- sentinel down-after-milliseconds name 5000 #默认 1s 检测一次, 这里配置超时 5000 毫秒为宕机
sentinel failover-timeout name 900000
sentinel parallel-syncs name 2
sentinel can-fallover name yes
port 26379 #哨兵默认的端口
启动哨兵
/user/intsmaze/redis/bin/redis-server /user/intsmaze/redis/etc/sentinel.conf --sentinel &
查看哨兵相关信息
/user/intsmaze/redis/bin/redis-cli -h 192.168.19.131 -p 26379 Info sentinell
关闭主服务器查看集群信息
/user/intsmaze/redis/bin/redis-cli -h 192.168.19.131 -p 8089 shutdonwn
缺点: 主节点宕机了, 再切换节点时, 中间有几秒无法提供服务, 这几秒是用来切换的, 且是无法解决的. 这个时候只能在 java 代码中对 redis 的操作进行异常捕获, 如果发现是宕机异常, 则在 catch 中睡眠一秒, 在重试几次即可.
或者使用两个哨兵集群进行解决, 每个集群一个主, 几个从. 使用 keepalive 进行漂移, 如果某个主宕机了, 则 keepalive 则将 ip 飘到另一个主节点上. 不需要等待从节点变为主节点.
Redis Sentinel 是一个分布式系统, 可以部署多个 Sentinel 实例来监控同一组 Redis 实例, 它们通过 Gossip 协议来确定一个主实例宕机, 通过 Agreement 协议来执行故障恢复和配置变更, 一般在生产环境中部署多个实例来提高系统可用性, 只要有一个 Sentinel 实例运行正常, 就能保证被监控的 Redis 实例运行正常(类似 Zookeeper, 通过多个 Zookeeper 来提高系统可用性);
redis 的主从读写
redis 的主从读写, redis 自己是无法做到的, 即我们要在 java 客户端通过代码指定写操作请求 master, 读操作请求 slave.
jedis 提供的连接池不支持主从读写的, 只支持哨兵模式. 就是连接池地址是哨兵, 然后所有的读写请求都是走向 master, 只是做到了当主节点宕机, 从升级为主后, jedis 的连接池会自动更改当前 master 的地址.
HA 的关键在于避免单点故障及故障恢复
在 Redis Cluster 未发布之前, Redis 一般以主 / 从方式部署(这里讨论的应用从实例主要用于备份, 主实例提供读写, 有不少应用是读写分离的, 读写操作需要取不同的 Redis 实例, 该方案也可用于此种应用, 原理都是相通的, 区别在于数据操作层如何封装), 该方式要实现 HA 主要有如下几种方案:
1,keepalived: 通过 keepalived 的虚拟 IP, 提供主从的统一访问, 在主出现问题时, 通过 keepalived 运行脚本将从提升为主, 待主恢复后先同步后自动变为主, 该方案的好处是主从切换后, 应用程序不需要知道(因为访问的虚拟 IP 不变), 坏处是引入 keepalived 增加部署复杂性;
2,zookeeper: 通过 zookeeper 来监控主从实例, 维护最新有效的 IP, 应用通过 zookeeper 取得 IP, 对 Redis 进行访问;
3,sentinel: 通过 Sentinel 监控主从实例, 自动进行故障恢复, 该方案有个缺陷: 因为主从实例地址 (IP&PORT) 是不同的, 当故障发生进行主从切换后, 应用程序无法知道新地址, 故在 Jedis2.2.2 中新增了对 Sentinel 的支持, 应用通过 redis.clients.jedis.JedisSentinelPool.getResource()取得的 Jedis 实例会及时更新到新的主实例地址.
笔者所在的公司先使用了方案 1 一段时间后, 发现 keepalived 在有些情况下会导致数据丢失, keepalived 通过 shell 脚本进行主从切换, 配置复杂, 而且 keepalived 成为新的单点, 后来选用了方案 3, 使用 Redis 官方解决方案;(方案 2 需要编写大量的监控代码, 没有方案 3 简便, 网上有人使用方案 2 读者可自行查看)
原文和作者一起讨论: http://www.cnblogs.com/intsmaze/p/6819091.html
来源: https://www.cnblogs.com/intsmaze/p/6819091.html