前言
本期原本计划是写些redis高可用架构选型,分析,及实战,发现篇幅过长,所以拆开来写了。这期先讲一些官方提供的高可用功能,主从,sentinel,以及redis cluster。
Redis-Replication
Redis 支持简单且易用的主从复制(master-slave replication)功能, 该功能可以让从服务器(slave server)成为主服务器(master server)的精确复制品。
以下是关于 Redis 复制功能的几个重要方面:
Redis 使用异步复制。 从 Redis 2.8 开始, 从服务器会以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度。
一个主服务器可以有多个从服务器。
不仅主服务器可以有从服务器, 从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个图状结构。
复制功能不会阻塞主服务器: 即使有一个或多个从服务器正在进行初次同步, 主服务器也可以继续处理命令请求。
复制功能也不会阻塞从服务器: 只要在 redis.conf 文件中进行了相应的设置, 即使从服务器正在进行初次同步, 服务器也可以使用旧版本的数据集来处理命令查询。
复制功能可以单纯地用于数据冗余(data redundancy), 也可以通过让多个从服务器处理只读命令请求来提升扩展性(scalability): 比如说, 繁重的 SORT 命令可以交给附属节点去运行。
可以通过复制功能来让主服务器免于执行持久化操作: 只要关闭主服务器的持久化功能, 然后由从服务器去执行持久化操作即可。
工作原理
① 无论是初次连接还是重新连接, 当建立一个从服务器时, 从服务器都将向主服务器发送一个SYNC
命令。
② 接到SYNC
命令的主服务器将开始执行BGSAVE
, 并在保存操作执行期间, 将所有新执行的写入命令都保存到一个缓冲区里面。
③ 当BGSAVE
执行完毕后, 主服务器将执行保存操作所得的 .rdb 文件发送给从服务器, 从服务器接收这个 .rdb 文件, 并将文件中的数据载入到内存中。
④ 之后主服务器会以 Redis 命令协议的格式, 将写命令缓冲区中积累的所有内容都发送给从服务器。
你可以通过telnet
命令来亲自验证这个同步过程: 首先连上一个正在处理命令请求的 Redis 服务器, 然后向它发送SYNC
命令, 过一阵子, 你将看到 telnet 会话(session)接收到服务器发来的大段数据(.rdb 文件), 之后还会看到, 所有在服务器执行过的写命令, 都会重新发送到telnet
会话来。
即使有多个从服务器同时向主服务器发送SYNC
, 主服务器也只需执行一次BGSAVE
命令, 就可以处理所有这些从服务器的同步请求。
注意:从服务器可以在主从服务器之间的连接断开时进行自动重连, 在 Redis 2.8 版本之前, 断线之后重连的从服务器总要执行一次完整重同步(full resynchronization)操作, 但是从 Redis 2.8 版本开始, 从服务器可以根据主服务器的情况来选择执行完整重同步还是部分重同步(partial resynchronization)。
配置
replication的配置非常简单,在之前的文章中也有讲过,这里就不细说了。
|
|
另外一种方法是调用 SLAVEOF 命令, 输入主服务器的 IP 和端口, 然后同步就会开始:
|
|
slave
从 Redis 2.6 开始, 从服务器默认为只读模式。
只读模式由 redis.conf
文件中的 slave-read-only
选项控制, 也可以通过 CONFIG SET
命令来开启或关闭这个模式。
只读从服务器会拒绝执行任何写命令, 所以不会出现因为操作失误而将数据不小心写入到了从服务器的情况。
即使从服务器是只读的, DEBUG 和 CONFIG 等管理式命令仍然是可以使用的, 所以我们还是不应该将服务器暴露给互联网或者任何不可信网络。 不过, 使用 redis.conf
中的命令改名选项, 我们可以通过禁止执行某些命令来提升只读从服务器的安全性。
你可能会感到好奇, 既然从服务器上的写数据会被重同步数据覆盖, 也可能在从服务器重启时丢失, 那么为什么要让一个从服务器变得可写呢?
原因是, 一些不重要的临时数据, 仍然是可以保存在从服务器上面的。 比如说, 客户端可以在从服务器上保存主服务器的可达性(reachability)信息, 从而实现故障转移(failover)策略。
注意:一般来说,常规业务,普通企业,redis这种内存型nosql是不存在IO瓶颈的,即便存在一般也是通过proxy构建集群,对数据进行分片来分担压力,所以向常规数据库样做读写分离是没有必要的。(这里说的是一般情况,具体场景具体分析)
sentinel
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
- 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
sentinel原理
在讲解 Redis 高可用方案之前,我们先来看看 Redis Sentinel 原理是怎么样的。
- Sentinel 集群通过给定的配置文件发现 master,启动时会监控 master。通过向 master 发送 info 信息获得该服务器下面的所有从服务器。
- Sentinel 集群通过命令连接向被监视的主从服务器发送 hello 信息 (每秒一次),该信息包括 Sentinel 本身的 IP、端口、id 等内容,以此来向其他 Sentinel 宣告自己的存在。
- Sentinel 集群通过订阅连接接收其他 Sentinel 发送的 hello 信息,以此来发现监视同一个主服务器的其他 Sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收 hello 信息的中介,Sentinel 之间不会创建订阅连接。
- Sentinel 集群使用 ping 命令来检测实例的状态,如果在指定的时间内(
down-after-milliseconds
)没有回复或则返回错误的回复,那么该实例被判为下线。 - 当
failover
主备切换被触发后,failover
并不会马上进行,还需要 Sentinel 中的大多数 Sentinel 授权后才可以进行failover
,即进行failover
的 Sentinel 会去获得指定 quorum 个的 Sentinel 的授权,成功后进入 ODOWN 状态。如在 5 个 Sentinel 中配置了 2 个 quorum,等到 2 个 Sentinel 认为 master 死了就执行 failover。 - Sentinel 向选为 master 的 slave 发送
SLAVEOF NO ONE
命令,选择 slave 的条件是 Sentinel 首先会根据 slaves 的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从 master 接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程 ID 较小的。 - Sentinel 被授权后,它将会获得宕掉的 master 的一份最新配置版本号 (
config-epoch
),当 failover 执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它 Sentinel,其它的 Sentinel 则更新对应 master 的配置。
1 到 3 是自动发现机制:
- 以 10 秒一次的频率,向被监视的 master 发送 info 命令,根据回复获取 master 当前信息。
- 以 1 秒一次的频率,向所有 redis 服务器、包含 Sentinel 在内发送 PING 命令,通过回复判断服务器是否在线。
- 以 2 秒一次的频率,通过向所有被监视的 master,slave 服务器发送当前 Sentinel master 信息的消息。
4 是检测机制,5 和 6 是failover 机制,7 是更新配置机制。
sentinel配置
Redis 源码中包含了一个名为 sentinel.conf 的默认配置文件。
运行一个 Sentinel 所需的配置如下所示:
|
|
注意:
sentinel client-reconfig-script
为sentinel指定故障触发脚本,多用于配合proxy使用,去同步修改proxy配置,屏蔽切换故障节点。
启动Sentinel
对于 redis-sentinel 程序, 你可以用以下命令来启动 Sentinel 系统:
|
|
对于 redis-server 程序, 你可以用以下命令来启动一个运行在 Sentinel 模式下的 Redis 服务器:
|
|
两种方法都可以启动一个 Sentinel 实例。
启动 Sentinel 实例必须指定相应的配置文件, 系统会使用配置文件来保存 Sentinel 的当前状态, 并在 Sentinel 重启时通过载入配置文件来进行状态还原。
有朋友反映前几篇文章篇幅过长,影响可读性,不应向PC端技术文章那样详细,因此我对后续文章开始逐步精简。
下一篇横向分析下redis cluster,twemproxy,codis等集群架.