1. 程式人生 > 實用技巧 >redis 主從複製

redis 主從複製

一,redis主從複製原理

1、主從複製過程大體可以分為3個階段
1.連線建立階段(即準備階段)
2.資料同步階段
3.命令傳播階段

2、在從節點執行 slaveof 命令後,複製過程便開始按下面的流程運作
1.儲存主節點資訊:配置slaveof之後會在從節點儲存主節點的資訊。
2.主從建立socket連線:定時發現主節點以及嘗試建立連線。
3.傳送ping命令:從節點定時傳送ping給主節點,主節點返回PONG。若主節點沒有返回PONG或因阻塞無法響應導致超時,則主從斷開,在下次定時任務時會從新ping主節點。
4.許可權驗證:若主節點開啟了ACL或配置了requirepass引數,則從節點需要配置masteruser和masterauth引數才能保證主從正常連線。
5.同步資料集:首次連線,全量同步。
6.命令持續複製:全量同步完成後,保持增量同步。

3、當節點被當做從節點的時候,需要注意!!
當節點被當做從節點的時候,需要將從節點設定為只讀,這樣做的目的是保證叢集的資料一致性。
主從複製原理圖

二,主從複製作用

1.資料冗餘:主從複製實現了資料的熱備份,是持久化之外的一種資料冗餘方式。
2.故障恢復:當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗餘。
3.負載均衡:在主從複製的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務,分擔伺服器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis伺服器的併發量。
4.讀寫分離:主庫寫、從庫讀,讀寫分離不僅可以提高伺服器的負載能力,同時可根據需求的變化,改變從庫的數量。
高可用基石:除了上述作用以外,主從複製還是哨兵和叢集能夠實施的基礎。

2.1 主從部分複製

當master和slave斷開連線時,master會將期間所做的操作記錄到複製快取區當中(可以看成是一個佇列,其大小預設1M)。待slave重連後,slave會向master傳送psync命令並傳入offset和runId,這時候,如果master發現slave傳輸的偏移量的值,在快取區佇列範圍中,就會將從offset開始到佇列結束的資料傳給slave,從而達到同步,降低了使用全量複製的開銷。

2.2 全量複製的開銷
1.bgsave的開銷,每次bgsave需要fork子程序,對記憶體和CPU的開銷很大
2.RDB檔案網路傳輸的時間(網路頻寬)
3.從節點清空資料的時間
4.從節點載入RDB的時間
5.可能的AOF重寫時間(如果我們的從節點開啟了AOF,則載入完RDB後會對AOF進行一個重寫,保證AOF是最新的

三,部署主從複製

1.1 環境準備
角色 主機 IP埠
主庫 redis01 172.16.1.81:6379
從庫 redis02 172.16.1.82:6379
從庫 redis03 172.16.1.83:6379

1.2 配置



# 81 redis配置
[root@redis01 ~]# egrep -v '^#|^$' /usr/local/redis/conf/redis.conf 
bind 127.0.0.1 172.16.1.81
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "/usr/local/redis/conf/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir "/usr/local/redis/data"
masterauth 123
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass 123
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes

# 82 配置
[root@redis02]# egrep -v '^#|^$' /usr/local/redis/conf/redis.conf
bind 127.0.0.1 172.16.1.82
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "/usr/local/redis/conf/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir "/usr/local/redis/data"
masterauth 123
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass 123
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly yes
appendfilename "appendonly.aof"
appendfsync always
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes


# 83 配置
[root@redis03 /usr/local/redis]# egrep -v '^#|^$' /usr/local/redis/conf/redis.conf
bind 127.0.0.1 172.16.1.83
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "/usr/local/redis/conf/redis/log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir "/usr/local/redis/data"
masterauth 123
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass 123
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes

四,啟動檢視主從複製

# 啟動每臺redis
[root@redis01 /usr/local/redis/conf]# ../bin/redis-server redis.conf
[root@redis02 /usr/local/redis/conf]# ../bin/redis-server redis.conf
[root@redis03 /usr/local/redis/conf]# ../bin/redis-server redis.conf 

# 開啟主從配置以81為主庫
[root@redis02 /usr/local/redis/conf]# ../bin/redis-cli 
127.0.0.1:6379> auth 123
OK
127.0.0.1:6379> SLAVEOF 172.16.1.81 6379
OK

[root@redis03 /usr/local/redis/conf]# ../bin/redis-cli 
127.0.0.1:6379> auth 123
OK
127.0.0.1:6379> SLAVEOF 172.16.1.81 6379
OK

# 81檢視主從狀態
[root@redis01 /usr/local/redis/conf]# ../bin/redis-cli 
127.0.0.1:6379> auth 123
OK
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.82,port=6379,state=online,offset=224,lag=1
slave1:ip=172.16.1.83,port=6379,state=online,offset=224,lag=1
master_replid:36be025a09e8ef0983dbc69dd69b697f465cc868
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:224

五,主從複製存在的問題

1.手動故障轉移
2.寫能力和儲存能力受限