Redis主從架構、讀寫分離


1.redis replication的核心機制

(1).redis采用異步方式復制數據到slave節點,不過redis 2.8開始,slave node會周期性地確認自己每次復制的數據量 (2).一個master node是可以配置多個slave node的 (3).slave node也可以連接其他的slave node (4).slave node做復制的時候,是不會阻止 master node的正常工作的 (5).slave node在做復制的時候,也不會阻止對自己的查詢操作,它會用舊的數據集來提供服務; 但是復制完成的時候,需要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了 (6).slave node主要用來進行橫向擴容,做讀寫分離,擴容的slave node可以提高讀的吞吐量 

2.master持久化對於主從架構的安全保障的意義

如果采用了主從架構,那么建議必須開啟master node的持久化!不建議用slave node作為master node的數據熱備,因為那樣的話,如果你關掉master的持久化,可能在master宕機重啟的時候數據是空的,然后可能一經過復制,salve node數據也丟了 master一定要做備份方案,萬一本地的所有文件丟失了; 從備份中挑選一份rdb去恢復master; 這樣才能確保master啟動的時候,是有數據的。即使采用了高可用機制,slave node可以自動接管master node,但是也可能sentinal還沒有檢測到master failure,master node就自動重啟了,還是可能導致上面的所有slave node數據清空故障 

3.Redis主從架構的核心原理

當啟動一個slave node的時候,它會發送一個PSYNC命令給master node,如果這時候slave node重新連接master node,那么master node僅僅會復制給slave部分缺少的數據; 否則如果是slave node第一次連接master node,那么會觸發一次full resynchronization。 開始full resynchronization的時候,master會啟動一個后台線程,開始生成一份RDB快照文件,同時還會將從客戶端收到的所有寫命令緩存在內存中。RDB文件生成完畢之后,master會將這個RDB發送給slave,slave會先寫入本地磁盤,然后再從本地磁盤加載到內存中。然后master會將內存中緩存的寫命令異步的發送給slave,slave也會同步這些數據。 slave node如果跟master node有網絡故障,斷開了連接,會自動重連。master如果發現有多個slave node都來重新連接,僅僅會啟動一個rdb save操作,用一份數據服務所有slave node

4.主從復制的斷點續傳

從redis 2.8開始,就支持主從復制的斷點續傳,如果主從復制過程中,網絡連接斷掉了,那么可以接着上次復制的地方,繼續復制下去,而不是從頭開始復制一份。master node會在內存中創建一個backlog,master和slave都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。如果master和slave網絡連接斷掉了,slave會讓master從上次的replica offset開始繼續復制,但是如果沒有找到對應的offset,那么就會執行一次全量復制。 

5.無磁盤化復制(增量復制的策略)

slave node如果跟master node有網絡故障,斷開了連接,這時候又重新連接,master最近增加的數據可以通過無磁盤化的方式復制到slave。 master在內存中直接創建rdb,然后發送給slave,不會在自己本地落地磁盤了 repl-diskless-sync=yes repl-diskless-sync-delay 5,等待一定時長再開始復制,因為要等更多slave重新連接過來 

6.過期key處理

slave不會過期key,只會等待master過期key。如果master過期了一個key,或者通過LRU淘汰了一個key,那么會模擬一條del命令發送給slave。 

7.復制的完整流程

(1).slave node啟動,僅僅保存master node的信息,包括master node的host和ip(redis.conf里面的slaveof配置的),但是復制流程沒開始 (2).slave node內部有個定時任務,每秒檢查是否有新的master node要連接和復制,如果發現,就跟master node建立socket網絡連接 (3).slave node發送ping命令給master node (4).口令認證,如果master設置了requirepass,那么salve node必須發送masterauth的口令過去進行認證 (5).master node第一次執行全量復制,將所有數據發給slave node (6).master node后續持續將寫命令,異步復制給slave node 

8.數據同步相關的核心機制(指的就是第一次slave連接msater的時候,執行的全量復制,那個過程里面你的一些細節的機制)

(1).master和slave都會維護一個offset,master會在自身不斷累加offset,slave也會在自身不斷累加offset,slave每秒都會上報自己的offset給master,同時master也會保存每個slave的offset(這個倒不是說特定就用在全量復制的,主要是master和slave都要知道各自的數據的offset,才能知道互相之間的數據不一致的情況) (2).backlog master node有一個backlog,默認是1MB大小 master node給slave node復制數據時,也會將數據在backlog中同步寫一份 backlog主要是用來做全量復制中斷后的增量復制的 (3).master run id info server,可以看到master run id 如果根據host+ip定位master node,是不靠譜的,如果master node重啟或者數據出現了變化,那么slave node應該根據不同的run id區分,run id不同就做全量復制 如果需要不更改run id重啟redis,可以使用redis-cli debug reload命令 (4).psync 從節點使用psync從master node進行復制,psync runid offset master node會根據自身的情況返回響應信息,可能是FULLRESYNC runid offset觸發全量復制,可能是CONTINUE觸發增量復制 

9.全量復制

