本文檔是一篇草案,其包含的指引將來可能會(huì)隨著Sentinel項(xiàng)目的進(jìn)展而改變。
Redis Sentinel是Redis實(shí)例的監(jiān)控解決方案,處理Redis主服務(wù)器的自動(dòng)故障轉(zhuǎn)移和服務(wù)發(fā)現(xiàn)(誰是一組實(shí)例中的當(dāng)前主服務(wù)器)。由于Sentinel具有在故障轉(zhuǎn)移期間重新配置實(shí)例,以及提供配置給連接Redis主服務(wù)器或者從服務(wù)器的客戶端的雙重責(zé)任,客戶端需要有對(duì)Redis Sentinel的顯式支持。
這篇文檔針對(duì)Redis客戶端開發(fā)人員,他們想在其客戶端實(shí)現(xiàn)中支持Sentinel,以達(dá)到如下目標(biāo):
本文檔是一篇草案,其包含的指引將來可能會(huì)隨著 Sentinel 項(xiàng)目的進(jìn)展而改變。
Redis Sentinel 是 Redis 實(shí)例的監(jiān)控解決方案,處理 Redis 主服務(wù)器的自動(dòng)故障轉(zhuǎn)移和服務(wù)發(fā)現(xiàn)(誰是一組實(shí)例中的當(dāng)前主服務(wù)器)。由于 Sentinel 具有在故障轉(zhuǎn)移期間重新配置實(shí)例,以及提供配置給連接 Redis 主服務(wù)器或者從服務(wù)器的客戶端的雙重責(zé)任,客戶端需要有對(duì) Redis Sentinel 的顯式支持。
這篇文檔針對(duì) Redis 客戶端開發(fā)人員,他們想在其客戶端實(shí)現(xiàn)中支持 Sentinel,以達(dá)到如下目標(biāo):
要想獲得 Redis Sentinel 如何工作的細(xì)節(jié),請(qǐng)查看相關(guān)文檔(請(qǐng)查看本系列相關(guān)文章,譯者注),本文只包含 Redis 客戶端開發(fā)人員需要的信息,期待讀者已經(jīng)比較熟悉 Redis Sentinel 的工作方式。
Redis Sentinel 通過像”stats”或”cache”這樣的名字來識(shí)別每個(gè)主服務(wù)器。每個(gè)名字實(shí)際上標(biāo)識(shí)了一組實(shí)例,由一個(gè)主服務(wù)器和若干個(gè)從服務(wù)器組成。
網(wǎng)絡(luò)中用于特定目的的 Redis 主服務(wù)器的地址,在一些像自動(dòng)故障轉(zhuǎn)移,手工觸發(fā)故障轉(zhuǎn)移(例如,為了提升一個(gè) Redis 實(shí)例),或者其他原因引起的這樣的事件后可能會(huì)改變。
通常,Redis 客戶端中有一些硬編碼的配置來指定 IP 地址和端口作為網(wǎng)絡(luò)中 Redis 主服務(wù)器的地址。但是,如果主服務(wù)器的地址改變了,就需要手工介入到每個(gè)客戶端了。
支持 Sentinel 的 Redis 客戶端可以從使用 Sentinel 的主服務(wù)器的名稱自動(dòng)發(fā)現(xiàn) Redis 的地址。所以支持 Sentinel 的客戶端應(yīng)該可以從輸入中獲得,而不是硬編碼的 IP 地址和端口:
下面是客戶端為了從 Sentinel 列表和服務(wù)名稱獲得主服務(wù)器地址而需要遵循的步驟。
客戶端應(yīng)該迭代 Sentinel 地址列表。應(yīng)該嘗試使用較短的超時(shí)(大約幾百毫秒)來連接到每一個(gè)地址的 Sentinel。遇到錯(cuò)誤或者超時(shí)就嘗試下一個(gè) Sentinel 地址。
如果所有的 Sentinel 地址都沒有嘗試成功,就返回一個(gè)錯(cuò)誤給客戶端。
第一個(gè)回應(yīng)客戶端請(qǐng)求的 Sentinel 被置于列表的開頭,這樣在下次重連時(shí),我們會(huì)首先嘗試在上一次連接嘗試是可達(dá)的 Sentinel,以最小化延遲。
一旦與 Sentinel 的連接建立起來,客戶端應(yīng)該重新嘗試在 Sentinel 上執(zhí)行下面的命令:
SENTINEL get-master-addr-by-name master-name
這里的 master-name 應(yīng)該被替換為用戶指定的真實(shí)服務(wù)名稱。
調(diào)用的結(jié)果可能是下面兩種回復(fù)之一:
如果收到了 ip:port 對(duì),這個(gè)地址應(yīng)該用來連接到 Redis 主服務(wù)器。否則,如果收到了一個(gè) null 回復(fù),客戶端應(yīng)該嘗試列表中的下一個(gè) Sentinel。
一旦客戶端發(fā)現(xiàn)了主服務(wù)器實(shí)例的地址,就應(yīng)該嘗試與主服務(wù)器的連接,然后調(diào)用 ROLE 命令來驗(yàn)證實(shí)例的角色真的是一個(gè)主服務(wù)器。
如果 ROLE 命令不可用(Redis 2.8.12 引進(jìn)的),客戶端可以使用 INFO 復(fù)制命令來解析角色:輸出中的某一個(gè)字段。
如果實(shí)例不是期待中的主服務(wù)器,客戶端應(yīng)該等待一小段時(shí)間(幾百毫秒)然后再嘗試從第 1 步開始。
一旦服務(wù)名稱被解析為主服務(wù)器地址,并且與 Redis 主服務(wù)器實(shí)例的連接已經(jīng)建立,每次需要重新連接時(shí),客戶端應(yīng)該重新從第 1 步開始使用 Sentinel 來解析地址。例如,下面的情況下需要重新聯(lián)系 Sentinel:
在上面的情況下或者任何客戶端丟失了與 Redis 服務(wù)器連接的情況下,客戶端應(yīng)該再次解析主服務(wù)器地址。
從 Redis 2.8.12 開始,當(dāng) Redis Sentinel 改變了實(shí)例的配置,例如,提升從服務(wù)器為主服務(wù)器,故障轉(zhuǎn)移后降級(jí)主服務(wù)器來復(fù)制新的主服務(wù)器,或者只是改變一個(gè)舊的(stale)從服務(wù)器的主服務(wù)器地址,會(huì)發(fā)送一個(gè) CLIENT KILL 類型的命令給實(shí)例,來確保所有的客戶端都與重新配置過的實(shí)例斷開。這會(huì)強(qiáng)制客戶端再次解析主服務(wù)器地址。
如果客戶端要聯(lián)系一個(gè)還未更新信息的 Sentinel,通過 ROLE 命令驗(yàn)證 Redis 實(shí)例角色會(huì)失敗,允許客戶端發(fā)現(xiàn)聯(lián)系上的 Sentinel 提供了舊的(stale)信息,然后會(huì)重試。
注意:一個(gè)舊的主服務(wù)器返回在線的同時(shí),客戶端聯(lián)系一個(gè)舊的 Sentinel 實(shí)例是有可能的,所以客戶端可能連接了一個(gè)舊的主服務(wù)器,然而 ROLE 的輸出也是匹配的。但是,當(dāng)主服務(wù)器恢復(fù)回來以后,Sentinel 將會(huì)嘗試將其降級(jí)為從服務(wù)器,觸發(fā)一次新的斷開。這個(gè)邏輯也適用于連接到一個(gè)舊的從服務(wù)器,其會(huì)被重新配置來復(fù)制一個(gè)不同的主服務(wù)器。
有時(shí)候客戶端有興趣連接到從服務(wù)器,例如,為了分離(scale)讀請(qǐng)求。簡(jiǎn)單修改一下第 2 步就可以支持連接從服務(wù)器。不是調(diào)用下面的命令:
SENTINEL get-master-addr-by-name master-name
客戶端應(yīng)該調(diào)用:
SENTINEL slaves master-name
用于檢索從服務(wù)器實(shí)例的清單。
相應(yīng)地,客戶端應(yīng)該使用 ROLE 命令來驗(yàn)證實(shí)例真的是一個(gè)從服務(wù)器,以防止分離讀請(qǐng)求到主服務(wù)器。
對(duì)于實(shí)現(xiàn)了連接池的客戶端,當(dāng)單個(gè)連接重連時(shí),應(yīng)該要再次聯(lián)系 Sentinel,如果是主服務(wù)器的地址改變了,所有已經(jīng)存在的連接都要關(guān)閉并且重新連接到新的地址。
客戶端應(yīng)該在遇到錯(cuò)誤時(shí)正確的返回信息給用戶,尤其是:
一旦收到 get-master-addr-by-name 的成功回復(fù),客戶端會(huì)按照下面的步驟來更新其內(nèi)部的 Sentinel 節(jié)點(diǎn)的列表:
客戶端不需要更新自己的配置文件來持久化列表。更新內(nèi)存中表示的 Sentinel 列表的能力對(duì)改進(jìn)可靠性已經(jīng)很有用了。
介紹 Sentinel 的文檔中展示了客戶端可以使用發(fā)布訂閱來連接 Sentinel 以訂閱 Redis 實(shí)例的配置變更。
這種機(jī)制可以用來加快客戶端的重配置,也就是,客戶端可以監(jiān)聽發(fā)布訂閱,以知道配置變更什么時(shí)候發(fā)生,從而運(yùn)行上文解釋的三步協(xié)議來解析新的 Redis 主服務(wù)器(或者從服務(wù)器)地址。
但是,通過發(fā)布訂閱收到的變更消息不能代替上面的步驟,因?yàn)椴荒鼙WC客戶端可以收到所有的變更消息。
要獲得額外信息或者討論這個(gè)指引的特定方面,請(qǐng)發(fā)消息到 Redis Google Group。