小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【Redis21】Redis進階:主從復制

 硬核項目經(jīng)理 2023-05-15 發(fā)布于湖南

Redis進階:主從復制

對于大型企業(yè)來說,一臺 Redis 實例要保證可用性,往往會配置主從庫。這一點上其實和 MySQL 是一樣的,我們絕大部分的業(yè)務需求通常的情況都是讀多寫少。在這種情況下,合理的分攤讀庫請求,就可以大大加強請求的響應速度。對比 MySQL 來說,Redis 的主從復制簡單的沒朋友。

主從復制配置

對于我們測試學習來說,一般不會去建立多個虛擬機或者 Docker ,更不可能去買多臺真正的服務器來練習。大家一般都是多開幾個實例,只要端口號不重復就行了。因此,我們需要多建兩個配置文件,區(qū)分開端口號。

// vim redis_80.conf
include /usr/local/etc/redis.conf
port 6380
pidfile "/var/run/redis_6380.pid"
dbfilename "dump6380.rdb"

默認的 Redis 端口號是 6379 ,為了測試方便,我們就新建兩個文件,一個用 6380 ,一個用 6381 。配置文件可以直接 include 默認的那個主配置文件,然后覆蓋寫上新的端口號就可以了。另外需要注意的是,pidfile 和 dbfilename 也要換個名字,要不就會共用 6379 的。6381 的配置文件也是類似的,這里就不粘出來了。然后我們啟動 6380 和 6381 。

// 服務端 6380
redis-server redis_80.conf

// 服務端 6381
redis-server redis_81.conf

如果你不想在控制臺看到啟動情況,或者說想讓實例在后臺運行的話,可以再加上下面這個配置。

// 配置文件
daemonize yes

然后使用客戶端進入 6380 和 6381 ,直接運行 SLAVEOF <host> <port> 命令,其中 host 指的是主庫的地址,port 指的是主庫的端口號。

// 客戶端 6380
?  redis-cli -p 6380
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK

// 客戶端 6381
?  redis-cli -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK

好了,6380 和 6381 就是 6379 的兩臺從庫了。是不是很簡單,我們去驗證一下。

// 客戶端 6379
127.0.0.1:6379> INFO Replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=252,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=252,lag=1
………………

127.0.0.1:6379> role
1) "master"
2) (integer) 1313
3) 1) 1) "127.0.0.1"
      2) "6380"
      3) "1313"
   2) 1) "127.0.0.1"
      2) "6381"
      3) "1313"

在 6379 上,使用 INFO Replication 就可以看到當前的角色是 master ,有兩臺從庫,它們的狀態(tài)信息也都能看到。另外還有一個命令就是 role ,它也能看到當前的主從狀態(tài)信息。第一行是本機的角色,下面是從庫的情況。同樣的,在從庫上也能看到相關的信息。

// 客戶端 6380
127.0.0.1:6380> INFO Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_read_repl_offset:378
slave_repl_offset:378
slave_priority:100
slave_read_only:1
………………

127.0.0.1:6380> role
1) "slave"
2) "127.0.0.1"
3) (integer) 6379
4) "connected"
5) (integer) 1341

好了,現(xiàn)在試試看主從之間有沒有真正的實現(xiàn)復制吧。

// 客戶端 6379
?  redis-cli -p 6379
127.0.0.1:6379> set a 111
OK

// 客戶端 6380
?  redis-cli -p 6380
127.0.0.1:6380> get a
"111"

可以看到,我們在 6379 添加了一個 a 的數(shù)據(jù),然后到 6380 可以 GET 到這條數(shù)據(jù)。嗯,目前來看主從配置是完全沒問題啦。

要說明的是,SLAVEOF 命令也可以配置到配置文件中,這樣實例一啟動就直接會進行主從連接。

復制機制

當主庫和從庫建立起連接后,主庫會發(fā)送命令流來保持對從庫的更新,包括客戶端的寫入、key的過期等。如果從庫斷開連接,過一段時間又重新連接之后,會進行部分重同步,可能會丟失部分命令。如果無法進行部分重同步的話,從庫會請求進行全量同步,也就是主庫會把 rdb 整個發(fā)送給從庫。

整個同步復制的過程都是走的異步復制,具有低延遲和高性能的特點。從庫和從庫之間也可以建立主從關系,從而形成一個樹狀的同步結構,當最頂上的主庫掛了的時候,可以馬上選擇一臺擁有從庫的從庫來切換成主庫,從而保證服務提供的可用性。

持久化問題

