Redis 单机的问题
- 单点故障(用主备解决,AKF 的 X 轴)
- 容量有限(用分片解决,还可以分实例,AKF 的 Z 轴)
- 压力:大的数据量、QPS 等等造成的问题。
AKF:
- X 轴:主从或主备,冗余多个相同的库。
- Y 轴:按业务逻辑分库。
- Z 轴:分片
![](https://img.haomeiwen.com/i3491218/d58a3deaca3b80f9.png)
Redis 默认工作在弱一致性,也可以支持强一致性。
Redis 的主从同步
使用主从会有一个大问题:如何保持数据一致性(同步)。
![](https://img.haomeiwen.com/i3491218/7e6ccc8c99077be4.png)
Redis 没用最终一致性。但可以加一个相当可靠、快速的中间件(比如 Kafka)来实现。它将数据暂存在 Kafka 中,要保证只要数据到 Kafka 最终(只要子结点可用)就一定会同步到子结点。
![](https://img.haomeiwen.com/i3491218/b0799520ad48e7b2.jpg)
高可用
当集群中 主 挂了后,需要仍然不影响对外提供服务。这就是对 主 做高可用,要实现 自动故障转移。由于只要是一个程序也会有单点故障问题,所以这个程序也需要是个 集群。
![](https://img.haomeiwen.com/i3491218/ef633ba92e6be2bc.jpg)
推导:当使用监控后,又有问题,
- 强一致性,监控者所有都认为它存活,则认为存活。这个时候会破坏可用性。
- 一部分认为存活,则认为存活。那一部分是多少呢?
- 一部分认为存活,一部分认为不存活,则产生了 脑裂。(但这不一定是坏事,可以设定 分区容忍性)
- 如果这两部分监控的数目相等,则无法选出正确的选择,所以选举一定要 过半。
- 由于过半中只允许少于一半的服务宕机,所以奇数台比偶数台少一台,更节省成本,所以集群最好是 奇数台。
奇数台节省成本的逻辑:
当有 3 台时,过半是 2,最多只允许一台服务宕机;(需要 2 台的势力范围)
当有 4 台时,过半是 3,最多也是只允许只有一台服务宕机;
所以 3 台和 4 台 承担的宕机风险的个数 一样,但成本不一样,用 3 更节省成本
并且用得越多,有一台宕机的风险也变大。
这就是 CAP 原则。
- Consistency:一致性
- Availability:可用性
- Partition tolerance:分区容错性
CAP 中,C 和 A 是互斥的,即满足了 C 就一定会破坏 A。
官网摘抄:
Replication(主从复制)
“Redis使用默认的异步复制,其特点是低延迟和高性能”
“master 与 slave 连接正常时,master 会发送一连串的命令流来保持对 slave 的更新”;
“因为网络问题、或者是主从意识到连接超时, slave 重新连接上 master 并会尝试进行 部分重同步”;
“当无法进行部分重同步时, slave 会请求进行 全量重同步”。
命令
-
slaveof host port
(5.0 之后命令是replicaof
)或在配置文件中设置。
起来之后 master 的日志描述说明了它执行的过程:
- Starting BGSAVE on disk
- Sync with replica xxx
slave 的日志描述说明了它的执行过程(第一次是 salve):
- Connecting to master xxx
- Trying partial sync ...
- Full resync from master
- Flushing old data (删除了自己的旧数据)
- Loading DB in memory (加载 master 的 RDB)
问:与 slave 传数据时一定要落 RDB 吗?
答:不一定。 repl-diskless-sync
当为 no 时是通过落 RDB 再经过网络传输 RDB 来同步的。当为 yes 时直接通过网络传输 RDB 到 slave(不再落成文件/磁盘)。
问:slave 在与 master 建立连接要成为 slave 的过程中,旧的数据还能不能访问?
slave 还没收到 master 的数据时,replica-serve-sale-data
当为 yes 时,可以支持; 为 false 时过程中不能访问。
但注意的是,当 slave 收到 master 的数据之后,会执行一次 flush data 操作,这之后旧的数据就不存在了。
问:slave 就只能支持查询了吗?还能支持写操作吗?
replica-read-only
为 yes 时只支持查询,为 no 时支持写入。(之后的没讲)
问:如何趋近于强一致性?
min-replicas-to-write 3
、min-replicas-max-lag 10
,是最少 3 个 slave 与 master 的延迟小于 10 秒,则 master 可以进行写。否则,master 不能接受写操作。
主挂了后
人手动操作的方式:
- slave 中执行
slaveof no one
可以将自己不再追随前 master - 其他 slave 中执行
slaveof xxx xxx
更换掉追随者
自动的方式,就是 哨兵模式
哨兵模式(Sentinel)
哨兵模式 可以自动来维护主从问题。它执行下面三个任务:
- 监控。检查 主 与 从 的动作状态。
- 提醒。可以通过 API 向管理员发通知。
- 自动故障转移。当 master 挂了后,选出新的 master,并和其他 slave 建立连接。
启动方式
两种
-
redis-sentinel
服务程序 redis-server /path/to/config --sentinel
配置文件
port xxx // 哨兵工作在哪个端口
sentinel monitor mymaster 127.0.0.1 6379 2 // 监控的谁(名字随意, 用于分组, 关键是host port),及投票势力范围(2)
sentinel down-after-milliseconds mymaster 60000 // 60000ms 没响应(Ping) Sentinel 就认为服务器已经断线
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1 // 故障转移时,最多多少个从服务器同步(越多越快)
// 另一个哨兵
sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5
哨兵启动后自动识别到 slave 和其他哨兵
注意:
- 只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行。
哨兵内部实现
- 用的 发布/订阅 功能
- 哨兵会自动改配置文件
哨兵用了发布订阅
可以用 PSUBSCRIBE <parttern>
可以查到 __sentinel__:hello
这个 channel 看到 哨兵 们在互相通话。
这在分布式中只是解决了单点故障的问题,所以下节课讲解决 redis 容量有限 的问题。容量问题解决的实现:
- 不同业务访问不同实例(但某一项业务容量需求太大就搞不定了)
- 分片方式 (Cluster 模式),通过 16384 个槽位,落在 N 个节点上,让数据分成 N 份,存在集群之上。
网友评论