1. CPA原理是分佈式存儲理論的基石: C(一致性); A(可用性); P(分區容忍性);redis
2. 當主從網絡沒法連通時,修改操做沒法同步到節點,因此「一致性」沒法知足數據庫
3. 除非咱們犧牲「可用性」,也就是暫停分佈式節點服務,再也不提供修改數據功能,知道網絡恢復服務器
一句話歸納CAP: 當網絡分區發生時,一致性 和 可用性 兩難全網絡
1. 和MySQL主從複製的緣由同樣,Redis雖然讀取寫入的速度都特別快,可是也會產生讀壓力特別大的狀況。
2. 爲了分擔讀壓力,Redis支持主從複製,Redis的主從結構能夠採用一主多從或者級聯結構。
3. Redis主從複製能夠根據是不是全量分爲全量同步和增量同步。併發
注:redis主節點Master掛掉時,運維讓從節點Slave接管(redis主從默認沒法自動切換,須要運維手動切換)運維
注:Redis全量複製通常發生在Slave初始化階段,這時Slave須要將Master上的全部數據都複製一份。具體步驟以下:異步
1)從服務器鏈接主服務器,發送SYNC命令;分佈式
2)主服務器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的全部寫命令;高併發
3)主服務器BGSAVE執行完後,向全部從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令;性能
4)從服務器收到快照文件後丟棄全部舊數據,載入收到的快照;
5)主服務器快照發送完畢後開始向從服務器發送緩衝區中的寫命令;
6)從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令;
7)完成上面幾個步驟後就完成了從服務器數據初始化的全部操做,從服務器此時能夠接收來自用戶的讀請求。
1. 主節點會將那些對本身狀態產生修改性影響的指令記錄在本地內存buffer中,而後異步將buffer中指令同步到從節點
2. 從節點一邊執行同步指令達到主節點狀態,一邊向主節點反饋本身同步到哪裏(偏移量)
3. 當網絡狀態很差時,從節點沒法和主節點進行同步,當網絡恢復時須要進行快照同步
1. 主從剛剛鏈接的時候,進行全量同步;全同步結束後,進行增量同步。
2. 固然,若是有須要,slave 在任什麼時候候均可以發起全量同步。
3. redis 策略是,不管如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。
1. 若是多個Slave斷線了,須要重啓的時候,由於只要Slave啓動,就會發送sync請求和主機全量同步,當多個同時出現的時候,可能會致使Master IO劇增宕機。
1. 當用Redis作主從方案時,假如master宕機,Redis自己沒法自動進行主備切換
2. 而Redis-sentinel自己也是一個獨立運行的進程,它能監控多個master-slave集羣,發現master宕機後能進行自動切換。
1. sentinel負責持續監控主節點的健康,當主節掛掉時,自動選擇一個最優的從節點切換成主節點
2. 從節點來鏈接集羣時會首先鏈接sentinel,經過sentinel來查詢主節點的地址
3. 當主節點發生故障時,sentinel會將最新的主節點地址告訴客戶端,能夠實現無需重啓自動切換redis
1. 只使用單個sentinel進程來監控redis集羣是不可靠的,當sentinel進程宕掉後sentinel自己也有單點問題
2. 若是有多個sentinel,redis的客戶端能夠隨意地鏈接任意一個sentinel來得到關於redis集羣中的信息。
1. Sentinel當前穩定版本稱爲Sentinel 2,Redis2.8和Redis3.0附帶穩定的哨兵版本
2. 安裝完redis-3.2.8後,redis-3.2.8/src/redis-sentinel啓動程序 redis-3.2.8/sentinel.conf是配置文件。
法1:redis-sentinel /path/to/sentinel.conf
法2:redis-server /path/to/sentinel.conf --sentinel
1. 以上兩種方式,都必須指定一個sentinel的配置文件sentinel.conf,若是不指定,將沒法啓動sentinel。
2. sentinel默認監聽26379端口,因此運行前必須肯定該端口沒有被別的進程佔用。
1. 配置文件只須要配置master的信息就好啦,不用配置slave的信息,由於slave可以被自動檢測到
2. 須要注意的是,配置文件在sentinel運行期間是會被動態修改的,例如當發生主備切換時候,配置文件中的master會被修改成另一個slave。
3. 這樣,以後sentinel若是重啓時,就能夠根據這個配置來恢復其以前所監控的redis集羣的狀態。
# sentinel.conf 配置說明 sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 60000 sentinel failover-timeout mymaster 180000 sentinel parallel-syncs mymaster 1
'''一、sentinel monitor mymaster 127.0.0.1 6379 2''' #1)sentinel監控的master的名字叫作mymaster,地址爲127.0.0.1:6379 #2)當集羣中有2個sentinel認爲master死了時,才能真正認爲該master已經不可用了 '''二、sentinel down-after-milliseconds mymaster 60000''' #1)sentinel會向master發送心跳PING來確認master是否存活,若是master在60000毫秒內不迴應PONG #2)那麼這個sentinel會單方面地認爲這個master已經不可用了 '''三、sentinel failover-timeout mymaster 180000''' #1)若是sentinel A推薦sentinel B去執行failover,B會等待一段時間後,自行再次去對同一個master執行failover, #2)這個等待的時間是經過failover-timeout配置項去配置的。 #3)從這個規則能夠看出,sentinel集羣中的sentinel不會再同一時刻併發去failover同一個master, #4)第一個進行failover的sentinel若是失敗了,另一個將會在必定時間內進行從新進行failover,以此類推。 '''四、sentinel parallel-syncs mymaster 1''' #1)在發生failover主備切換時,這個選項指定了最多能夠有多少個slave同時對新的master進行同步 #2)若是這個數字越大,就意味着越多的slave由於replication而不可用,這個數字越小,完成failover所需的時間就越長。 #3)能夠經過將這個值設爲 1 來保證每次只有一個slave處於不能處理命令請求的狀態。
1. 一旦一個sentinel成功地對一個master進行了failover,它將會把關於master的最新配置經過廣播形式通知其它sentinel,其它的sentinel則更新對應master的配置。
2. 一個faiover要想被成功實行,sentinel必須可以向選爲master的slave發送SLAVE OF NO ONE
命令,而後可以經過INFO
命令看到新master的配置信息。
3. 當將一個slave選舉爲master併發送SLAVE OF NO ONE
`後,即便其它的slave還沒針對新master從新配置本身,failover也被認爲是成功了的。
由於每個配置都有一個版本號,因此以版本號最大的那個爲標準:
1)假設有一個名爲mymaster的地址爲192.168.1.50:6379。
2)一開始,集羣中全部的sentinel都知道這個地址,因而爲mymaster的配置打上版本號1。
3)一段時候後mymaster死了,有一個sentinel被受權用版本號2對其進行failover。
4)若是failover成功了,假設地址改成了192.168.1.50:9000,此時配置的版本號爲2
5)進行failover的sentinel會將新配置廣播給其餘的sentinel,發現新配置的版本號爲2時,版本號變大了,
說明配置更新了,因而就會採用最新的版本號爲2的配置。
1. 在大數據高併發場景下,單個redis實例每每會沒法應對
2. 首先redis內存不易過大,內存太大會致使rdb文件過大,致使主從同步時間過長
3. 其次在CPU利用率中上,單個redis實例只能利用單核,數據量太大,壓力就會特別大
1. codis是redis集羣解決方案之一,codis是GO語言開發的代理中間件
2. 當客戶端向codis發送指令時,codis負責將指令轉發給後面的redis實例來執行,並將返回結果轉發給客戶端
1. 單個codis代理支撐的QPS比較有限,經過啓動多個codis代理能夠顯著增長總體QPS
2. 多codis還能起到容災功能,掛掉一個codis代理還有不少codis代理能夠繼續服務
1. codis負責將特定key轉發到特定redis實例,codis默認將全部key劃分爲1024個槽位
2. 首先會對客戶端傳來的key進行crc32計算hash值,而後將hash後的整數值對1024進行取模,這個餘數就是對應的key槽位
3. 每一個槽位都會惟一映射到後面的多個redis實例之一,codis會在內存中維護槽位和redis實例的映射關係
4. 這樣有了上面key對應的槽位,那麼它應該轉發到那個redis實例就很明確了
5. 槽位數量默認是1024,若是集羣中節點較多,建議將這個數值大一些,好比2048,4096
1. 若是codis槽位值存在內存中,那麼不一樣的codis實例間的槽位關係得不到同步
2. 因此codis還須要一個分佈式配置存儲的數據庫專門來持久化槽位關係
3. codis將槽位關係存儲在zookeeper中,而且提供一個dashboard能夠來觀察和修改槽位關係