Redis replica
作用
-
读写分离
-
容灾恢复
-
数据备份
-
水平扩容支撑高并发
conf
redis.conf | description |
---|---|
replicaof | 主机ip port |
masterauth | 主机验证密码(redis-cli 登录密码 |
单机集群
Compose devOps
配置docker-compose快速部署服务
version: '1.0'
services:
redis6379:
image: redis
container_name: redis6379
ports:
- 6379:6379
restart: true
volumes:
- /storage/redis6379/conf/redis6379.conf:/usr/local/etc/redis/redis.conf \
- /storage/redis6379/data:/data \
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis6380:
image: redis
container_name: redis6380
ports:
- 6380:6380
restart: true
volumes:
- /storage/redis6380/conf/redis6380.conf:/usr/local/etc/redis/redis.conf \
- /storage/redis6380/data:/data \
command: ["redis-server","/usr/local/etc/redis/redis.conf"]
depends_on:
- redis6379
redis6380:
image: redis
container_name: redis6381
ports:
- 6381:6381
restart: true
volumes:
- /storage/redis6381/conf/redis6381.conf:/usr/local/etc/redis/redis.conf \
- /storage/redis6381/data:/data \
command: ["redis-server","/usr/local/etc/redis/redis.conf"]
depends_on:
- redis6379
集群关系
一主多从
级联传递
中间结点依然无写能力
slave command
# slave 结点执行命令动态绑定
slaveof master-ip master-port
# 临时密令,重启后主从关系消失
# 使结点独立
slaveof no one
基本概念
-
slave结点不可执行写入,报错
(error) READONLY You can't write against a read only replica.
-
slave结点启动后统一复制,随后跟随复制
-
master结点
shutdown
后,slave结点原地待命,数据正常查询,等待主机重新启动 -
master
restart
后,主从关系依然存在 -
中间结点无写功能
Details
-
登录
slave
从机时,指定端口docker exec -it redis6380 -p 6380
-
登录
redis-cli
后,通过info replication
查询配置信息
复制原理
-
slave启动,同步初请
slave 启动后不断重试发送
sync
命令slave首次全新连接master,一次性完全同步(全量复制)将被自动执行,slave自身原有数据将会被master数据覆盖清除
-
首次连接,全量复制
master结点收到
sync
命令后会在开始后台保存快照(RDB,主从复制触发rdb持久化),同时将所有接受到的用于修改数据集的命令缓存起来,master结点执行rdb持久化后,master将rdb snapshot 文件核所有缓存命令发送到slave,完成全量复制
# ${url} 表式服务器ip
1:M 02 Dec 2023 21:00:30.482 * Ready to accept connections tcp
# 接受请求
1:M 02 Dec 2023 21:00:30.594 * Replica ${url} asks for synchronization
1:M 02 Dec 2023 21:00:30.594 * Full resync requested by replica ${url}
1:M 02 Dec 2023 21:00:30.594 * Replication backlog created, my new replication IDs are '8c3b0bcfd52dafbd69d639c42512d41acaac4379' and '0000000000000000000000000000000000000000'
1:M 02 Dec 2023 21:00:30.594 * Delay next BGSAVE for diskless SYNC
1:M 02 Dec 2023 21:00:30.892 * Replica ${url} asks for synchronization
1:M 02 Dec 2023 21:00:30.892 * Full resync requested by replica ${url}
1:M 02 Dec 2023 21:00:30.892 * Delay next BGSAVE for diskless SYNC
# 执行bgsave
1:M 02 Dec 2023 21:00:35.395 * Starting BGSAVE for SYNC with target: replicas sockets
1:M 02 Dec 2023 21:00:35.395 * Background RDB transfer started by pid 20
20:C 02 Dec 2023 21:00:35.396 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
1:M 02 Dec 2023 21:00:35.396 * Diskless rdb transfer, done reading from pipe, 2 replicas still up.
1:M 02 Dec 2023 21:00:35.401 * Background RDB transfer terminated with success
1:M 02 Dec 2023 21:00:35.401 * Streamed RDB transfer with replica ${url}:6380 succeeded (socket). Waiting for REPLCONF ACK from replica to enable streaming
1:M 02 Dec 2023 21:00:35.401 * Synchronization with replica ${url}:6380 succeeded
1:M 02 Dec 2023 21:00:35.401 * Streamed RDB transfer with replica ${url}:6381 succeeded (socket). Waiting for REPLCONF ACK from replica to enable streaming
1:M 02 Dec 2023 21:00:35.401 * Synchronization with replica ${url}:6381 succeeded
#rdb 传输成功
1:M 04 Dec 2023 13:07:43.081 * 1 changes in 3600 seconds. Saving...
1:M 04 Dec 2023 13:07:43.081 * Background saving started by pid 46
46:C 04 Dec 2023 13:07:43.090 * DB saved on disk
-
心跳持续,保持通信
repl-ping-replica-period 10
,默认心跳时间10s -
进入平稳,增量复制
master继续将新的收集到的修改命令自动一次发送给slave,完成同步
-
从机下线,重连续传
master 会检查backlog中的offset,master和slave都会保存一个复制的offset和masterId,master只会将offset后的数据复制给slave
expired key
问题:Redis expires allow keys to have a limited time to live (TTL). Such a feature depends on the ability of an instance to count the time, however Redis replicas correctly replicate keys with expires, even when such keys are altered using Lua scripts.
解决如下:
- Replicas don’t expire keys, instead they wait for masters to expire the keys. When a master expires a key (or evict it because of LRU), it synthesizes a
DEL
command which is transmitted to all the replicas. - However because of master-driven expire, sometimes replicas may still have in memory keys that are already logically expired, since the master was not able to provide the
DEL
command in time. To deal with that the replica uses its logical clock to report that a key does not exist only for read operations that don’t violate the consistency of the data set (as new commands from the master will arrive). In this way replicas avoid reporting logically expired keys that are still existing. In practical terms, an HTML fragments cache that uses replicas to scale will avoid returning items that are already older than the desired time to live. - During Lua scripts executions no key expiries are performed. As a Lua script runs, conceptually the time in the master is frozen, so that a given key will either exist or not for all the time the script runs. This prevents keys expiring in the middle of a script, and is needed to send the same script to the replica in a way that is guaranteed to have the same effects in the data set.
问题
主从结构下,高并发时,master的写压力增大,且slave增多对性能消耗,如果master结点故障,slave结点陷入等待,此结构不满足需求,引入哨兵机制