如果想要高性能,我們其實可以這樣配置,那就是主庫不做持久化,而在從庫中選一臺出來做持久化。雖然這樣做可以獲取到很高的性能,但是,假如主庫掛了,那么當它重啟的時候,會是一個空的數(shù)據(jù)庫。這樣的空數(shù)據(jù)庫也會同步給從庫,從而導致所有數(shù)據(jù)全部被清空,這一點是需要注意的。特別是配置了一些自動重啟實例的工具的情況下,非常危險。

因此,還是更建議主從都開啟持久化,或者使用哨兵機制以及分布式的方式來進行部署,這兩塊我們后面的文章馬上就會學習到哦。

密碼

如果主庫有密碼,我們可以通過 masterauth <password> 這個命令或者直接在配置文件中寫上,來設置從庫連接到主庫之后使用的密碼。

REPLICAOF

SLAVEOF 命令已經(jīng)是過時的命令了,在 Redis5 之后,更推薦使用的是 REPLICAOF <masterip> <masterport> ,參數(shù)和使用方式與 SLAVEOF 是一樣的。在現(xiàn)在的版本中,默認的配置文件中也只能搜到 REPLICAOF ,搜不到 SLAVEOF ,但是這個命令還是可以正常使用的。大家將來應用的時候,如果版本是在 Redis5 及以上的話,還是盡量使用新的命令哦。

從庫對于過期 Key 的處理

Redis 的從庫不會主動清理過期的 Key ,這是為啥呢?因為要聽老大的嘛。當主庫的 Key 過期后,主庫會發(fā)送一個 DEL 給從庫,從而實現(xiàn)過期 Key 的刪除。

但是,主從多少會有延遲的嘛,所以從庫也有自己的一個邏輯時鐘用以報告不違反數(shù)據(jù)庫一致性的讀操作中存在的 Key 。也就是說,從庫雖然不會主動過期,但也會在自己的計時中標注當前這個 Key 是否已經(jīng)過期,只不過,它不會真的刪除這個 Key ,而是要等待主庫的命令到達。如果客戶端請求,它將返回一個空值。在 Redis3.2 之前的版本中,從庫沒有自己的邏輯時鐘,這是一個大問題,所以老版本的小伙伴一定要注意(這個現(xiàn)在應該很少了吧)。

因此,要注意主從庫,特別是不在一臺服務器上的主從庫之間的時鐘同步性。

另外一種情況就是沒有設置過期時間的,就是主庫主動刪除的 Key 。只要是有同步,那么必然就會有延遲,因此,盡量將主從實例的主機部署在同一個機房,盡量的減少同步延遲就是最重要的步驟了,這一塊不僅是 Redis ,任何牽涉到主從復制這種機制的應用都會有這個問題,可以考慮應用層面上的代碼解決方案,更深層次上就是整體架構設計方面的問題了。這一塊咱的水平不夠,也說不出個所以然來,更重要的是,沒經(jīng)歷過啊,中小型公司能將一臺 Redis 實例的極限性能能發(fā)揮出來的都少之又少,所以只能將來我們學習到相關架構實踐的時候再來說吧!

另外配置文件中的 repl-disable-tcp-nodelay 參數(shù)如果選擇 no 的話,可以降低主從延遲,但是會加大帶寬消耗,如果在一個機房是可以考慮關閉這個參數(shù)的,畢竟內網(wǎng)基本是不收費的,而且?guī)掃€大。

同步過程

第一臺主庫會有一個 replication ID ,這是一個隨機字符串,在 INFO 中可以看到。

127.0.0.1:6379> info replication
………………
master_replid:1cf72f79da111329945c43855616ca5cf4b43f1a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
………………

同時也有一個偏移量 offset 。

主庫將自己產生的復制流發(fā)送給從庫的時候,發(fā)送多少個字節(jié)的數(shù)據(jù),自身的偏移量就會增加多少,目的就是當有新的操作修改數(shù)據(jù)時,可以以此更新從庫的狀態(tài)。這個其實就和 MySQL 主從中的 binlog 日志一樣,在配置主庫的時候,我們也會記錄當前的一個偏移量,然后等待從庫同步到與主庫相同的狀態(tài)時,才開放主庫的寫操作。一般也會通過偏移量來確定主從之間是否產生延遲。

接著,從庫通過 PSYNC 命令發(fā)送請求并獲得 replication ID 和 offset ,開始比較自己的同步情況,然后進行數(shù)據(jù)同步。這一塊我們可以通過 SYNC 命令看到。

127.0.0.1:6380> SYNC
Entering replica output mode...  (press Ctrl-C to quit)
SYNC with master, discarding 14838 bytes of bulk transfer...
SYNC done. Logging commands from master.
"set","b","222"
"ping"

