本期原本计划是写些redis高可用架构选型,分析,及实战,发现篇幅过长,所以拆开来写了。这期先讲一些官方提供的高可用功能,主从,sentinel,以及redis cluster。
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 和端口, 然后同步就会开始:
|
|
从 Redis 2.6 开始, 从服务器默认为只读模式。
只读模式由 redis.conf
文件中的 slave-read-only
选项控制, 也可以通过 CONFIG SET
命令来开启或关闭这个模式。
只读从服务器会拒绝执行任何写命令, 所以不会出现因为操作失误而将数据不小心写入到了从服务器的情况。
即使从服务器是只读的, DEBUG 和 CONFIG 等管理式命令仍然是可以使用的, 所以我们还是不应该将服务器暴露给互联网或者任何不可信网络。 不过, 使用 redis.conf
中的命令改名选项, 我们可以通过禁止执行某些命令来提升只读从服务器的安全性。
你可能会感到好奇, 既然从服务器上的写数据会被重同步数据覆盖, 也可能在从服务器重启时丢失, 那么为什么要让一个从服务器变得可写呢?
原因是, 一些不重要的临时数据, 仍然是可以保存在从服务器上面的。 比如说, 客户端可以在从服务器上保存主服务器的可达性(reachability)信息, 从而实现故障转移(failover)策略。
注意:一般来说,常规业务,普通企业,redis这种内存型nosql是不存在IO瓶颈的,即便存在一般也是通过proxy构建集群,对数据进行分片来分担压力,所以向常规数据库样做读写分离是没有必要的。(这里说的是一般情况,具体场景具体分析)
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
在讲解 Redis 高可用方案之前,我们先来看看 Redis Sentinel 原理是怎么样的。
down-after-milliseconds
)没有回复或则返回错误的回复,那么该实例被判为下线。failover
主备切换被触发后,failover
并不会马上进行,还需要 Sentinel 中的大多数 Sentinel 授权后才可以进行failover
,即进行failover
的 Sentinel 会去获得指定 quorum 个的 Sentinel 的授权,成功后进入 ODOWN 状态。如在 5 个 Sentinel 中配置了 2 个 quorum,等到 2 个 Sentinel 认为 master 死了就执行 failover。SLAVEOF NO ONE
命令,选择 slave 的条件是 Sentinel 首先会根据 slaves 的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从 master 接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程 ID 较小的。config-epoch
),当 failover 执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它 Sentinel,其它的 Sentinel 则更新对应 master 的配置。1 到 3 是自动发现机制:
4 是检测机制,5 和 6 是failover 机制,7 是更新配置机制。
Redis 源码中包含了一个名为 sentinel.conf 的默认配置文件。
运行一个 Sentinel 所需的配置如下所示:
|
|
注意:
sentinel client-reconfig-script
为sentinel指定故障触发脚本,多用于配合proxy使用,去同步修改proxy配置,屏蔽切换故障节点。
对于 redis-sentinel 程序, 你可以用以下命令来启动 Sentinel 系统:
|
|
对于 redis-server 程序, 你可以用以下命令来启动一个运行在 Sentinel 模式下的 Redis 服务器:
|
|
两种方法都可以启动一个 Sentinel 实例。
启动 Sentinel 实例必须指定相应的配置文件, 系统会使用配置文件来保存 Sentinel 的当前状态, 并在 Sentinel 重启时通过载入配置文件来进行状态还原。
有朋友反映前几篇文章篇幅过长,影响可读性,不应向PC端技术文章那样详细,因此我对后续文章开始逐步精简。
下一篇横向分析下redis cluster,twemproxy,codis等集群架.