Redis基本原理


1、redis數據備份原理,RDB和AOF。

RDB:redis基於當前自身的所有數據所生成的數據快照,純粹的數據,若redis從rdb啟動,可直接加載使用。
AOF:類似redis日志文件,aof文件內部是redis收到的寫命令,若redis從aof啟動,需要先讀aof文件,然后執行里面的命令,生產數據。
當觸發生成rdb時,redis會開啟后台線程,生成一份rdb,觸發條件可以設置,類似隔多長時間或有多少數據改動時,生成rdb。
aof類似redis日志,可控制寫入的頻率,如每秒寫入,當開啟aof時(默認關閉),redis內部維護一個aof文件,實時將redis收到的寫命令寫入aof中。
aof由於不斷地寫入,會變得越來越大,當aof大小從0增大到設定的大小時,會觸發aof的第一次rewrite操作,redis會將基於當前的數據生成新的aof文件,在此期間,如果redis收到新的寫命令,redis會將寫命令暫時保存在內存,等新的aof完成后,再將內存中的命令追加到新aof中,當新aof完全完成后(假設大小為n),redis會刪除原aof文件。當新的aof文件不斷擴大到2n時(默認2倍),會觸發rewrite操作。
2、redis主從復制原理,斷點續傳和過期key處理
主從復制:redis主節點(master)向從節點(slave)復制數據,當集群沒有任何問題正常運轉時,主節點將收到的如set,del等命令實時復制給從節點,從節點會讀命令並生產數據。當slave第一次連接master時,master后台生成一份rdb,並等待一段時間,保證更多的slave接入,然后將rdb發給從節點,slave接到rdb后,首先在本地磁盤上備份,然后載入rdb。在此期間,master會將收到的寫命令先存在緩存中,然后發給slave。
斷點續傳:master和slave內部都會維護一個backlog文件,backlog里面保存一個offset數據,記錄復制數據位置。如果slave在工作中斷開一段時間又重新連接,會將自身的offset發給master進行對比,如果能在master找到對應的offset,則從offset開始復制,如果沒找到,則生成完整的rdb給slave。
過期key處理:master的key倍lru處理掉,會發del命令給slave。
3、redis哨兵底層原理(包括選舉算法)

》1、sdown和odown轉換機制

sdown和odown兩種失敗狀態

sdown是主觀宕機,就一個哨兵如果自己覺得一個master宕機了,那么就是主觀宕機

odown是客觀宕機,如果quorum數量的哨兵都覺得一個master宕機了,那么就是客觀宕機

sdown達成的條件很簡單,如果一個哨兵ping一個master,超過了is-master-down-after-milliseconds指定的毫秒數之后,就主觀認為master宕機

sdown到odown轉換的條件很簡單,如果一個哨兵在指定時間內,收到了quorum指定數量的其他哨兵也認為那個master是sdown了,那么就認為是odown了,客觀認為master宕機


》2、哨兵集群的自動發現機制

哨兵互相之間的發現,是通過redis的pub/sub系統實現的,每個哨兵都會往__sentinel__:hello這個channel里發送一個消息,這時候所有其他哨兵都可以消費到這個消息,並感知到其他的哨兵的存在

每隔兩秒鍾,每個哨兵都會往自己監控的某個master+slaves對應的__sentinel__:hello channel里發送一個消息,內容是自己的host、ip和runid還有對這個master的監控配置

每個哨兵也會去監聽自己監控的每個master+slaves對應的__sentinel__:hello channel,然后去感知到同樣在監聽這個master+slaves的其他哨兵的存在

每個哨兵還會跟其他哨兵交換對master的監控配置,互相進行監控配置的同步


》3、slave配置的自動糾正

哨兵會負責自動糾正slave的一些配置,比如slave如果要成為潛在的master候選人,哨兵會確保slave在復制現有master的數據; 如果slave連接到了一個錯誤的master上,比如故障轉移之后,那么哨兵會確保它們連接到正確的master上。

》4、slave->master選舉算法

如果一個master被認為odown了,而且majority哨兵都允許了主備切換,那么某個哨兵就會執行主備切換操作,此時首先要選舉一個slave來

會考慮slave的一些信息

(1)跟master斷開連接的時長
(2)slave優先級
(3)復制offset
(4)run id

如果一個slave跟master斷開連接已經超過了down-after-milliseconds的10倍,外加master宕機的時長,那么slave就被認為不適合選舉為master

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

接下來會對slave進行排序

(1)按照slave優先級進行排序,slave priority越低,優先級就越高
(2)如果slave priority相同,那么看replica offset,哪個slave復制了越多的數據,offset越靠后,優先級就越高
(3)如果上面兩個條件都相同,那么選擇一個run id比較小的那個slave

》5、quorum和majority

每次一個哨兵要做主備切換,首先需要quorum數量的哨兵認為odown,然后選舉出一個哨兵來做切換,這個哨兵還得得到majority哨兵的授權,才能正式執行切換

如果quorum < majority,比如5個哨兵,majority就是3,quorum設置為2,那么就3個哨兵授權就可以執行切換

但是如果quorum >= majority,那么必須quorum數量的哨兵都授權,比如5個哨兵,quorum是5,那么必須5個哨兵都同意授權,才能執行切換

》6、configuration epoch

哨兵會對一套redis master+slave進行監控,有相應的監控的配置

執行切換的那個哨兵,會從要切換到的新master(salve->master)那里得到一個configuration epoch,這就是一個version號,每次切換的version號都必須是唯一的

如果第一個選舉出的哨兵切換失敗了,那么其他哨兵,會等待failover-timeout時間,然后接替繼續執行切換,此時會重新獲取一個新的configuration epoch,作為新的version號

》7、configuraiton傳播

哨兵完成切換之后,會在自己本地更新生成最新的master配置,然后同步給其他的哨兵,就是通過之前說的pub/sub消息機制

這里之前的version號就很重要了,因為各種消息都是通過一個channel去發布和監聽的,所以一個哨兵完成一次新的切換之后,新的master配置是跟着新的version號的

其他的哨兵都是根據版本號的大小來更新自己的master配置的

4、數據分布算法,hash,一致性hash算法,hash slot
一致性hash算法要解決的問題:在多master集群中,所有數據需要按照給定的規則存在固定的master中,保證要查找的時候能知道在哪個master的從節點上。
最原始hash算法:對key計算hashcode值,對master個數取余數,得到master位置,類似hashmap。但是hashmap可以這么做,因為hashmap不存在某個entry宕機的情況。這種做法如果某個master宕機,那么取數據就會出錯。例如,有三個master,第二個master宕機,那么第二個master的數據全丟失,而且master個數變成2,取數據時要除的數字變成2,存的時候除的數字是3,這樣肯定不能找到正確的master。
一致性hash算法:一致性hash算法引入和hash環的概念,所有的master均勻分布在一個長度為(2^32-1)的圓環上,所有的K/V存儲時,都是將key的hashcode%(圓環長度),這個數字對應環上的位置順時針移動,打到哪個master,就存到其中。可以避免某一台master宕機導致整個集群不可用。
hash slot:redis集群固定持有16384個hash slot(虛擬節點),K/V存儲時,對K的取CRC16%16384,找到對應的hash slot,存儲在hash slot上,集群中每個master持有一部分hash slot,當某個master宕機,master上的hash slot會迅速轉移到其他master上,減小數據損失,而hash slot轉移的消耗是極低的。在讀取數據時,真正尋找的,是hash slot,與hash slot在哪個maste上無關,所以即便是master宕機了,上面的數據也不會全部消失,而且剩余數據還能正常工作。


免責聲明!

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



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