(1).master執行bgsave,在本地生成一份rdb快照文件 (2).master node將rdb快照文件發送給salve node,如果rdb復制時間超過60秒(repl-timeout),那么slave node就會認為復制失敗,可以適當調節大這個參數 (3).對於千兆網卡的機器,一般每秒傳輸100MB,6G文件,很可能超過60s (4).master node在生成rdb時,會將所有新的寫命令緩存在內存中,在salve node保存了rdb之后,再將新的寫命令復制給salve node (5).client-output-buffer-limit slave 256MB 64MB 60,如果在復制期間,內存緩沖區持續消耗超過64MB,或者一次性超過256MB,那么停止復制,復制失敗 (6).slave node接收到rdb之后,清空自己的舊數據,然后重新加載rdb到自己的內存中,salve none在接收的過程中仍然基於舊的數據版本對外提供服務 (7).如果slave node開啟了AOF,那么會立即執行BGREWRITEAOF,重寫AOF rdb生成、rdb通過網絡拷貝、slave舊數據的清理、slave aof rewrite,很耗費時間,如果復制的數據量在4G~6G之間,那么很可能全量復制時間消耗到1分半到2分鍾 

10.增量復制

(1).如果全量復制過程中,master-slave網絡連接斷掉,那么salve重新連接master時,會觸發增量復制 (2).master直接從自己的backlog中獲取部分丟失的數據,發送給slave node,默認backlog就是1MB (3).msater就是根據slave發送的psync中的offset來從backlog中獲取數據的 

11.heartbeat

主從節點互相都會發送heartbeat信息,master默認每隔10秒發送一次heartbeat,salve node每隔1秒發送一個heartbeat 

12.異步復制

master每次接收到寫命令之后,現在內部寫入數據,然后異步發送給slave node 

13.啟用復制,部署slave node

wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz tar -xzvf tcl8.6.1-src.tar.gz cd /usr/local/tcl8.6.1/unix/ ./configure make && make install 使用redis-3.2.8.tar.gz(截止2017年4月的最新穩定版) tar -zxvf redis-3.2.8.tar.gz cd redis-3.2.8 make && make test && make install (1).redis utils目錄下,有個redis_init_script腳本 (2).將redis_init_script腳本拷貝到linux的/etc/init.d目錄中,將redis_init_script重命名為redis_6379,6379是我們希望這個redis實例監聽的端口號 (3).修改redis_6379腳本的第6行的REDISPORT,設置為相同的端口號(默認就是6379) (4).創建兩個目錄:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件) (5).修改redis配置文件(默認在根目錄下,redis.conf),拷貝到/etc/redis目錄中,修改名稱為6379.conf (6).修改redis.conf中的部分配置為生產環境 daemonize yes 讓redis以daemon進程運行 pidfile /var/run/redis_6379.pid 設置redis的pid文件位置 port 6379 設置redis的監聽端口號 dir /var/redis/6379 設置持久化文件的存儲位置 (7).讓redis跟隨系統啟動自動啟動 在redis_6379腳本中,最上面,加入兩行注釋 # chkconfig: 2345 90 10 # description: Redis is a persistent key-value database chkconfig redis_6379 on 在slave node上配置:slaveof 192.168.1.1 6379,即可,也可以使用slaveof命令 

14.強制讀寫分離

基於主從復制架構,實現讀寫分離
redis slave node只讀,默認開啟,slave-read-only 開啟了只讀的redis slave node,會拒絕所有的寫操作,這樣可以強制搭建成讀寫分離的架構 

15.集群安全認證

master上啟用安全認證,requirepass master連接口令,masterauth 

16.讀寫分離架構的測試

先啟動主節點,eshop-cache01上的redis實例 再啟動從節點,eshop-cache02上的redis實例 如果redis slave node一直說沒法連接到主節點的6379的端口,在搭建生產環境的集群的時候,不要忘記修改一個配置(bind) bind 127.0.0.1 -> 本地的開發調試的模式,就只能127.0.0.1本地才能訪問到6379的端口 每個redis.conf中的bind 127.0.0.1 -> bind自己的ip地址 在每個節點上都: iptables -A INPUT -ptcp --dport 6379 -j ACCEPT redis-cli -h ipaddr info replication 

17.對redis讀寫分離架構進行壓測,單實例寫QPS+單實例讀QPS

 
你如果要對自己剛剛搭建好的redis做一個基准的壓測,測一下你的redis的性能和QPS(query per second)
redis自己提供的redis-benchmark壓測工具,是最快捷最方便的,當然啦,這個工具比較簡單,用一些簡單的操作和場景去壓測
redis-3.2.8/src ./redis-benchmark -h 192.168.31.187 -c <clients> Number of parallel connections (default 50) -n <requests> Total number of requests (default 100000) -d <size> Data size of SET/GET value in bytes (default 2) 根據你自己的高峰期的訪問量,在高峰期,瞬時最大用戶量會達到10萬+,-c 100000,-n 10000000,-d 50 1核1G,虛擬機 ====== PING_INLINE ====== 100000 requests completed in 1.28 seconds 50 parallel clients 3 bytes payload keep alive: 1 99.78% <= 1 milliseconds 99.93% <= 2 milliseconds 99.97% <= 3 milliseconds 100.00% <= 3 milliseconds 78308.54 requests per second


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM