鍍金池/ 教程/ 大數(shù)據(jù)/ 高可用客戶端指引
使用 Redis 實(shí)現(xiàn) Twitter(上)
集群(下)
使用 Redis 實(shí)現(xiàn) Twitter(下)
使用 Redis 作為 LRU 緩存
高可用(上)
高可用客戶端指引
集群(中)
高可用(下)
持久化
Redis 介紹
集中插入
集群(上)
從入門到精通(上)
從入門到精通(下)
從入門到精通(中)
分片
數(shù)據(jù)類型初探
復(fù)制

高可用客戶端指引

本文檔是一篇草案,其包含的指引將來可能會(huì)隨著Sentinel項(xiàng)目的進(jìn)展而改變。

支持Redis Sentinel的Redis客戶端指引

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):

  • 通過Sentinel實(shí)現(xiàn)客戶端的自動(dòng)配置。
  • 改進(jìn)Sentinel自動(dòng)故障轉(zhuǎn)移的安全性。# 高可用客戶端指引

本文檔是一篇草案,其包含的指引將來可能會(huì)隨著 Sentinel 項(xiàng)目的進(jìn)展而改變。

支持 Redis Sentinel 的 Redis 客戶端指引

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):

  • 通過 Sentinel 實(shí)現(xiàn)客戶端的自動(dòng)配置。
  • 改進(jìn) Sentinel 自動(dòng)故障轉(zhuǎn)移的安全性。

要想獲得 Redis Sentinel 如何工作的細(xì)節(jié),請(qǐng)查看相關(guān)文檔(請(qǐng)查看本系列相關(guān)文章,譯者注),本文只包含 Redis 客戶端開發(fā)人員需要的信息,期待讀者已經(jīng)比較熟悉 Redis Sentinel 的工作方式。

通過 Sentinel 實(shí)現(xiàn) Redis 服務(wù)發(fā)現(xiàn)(Redis service discovery)

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 實(shí)例的 ip:port 對(duì)列表。
  • 服務(wù)的名稱,像”timelines”或者”cache”。

下面是客戶端為了從 Sentinel 列表和服務(wù)名稱獲得主服務(wù)器地址而需要遵循的步驟。

第 1 步:連接第一個(gè) Sentinel(connecting to the first Sentinel)

客戶端應(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,以最小化延遲。

第 2 步:請(qǐng)求主服務(wù)器地址(ask for master address)

一旦與 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è) null 回復(fù)。這表示 Sentinel 不知道這個(gè)主服務(wù)器。

如果收到了 ip:port 對(duì),這個(gè)地址應(yīng)該用來連接到 Redis 主服務(wù)器。否則,如果收到了一個(gè) null 回復(fù),客戶端應(yīng)該嘗試列表中的下一個(gè) Sentinel。

第 3 步:在目標(biāo)實(shí)例中調(diào)用 ROLE 命令(call the ROLE command in the target instance)

一旦客戶端發(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 步開始。

處理重連(Handling reconnections)

一旦服務(wù)名稱被解析為主服務(wù)器地址,并且與 Redis 主服務(wù)器實(shí)例的連接已經(jīng)建立,每次需要重新連接時(shí),客戶端應(yīng)該重新從第 1 步開始使用 Sentinel 來解析地址。例如,下面的情況下需要重新聯(lián)系 Sentinel:

  • 如果客戶端在超時(shí)或者 socket 錯(cuò)誤后重連。
  • 如果客戶端因?yàn)楸伙@式關(guān)閉或者被用戶重連而重連。

在上面的情況下或者任何客戶端丟失了與 Redis 服務(wù)器連接的情況下,客戶端應(yīng)該再次解析主服務(wù)器地址。

Sentinel 故障轉(zhuǎn)移斷開(Sentinel failover disconnection)

從 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ù)器。

連接從服務(wù)器(Connecting to slaves)

有時(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ù)器。

連接池(Connection pools)

對(duì)于實(shí)現(xiàn)了連接池的客戶端,當(dāng)單個(gè)連接重連時(shí),應(yīng)該要再次聯(lián)系 Sentinel,如果是主服務(wù)器的地址改變了,所有已經(jīng)存在的連接都要關(guān)閉并且重新連接到新的地址。

錯(cuò)誤報(bào)告(Error reporting)

客戶端應(yīng)該在遇到錯(cuò)誤時(shí)正確的返回信息給用戶,尤其是:

  • 如果沒有 Sentinel 能夠聯(lián)系上(這樣客戶端不可能從 SENTINEL get-master-addr-by-name 獲得回復(fù)),應(yīng)該返回明確表明 Redis Sentinel 不可達(dá)的錯(cuò)誤。
  • 如果所有池中的 Sentinel 返回 null 回復(fù),用戶必須被通知 Sentinel 不認(rèn)識(shí)這個(gè)主服務(wù)器名稱的錯(cuò)誤。

Sentinel 列表自動(dòng)刷新(Sentinels list automatic refresh)

一旦收到 get-master-addr-by-name 的成功回復(fù),客戶端會(huì)按照下面的步驟來更新其內(nèi)部的 Sentinel 節(jié)點(diǎn)的列表:

  • 使用 SENTINEL sentinels 命令獲取這臺(tái)主服務(wù)器的其他 Sentinel 列表。
  • 添加每個(gè)不在列表中的 ip:port 對(duì)到列表的后面。

客戶端不需要更新自己的配置文件來持久化列表。更新內(nèi)存中表示的 Sentinel 列表的能力對(duì)改進(jìn)可靠性已經(jīng)很有用了。

訂閱 Sentinel 事件來改進(jìn)響應(yīng)能力(Subscribe to Sentinel events to improve responsiveness)

介紹 Sentinel 的文檔中展示了客戶端可以使用發(fā)布訂閱來連接 Sentinel 以訂閱 Redis 實(shí)例的配置變更。

這種機(jī)制可以用來加快客戶端的重配置,也就是,客戶端可以監(jiān)聽發(fā)布訂閱,以知道配置變更什么時(shí)候發(fā)生,從而運(yùn)行上文解釋的三步協(xié)議來解析新的 Redis 主服務(wù)器(或者從服務(wù)器)地址。

但是,通過發(fā)布訂閱收到的變更消息不能代替上面的步驟,因?yàn)椴荒鼙WC客戶端可以收到所有的變更消息。

額外信息(Additional information)

要獲得額外信息或者討論這個(gè)指引的特定方面,請(qǐng)發(fā)消息到 Redis Google Group。

上一篇:集群(中)下一篇:分片