高级开发运维从简单学:Redis哨兵和集群小贴士
目錄
寫在前面
一、數(shù)據(jù)庫服務(wù)器高可用
二、 Sentinel (哨兵)是啥?
三、部署 Sentinel過程?
1、初始化服務(wù)器
2、將普通的Redis服務(wù)器使用的代碼替換成sentinel專用代碼
3、初始化sentinel狀態(tài)
4、創(chuàng)建連向主服務(wù)器的網(wǎng)絡(luò)連接
5、哨兵監(jiān)控實現(xiàn)原理
四、分布式數(shù)據(jù)庫高并發(fā)
五、Redis集群是如何實現(xiàn)的?
1、【槽指派】
2、【重新分片】
3、【MOVED錯誤】
4、【ASK錯誤】
寫在前面
最近博主學(xué)習(xí)數(shù)據(jù)庫方面的知識,也算是小白入門,大家伙來一起學(xué)習(xí)交流,我邊看書邊記錄總結(jié),馬上又開啟新的一周,趕緊把過去一周零散學(xué)習(xí)的知識記錄下來,以作備忘。
或許你了解高級開發(fā)運維知識,對高可用、高并發(fā)、分布式略知一二,或許你跟我一樣剛剛?cè)腴T,那就看完本篇,應(yīng)該有所收獲,其實這篇總結(jié)的知識點不難,是最基礎(chǔ)的Redis多機數(shù)據(jù)庫下的哨兵架構(gòu)和集群架構(gòu)。可能單純的文字描述閱讀起來有點枯燥,但內(nèi)容算是干貨總結(jié),值得閱讀,最后一鍵三連更好哈 :)
有趣的內(nèi)容大家可以看看我的博客,例如這篇:我之前做的這個《口罩預(yù)約管理系統(tǒng)——數(shù)據(jù)庫設(shè)計(前端+PHP+MySQL)》(有興趣可以瞧瞧,完整項目源碼和教程已上傳CSDN)。
還有《Socket網(wǎng)絡(luò)編程專欄》:https://blog.csdn.net/charzous/category_10465473.html? 里面有好玩的小程序(模擬QQ郵箱、實時聊天小程序、C/S架構(gòu)的通信等)。
一、數(shù)據(jù)庫服務(wù)器高可用
高可用性(High Availability)是系統(tǒng)開發(fā)中是經(jīng)常提到的一個名詞,現(xiàn)在來看看它具體指的是什么,顧名思義,就是保證某種事物可用性很高,不容易出現(xiàn)問題,對于服務(wù)器來講,那它指的就是來描述一個系統(tǒng)經(jīng)過專門的設(shè)計,從而增加正常運行時間,減少故障或者宕機停工時間,而保持其服務(wù)的高度可用性。
二、 Sentinel (哨兵)是啥?
出現(xiàn)的問題是:Redis主從復(fù)制模式下,當(dāng)主服務(wù)器由于故障不能提供服務(wù),需要人工將從節(jié)點晉升為主節(jié)點,同時需要更新應(yīng)用方的主節(jié)點地址。這種故障處理方法明顯是低效且繁瑣的。
由此,Redis服務(wù)器為了保證高可用性,Sentinel(哨兵)架構(gòu)誕生了!
sentinel架構(gòu)就是Redis高可用的解決方案。(圖片來源:Redis開發(fā)與運維)
- 它是由一個或多個sentinel實例組成的sentinel系統(tǒng),可以監(jiān)視任意多個主服務(wù)器,以及其下從服務(wù)器。
- 在被監(jiān)視的主服務(wù)器進入下線狀態(tài)時,自動將下屬的某個服務(wù)器升級為新的主服務(wù)器,代替下線的主服務(wù)器繼續(xù)處理命令請求。
三、部署 Sentinel過程?
sentinel系統(tǒng)的部署大概有下面幾個步驟:啟動和初始化sentinel命令:
redis-sentinel sentinel.conf?sentinel架構(gòu)部署如圖:?
1、初始化服務(wù)器
Sentinel 執(zhí)行的工作和普通 Redis 服務(wù)器執(zhí)行的工作不同, 所以 Sentinel 的初始化過程和普通 Redis 服務(wù)器的初始化過程并不完全相同。
比如說, 普通服務(wù)器在初始化時會通過載入 RDB 文件或者 AOF 文件來還原數(shù)據(jù)庫狀態(tài), 但是Sentinel 并不使用數(shù)據(jù)庫, 所以初始化 Sentinel 時就不會載入 RDB 文件或者 AOF 文件。
2、將普通的Redis服務(wù)器使用的代碼替換成sentinel專用代碼
使用REDIS_SENTINEL_PORT端口26379。命令列表包括:ping、sentinel、subscribe、unsubscribe、psubscribe、punsubscribe、info。
Sentinel 則使用 sentinel.c/sentinelcmds 作為服務(wù)器的命令表,具體如下:
struct redisCommand sentinelcmds[] = {{"ping",pingCommand,1,"",0,NULL,0,0,0,0,0},{"sentinel",sentinelCommand,-2,"",0,NULL,0,0,0,0,0},{"subscribe",subscribeCommand,-2,"",0,NULL,0,0,0,0,0},{"unsubscribe",unsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},{"psubscribe",psubscribeCommand,-2,"",0,NULL,0,0,0,0,0},{"punsubscribe",punsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},{"info",sentinelInfoCommand,-1,"",0,NULL,0,0,0,0,0} };3、初始化sentinel狀態(tài)
其中,master屬性記錄了所有被監(jiān)視的主服務(wù)器的相關(guān)信息,數(shù)據(jù)結(jié)構(gòu)是字典。
- 字典的鍵是被監(jiān)視主服務(wù)器的名字。
- 而字典的值是被監(jiān)視主服務(wù)器對應(yīng)的?sentinel.c/sentinelRedisInstance?結(jié)構(gòu)。
4、創(chuàng)建連向主服務(wù)器的網(wǎng)絡(luò)連接
一個是命令連接,專門用于向主服務(wù)器發(fā)送的命令,并接受命令回復(fù)。
一個是訂閱連接,專用用于訂閱主服務(wù)器的__sentinel__:hello頻道,保證頻道信息不丟失。
為什么有訂閱連接?
在 Redis 目前的發(fā)布與訂閱功能中, 被發(fā)送的信息都不會保存在 Redis 服務(wù)器里面, 如果在信息發(fā)送時, 想要接收信息的客戶端不在線或者斷線, 那么這個客戶端就會丟失這條信息。
因此, 為了不丟失?__sentinel__:hello?頻道的任何信息, Sentinel 必須專門用一個訂閱連接來接收該頻道的信息。
因為 Sentinel 需要與多個實例創(chuàng)建多個網(wǎng)絡(luò)連接, 所以 Sentinel 使用的是異步連接。
5、哨兵監(jiān)控實現(xiàn)原理
?Redis Sentinel通過三個定時監(jiān)控任務(wù)完成對各個節(jié)點發(fā)現(xiàn)和監(jiān)控,是判定節(jié)點不可達的重要保證。
任務(wù)1:每隔10秒,每個Sentinel節(jié)點會向主節(jié)點和從節(jié)點發(fā)送info命令獲取最新的拓?fù)浣Y(jié)構(gòu),如圖所示。
任務(wù)2:每隔2秒,定時任務(wù)可以完成以下兩個工作:
- 發(fā)現(xiàn)新的Sentinel節(jié)點:通過訂閱主節(jié)點的__sentinel__:hello了解其他的Sentinel節(jié)點信息,如果是新加入的Sentinel節(jié)點,將該Sentinel節(jié)點信息保存起來,并與該Sentinel節(jié)點創(chuàng)建連接。
- Sentinel節(jié)點之間交換主節(jié)點的狀態(tài),作為后面客觀下線以及領(lǐng)導(dǎo)者選舉的依據(jù)。
任務(wù)3:每隔1秒,每個Sentinel節(jié)點會向主節(jié)點、從節(jié)點、其余Sentinel節(jié)點發(fā)送一條ping命令做一次心跳檢測,來確認(rèn)這些節(jié)點當(dāng)前是否可達。
?
四、分布式數(shù)據(jù)庫高并發(fā)
高并發(fā)(High Concurrency)是分布式系統(tǒng)架構(gòu)設(shè)計中必須考慮的因素之一,它通常是指,通過設(shè)計保證系統(tǒng)能夠同時并行處理很多請求。
高并發(fā)相關(guān)常用的一些指標(biāo)有響應(yīng)時間,吞吐量,每秒查詢率QPS(Query Per Second),并發(fā)用戶數(shù)等。
五、Redis集群是如何實現(xiàn)的?
Redis集群就是提供的分布式數(shù)據(jù)庫方案。集群通過分片來進行數(shù)據(jù)共享,并提供復(fù)制和故障轉(zhuǎn)移的功能。
Redis的一個集群由多個節(jié)點組成,一個節(jié)點就是一個運行在集群模式下的Redis服務(wù)器,配置選項cluster-enabled決定是否開啟集群模式。
集群的建立通過向一個節(jié)點發(fā)送cluster meet <ip> <port>命令,握手成功則添加到node節(jié)點當(dāng)前所在的集群。
Redis集群的知識非常豐富,這里簡單介紹其中的幾個重要的點。
1、【槽指派】
Redis集群通過分片的方式來保存數(shù)據(jù)庫中的鍵值對。集群的整個數(shù)據(jù)庫被分為16384個槽slot,數(shù)據(jù)庫中的每個鍵都屬于這些槽中的一個,集群中的每個節(jié)點可以處理0個或16384個槽。
2、【重新分片】
可以將任意數(shù)量的已經(jīng)指派給某個節(jié)點的槽改為指派給另一個節(jié)點,并且相關(guān)槽所屬的鍵值對也會移動到目標(biāo)節(jié)點。
3、【MOVED錯誤】
當(dāng)節(jié)點發(fā)現(xiàn)鍵所在的槽并非由自己處理時候,節(jié)點就會向客戶端返回一個MOVED錯誤,指引客戶端轉(zhuǎn)向正在負(fù)責(zé)槽的節(jié)點。
集群模式下的客戶端并不會打印出MOVED錯誤,而是自動進行節(jié)點轉(zhuǎn)向,打印轉(zhuǎn)向信息,單機模式下就會打印出錯誤信息。
4、【ASK錯誤】
在重新分片期間,可能出現(xiàn)部分分片存在于不同節(jié)點的情況,客戶端向源節(jié)點發(fā)送鍵值對請求命令,出現(xiàn)ASK錯誤。同樣的,集群模式下ASK錯誤會自動轉(zhuǎn)向目標(biāo)節(jié)點。
可能單純的文字描述閱讀起來有點枯燥,但內(nèi)容算是干貨總結(jié),值得閱讀,最后一鍵三連更好哈 :)
有趣的內(nèi)容大家可以看看我的博客,例如這篇:我之前做的這個《口罩預(yù)約管理系統(tǒng)——數(shù)據(jù)庫設(shè)計(前端+PHP+MySQL)》(有興趣可以瞧瞧,完整項目源碼和教程已上傳CSDN)。
還有《Socket網(wǎng)絡(luò)編程專欄》:https://blog.csdn.net/charzous/category_10465473.html? 里面有好玩的小程序(模擬QQ郵箱、實時聊天小程序、C/S架構(gòu)的通信等)。
如果覺得不錯歡迎“一鍵三連”哦,點贊收藏關(guān)注,評論提問建議,歡迎交流學(xué)習(xí)!一起加油進步!?
本篇內(nèi)容首發(fā)我的CSDN博客:https://csdn-czh.blog.csdn.net/article/details/116596657
總結(jié)
以上是生活随笔為你收集整理的高级开发运维从简单学:Redis哨兵和集群小贴士的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2015无法使用编辑并继续 及 警告
- 下一篇: 【SequoiaDB|巨杉数据库】数据库