了解 Infinispan 和 JGroups 中的故障偵測

本指南說明 JGroups 如何偵測失敗的實例,以及如何設定它。它解釋了可用於自訂的組態屬性及其權衡,以達到所需的偵測速率。

JGroups 的使用位置以及為何故障偵測如此重要

Keycloak 使用 Infinispan 將與工作階段相關的資訊儲存在 Keycloak 內部和外部 Infinispan 實例的分散式快取中。Keycloak 實例和外部 Infinispan 實例會形成叢集,而叢集節點之間的通訊由 JGroups 處理。在多站點設定中,不同外部 Infinispan 叢集之間的通訊也由 JGroups 處理。

此類叢集中的每個節點都提供工作階段資料,這對於 Keycloak 服務請求非常重要。無回應的節點會導致請求被封鎖,並可能導致呼叫端出現逾時和錯誤。如果節點發生故障,則需要將請求重新導向至剩餘節點,並且需要從叢集中的備份節點重新分配其資料。

損壞的 TCP 連線導致通訊失敗

損壞的 TCP 連線會對叢集效能產生影響,並且有必要偵測到它,以便可以關閉連線並建立新的連線。請注意,TCP 是一種封鎖/同步協定,如果連線運作不正常,執行緒將在 Socket::write 操作中被封鎖。核心參數 tcp_retries2 設定失敗重試的次數,直到核心強制關閉連線。引述 核心文件

當 RTO 重新傳輸仍未收到確認時,此值會影響作用中的 TCP 連線逾時。預設值 15 會產生 924.6 秒的假設逾時,並且是有效逾時的下限。

在此期間,叢集效能會降低。不希望變更映像或容器中的核心參數,但 JGroups 具有可以設定以偵測並強制關閉這些損壞連線的屬性。

對於使用 Kubernetes 中的 TUNNEL 協定的跨站點網路通訊,Infinispan Pod 流量會透過 JGroups Gossip Router Pod 轉送。逾時設定在 Infinispan CR YAML 檔案中,如下所示

infinispan.yaml
  service:
    type: DataGrid
    sites:
      local:
        discovery:
          heartbeats:
            interval: 10000 (1)
            timeout: 30000 (2)
1 每隔 interval 毫秒向 Gossip 路由器傳送一次心跳訊號。
2 未收到訊息或心跳訊號後,關閉與 Gossip 路由器的連線的最大時間(以毫秒為單位)。
以上值是 Infinispan Operator 設定的預設值。

縮短間隔和逾時將提高 JGroups 偵測損壞連線的速度。但是,由於心跳訊號頻率增加,它也會增加網路使用量。請注意,兩個叢集中的所有 Infinispan Pod 都會將心跳訊號傳送至所有設定的 Gossip Router Pod。

預設值應適用於 99% 的使用案例。

對於 Infinispan 或 Keycloak 叢集中的叢集內通訊,損壞的 TCP 連線會由故障偵測來偵測和關閉。如需更多資訊,請參閱偵測無回應的節點章節。

偵測無回應的節點

叢集中的節點可能會發生故障,一旦發生這種情況,需要重新導向流量和資料。JGroups 中的故障偵測由 Infinispan 隨附的預設 JGroups 設定中存在的協定 FD_ALL3 提供。

FD_ALL3 是一個簡單的心跳協定,其中每個成員會定期多播心跳訊號。當收到來自另一個 Pod 的資料或心跳訊號時,該 Pod 會被視為作用中,否則該 Pod 會被視為可疑,並可能從群組視圖中移除。

心跳間隔和逾時設定如下所示

<infinispan>
   <jgroups>
      <stack name="my-tcp" extends="tcp"> (1)
         <FD_ALL3 stack.combine="COMBINE"
               interval="8000" (2)
               timeout="40000"/> (3)
      </stack>
   </jgroups>

   <cache-container>
      <transport stack="my-tcp"/> (4)
   </cache-container>