開啟 SYNC 命令之后,從庫會不停地發(fā)送 PING 命令,這時你可以在主庫上隨便進行一個操作,然后回到從庫,就可以看到 SYNC 也輸出了從主庫上獲得的命令信息。

只讀

默認情況下,Redis 中的從庫是只讀的,就像下面這樣。

// 客戶端 6380
127.0.0.1:6380> set a 123
(error) READONLY You can't write against a read only replica.

這是因為默認情況下,在配置文件中,有這樣一個配置 slave-read-only yes ,它的意思很明顯,就是從庫只能讀。我們可以修改配置文件,也可以動態(tài)修改它。

127.0.0.1:6380> config set slave-read-only no
OK
127.0.0.1:6380> set a 123
OK
127.0.0.1:6380> get a
"123"

// 客戶端 6379
?  ~ redis-cli -p 6379
127.0.0.1:6379> get a
"111"
127.0.0.1:6379> set a 456
OK

// 客戶端 6380
?  ~ redis-cli -p 6380
127.0.0.1:6380> get a
"456"

從上面的測試情況可以看出,將 slave-read-only 設置為 no 之后,從庫也可以寫數(shù)據(jù)了。但是主庫一旦修改了這條數(shù)據(jù),那么從庫還會跟著主庫變。

說實話,這一塊不要有太大別的想法,從庫做好自己的事就好了,要是從庫能夠任意修改,那么數(shù)據(jù)一致性就會出現(xiàn)大問題了。

故障切換

除了提供讀庫的分攤流量職責之外,主從復制還有一個好處就是可以快速地進行主從切換,從而提高整個 Redis 實例的可用性,也就是我們常說的 主備架構 。將從機或者多個從機的某一臺從機當做備份機,如果主機崩掉了,可以馬上用備份機頂上。今天我們先來看看怎么手動實現(xiàn)主備切換。

// 關閉6379
?  brew services stop redis
Stopping `redis`... (might take a while)
==> Successfully stopped `redis` (label: homebrew.mxcl.redis)

// 查看6380狀態(tài)
?  redis-cli -p 6380
127.0.0.1:6380> role
1) "slave"
2) "127.0.0.1"
3) (integer) 6379
4) "connect"
5) (integer) -1

// 6380服務端日志
48041:S 22 Jun 2022 09:58:32.532 * Connecting to MASTER 127.0.0.1:6379
48041:S 22 Jun 2022 09:58:32.532 * MASTER <-> REPLICA sync started
48041:S 22 Jun 2022 09:58:32.532 # Error condition on socket for SYNC: Connection refused

在上面的操作中,當我們關閉了 6379 ,也就是主庫之后,從庫的狀態(tài)中,connect 變成了 -1 ,同時,服務實例輸出的日志也出現(xiàn)了報錯信息,表示當前的連接不可用。接下來,我們就趕緊把 6380 升級成主庫吧。

// 6380
127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380> role
1) "master"
2) (integer) 2826
3) (empty array)

使用命令 SLAVEOF no one 就可以將當前的從庫轉回一臺默認的普通實例,這時默認它就是主庫,不過是一臺還沒有從庫的主庫而已。接下來,把 6381 轉換成 6380 的從庫。

// 6381
127.0.0.1:6381> slaveof 127.0.0.1 6380
OK
127.0.0.1:6381> role
1) "slave"
2) "127.0.0.1"
3) (integer) 6380
4) "connected"
5) (integer) 2826

這個就不多說了,當 6379 恢復之后,我們再讓 6379 成為 6380 的主庫就好了。

應用程序上呢?這個真沒辦法,我們需要去修改連接信息,讓程序去連接新的主庫,從庫的配置也要修改。是不是很麻煩?別急,下一篇我們就來學習自動切換的哨兵機制。

總結

今天的內容很簡單,因為確實 Redis 在主從配置這一塊非常方便。而且因為 Redis 本身就非常快,所以大部分情況下我們不需要像 MySQL 那樣在新開從庫的時候要等從庫同步很久才能使用。它也是可以邊提供寫入服務,邊進行從庫同步的,如果確實主庫的數(shù)據(jù)量非常大,需要進行全量同步從庫的話,可以在主庫使用 WAIT 命令進行鎖寫等待。

好了,下一篇我們就要學習激動人心的主從高可用功能:哨兵機制 。別掉隊哦,進階系列的內容不多了,但后面可是篇篇精彩。

參考文檔:

https:///docs/manual/replication/

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多