單機的redis幾乎不太可能說QPS超過10萬+,通常在幾萬。node
除非一些特殊狀況,好比你的機器性能特別好,配置特別高,物理機,維護作的特別好,並且你的總體的操做不是太複雜。面試
Redis經過主從架構,實現讀寫分離,主節點負責寫,並將數據同步給其餘從節點,從節點負責讀,從而實現高併發。redis
Redis高併發的同時,還須要容納大量的數據:一主多從,每一個實例都容納了完整的數據,好比redis主就10G的內存量,其實你就最對只能容納10g的數據量。若是你的緩存要容納的數據量很大,達到了幾十g,甚至幾百g,或者是幾t,那你就須要redis集羣,並且用redis集羣以後,能夠提供可能每秒幾十萬的讀寫併發。緩存
replication的核心機制安全
redis採用異步方式複製數據到slave節點,不過redis 2.8開始,slave node會週期性地確認本身每次複製的數據量
一個master node是能夠配置多個slave node的
slave node也能夠鏈接其餘的slave node
slave node作複製的時候,是不會block master node的正常工做的
slave node在作複製的時候,也不會block對本身的查詢操做,它會用舊的數據集來提供服務; 可是複製完成的時候,須要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了
slave node主要用來進行橫向擴容,作讀寫分離,擴容的slave node能夠提升讀的吞吐量
網絡
master持久化對於主從架構的安全保障的意義架構
若是採用了主從架構,那麼建議必須開啓master node的持久化!併發
不建議用slave node做爲master node的數據熱備,由於那樣的話,若是你關掉master的持久化,可能在master宕機重啓的時候數據是空的,而後可能一通過複製,salve node數據也丟了less
第二個,master的各類備份方案,要不要作,萬一說本地的全部文件丟失了; 從備份中挑選一份rdb去恢復master; 這樣才能確保master啓動的時候,是有數據的異步
master同步數據給slave的過程
當啓動一個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。
主從複製的斷點續傳
從redis 2.8開始,就支持主從複製的斷點續傳,若是主從複製過程當中,網絡鏈接斷掉了,那麼能夠接着上次複製的地方,繼續複製下去,而不是從頭開始複製一份
master node會在內存中常見一個backlog,master和slave都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。
若是master和slave網絡鏈接斷掉了,slave會讓master從上次的replica offset開始繼續複製
可是若是沒有找到對應的offset,那麼就會執行一次resynchronization
無磁盤化複製
master在內存中直接建立rdb,而後發送給slave,不會在本身本地落地磁盤了
repl-diskless-sync
repl-diskless-sync-delay,等待必定時長再開始複製,由於要等更多slave從新鏈接過來
過時key處理
slave不會過時key,只會等待master過時key。
若是master過時了一個key,或者經過LRU淘汰了一個key,那麼會模擬一條del命令發送給slave。
複製的完整流程
slave node啓動,僅僅保存master node的信息,包括master node的host和ip(redis.conf裏面的slaveof配置的),可是複製流程沒開始
slave node內部有個定時任務,每秒檢查是否有新的master node要鏈接和複製,若是發現,就跟master node創建socket網絡鏈接
slave node發送ping命令給master node
口令認證,若是master設置了requirepass,那麼salve node必須發送masterauth的口令過去進行認證
master node第一次執行全量複製,將全部數據發給slave node
master node後續持續將寫命令,異步複製給slave node
數據同步相關的核心機制
指的就是第一次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觸發增量複製
全量複製
master執行bgsave,在本地生成一份rdb快照文件
master node將rdb快照文件發送給salve node,若是rdb複製時間超過60秒(repl-timeout),那麼slave node就會認爲複製失敗,能夠適當調節大這個參數
對於千兆網卡的機器,通常每秒傳輸100MB,6G文件,極可能超過60s
master node在生成rdb時,會將全部新的寫命令緩存在內存中,在salve node保存了rdb以後,再將新的寫命令複製給salve node
client-output-buffer-limit slave 256MB 64MB 60,若是在複製期間,內存緩衝區持續消耗超過64MB,或者一次性超過256MB,那麼中止複製,複製失敗
slave node接收到rdb以後,清空本身的舊數據,而後從新加載rdb到本身的內存中,同時基於舊的數據版本對外提供服務
若是slave node開啓了AOF,那麼會當即執行BGREWRITEAOF,重寫AOF
增量複製
若是全量複製過程當中,master-slave網絡鏈接斷掉,那麼salve從新鏈接master時,會觸發增量複製
master直接從本身的backlog中獲取部分丟失的數據,發送給slave node,默認backlog就是1MB
msater就是根據slave發送的psync中的offset來從backlog中獲取數據的
heartbeat
主從節點互相都會發送heartbeat信息
master默認每隔10秒發送一次heartbeat,salve node每隔1秒發送一個heartbeat
異步複製
master每次接收到寫命令以後,如今內部寫入數據,而後異步發送給slave node
轉自:中華石杉Java工程師面試突擊