</infinispan>
1 自訂堆疊名稱。
2 將心跳訊號傳送至叢集的間隔,以毫秒為單位。
3 如果既未收到心跳訊號也未收到資料,則節點被視為可疑的逾時,以毫秒為單位。
4 JGroups 要使用的堆疊名稱。
上面的範例顯示預設值。

對於 M 個 Pod 的叢集,每個 Pod 都會在每個間隔產生 M-1 個心跳訊息。縮短 intervaltimeout 可以提高當機 Pod 的偵測速度,但會因為額外傳輸的訊息而對網路產生更大的影響。

如果啟用跨站點,FD_ALL3 心跳也會流向遠端叢集。跨站點通道有其自己的組態,可以獨立於叢集內通訊進行設定。

預設值應適用於 99% 的使用案例。

在 Pod 被視為可疑之後,會觸發不含當機成員的新群組視圖變更。此事件將關閉與該 Pod 的任何損壞的 TCP 連線,並解除封鎖可能被封鎖的執行緒。

讀取和寫入操作的逾時

Infinispan 具有三個可設定的逾時,會影響 Keycloak 和 Infinispan 叢集中的讀取或寫入操作。這些是鎖定逾時、遠端逾時和跨站點遠端逾時。

如果逾時彼此對齊,且與上述說明的故障偵測逾時和間隔對齊,則它們允許在連線或節點故障後至少重試一次。這允許向呼叫端提供有效回應,並隱藏發生的錯誤。

鎖定逾時是指操作等待鎖定釋放的等待時間。這應該是所有時間中最短的。

遠端逾時是 Infinispan Pod 等待來自同一叢集中其他 Pod 回覆的時間。它會影響寫入(在複寫資料時)和讀取(Pod 從其他 Pod 提取資料,如果本機不存在複本)。

最後,對於多站點部署,跨站點遠端逾時是指等待另一個叢集確認更新的等待時間。

變更這些值可能會直接影響回應時間。雖然在正常操作期間,Infinispan 會在幾毫秒內回覆,但如果工作負載較高、Pod 當機或在網路中斷期間,可能會達到這些逾時。

縮短逾時時間會縮短回應時間;Infinispan 會更快放棄,但會增加回報給使用者的錯誤率。增加這些值可能會減少錯誤數量,因為它會給予 Infinispan 更多時間來處理工作負載,但會增加最終使用者觀察到的回應時間。

若要更新使用 Infinispan Operator 部署的 Infinispan 叢集中的任何逾時值,請如下更新您的 CacheCR

apiVersion: infinispan.org/v2alpha1
kind: Cache
metadata:
  name: sessions
spec:
  clusterName: infinispan
  name: sessions
  template: |-
    distributedCache:
      mode: "SYNC"
      owners: 2
      statistics: "true"
      remoteTimeout: "15000" (1)
      locking:
        acquireTimeout: "10000" (2)
      backups:
        cluster-b:
          backup:
            strategy: "SYNC"
            timeout: "15000"  (3)
1 等待來自本機叢集中其他 Pod 回覆的逾時值,以毫秒為單位。
2 等待釋放已鎖定的鎖定的逾時值,以毫秒為單位。
3 等待來自遠端叢集回覆的逾時值,以毫秒為單位。
此範例顯示預設值。僅加入您要更新的逾時的行。

對於在 Keycloak 伺服器中執行的 Infinispan 叢集,需要自訂的 Infinispan XML 檔案。如所示變更快取設定,並加入您要更新的屬性(以粗體顯示)

<distributed-cache name="sessions" owners="2" statistics="true" remote-timeout="15000"> (1)
    <locking acquire-timeout="10000"/> (2)
    <backups>
        <backup site="cluster-b" timeout="15000"/> (3)
    </backups>
</distributed-cache>
1 等待來自本機叢集中其他 Pod 回覆的逾時值,以毫秒為單位。
2 等待釋放已鎖定的鎖定的逾時值,以毫秒為單位。
3 等待來自遠端叢集回覆的逾時值,以毫秒為單位。
此範例顯示預設值。