設定分散式快取

了解如何設定快取層

Keycloak 的設計宗旨是實現高可用性和多節點叢集設定。目前的分散式快取實作是建立在高效能、可分散的記憶體內資料網格 Infinispan 之上。

啟用分散式快取

當您使用 start 命令以生產模式啟動 Keycloak 時,會啟用快取,並且會探索您網路中的所有 Keycloak 節點。

預設情況下,快取會使用 UDP 傳輸堆疊,以便使用基於 UDP 的 IP 多點廣播傳輸來探索節點。對於大多數生產環境,有比 UDP 更好的探索替代方案。Keycloak 允許您從一組預先定義的預設傳輸堆疊中選擇,或定義您自己的自訂堆疊,您將在本指南稍後看到。

若要明確啟用分散式 Infinispan 快取,請輸入此命令

bin/kc.[sh|bat] start --cache=ispn

當您使用 start-dev 命令以開發模式啟動 Keycloak 時,Keycloak 只會使用本機快取,並且會藉由隱含設定 --cache=local 選項,完全停用分散式快取。local 快取模式僅適用於開發和測試目的。

設定快取

Keycloak 提供了一個快取組態檔案,其中包含位於 conf/cache-ispn.xml 的合理預設值。

快取組態是一個常規的 Infinispan 組態檔案

下表概述了 Keycloak 使用的特定快取。您可以在 conf/cache-ispn.xml 中設定這些快取

快取名稱 快取類型 描述

realms

本機

快取持久化的領域資料

users

本機

快取持久化的使用者資料

authorization

本機

快取持久化的授權資料

keys

本機

快取外部公鑰

work

複寫

在節點之間傳播失效訊息

authenticationSessions

分散式

快取驗證工作階段,在驗證過程中建立/銷毀/過期

sessions

分散式

快取持久化的使用者工作階段資料

clientSessions

分散式

快取持久化的用戶端工作階段資料

offlineSessions

分散式

快取持久化的離線使用者工作階段資料

offlineClientSessions

分散式

快取持久化的離線用戶端工作階段資料

loginFailures

分散式

追蹤失敗的登入,詐欺偵測

actionTokens

分散式

快取動作權杖

快取類型和預設值

本機快取

Keycloak 會在本機快取持久化的資料,以避免不必要地往返資料庫。

下列資料會使用本機快取保留在叢集中每個節點的本機

  • realms 和相關資料,例如用戶端、角色和群組。

  • users 和相關資料,例如授權的角色和群組成員資格。

  • authorization 和相關資料,例如資源、權限和原則。

  • keys

realms、users 和 authorization 的本機快取設定為預設最多可容納 10,000 個項目。本機金鑰快取預設最多可容納 1,000 個項目,並且預設為每小時過期一次。因此,金鑰會被強制定期從外部用戶端或身分提供者下載。

為了實現最佳執行時間並避免額外往返資料庫,您應該考慮查看每個快取的組態,以確保最大項目數與資料庫的大小一致。您可以快取的項目越多,伺服器需要從資料庫擷取資料的頻率就越低。您應該評估記憶體使用率和效能之間的權衡取捨。

本機快取的失效

本機快取可提升效能,但會在多節點設定中增加挑戰。

當一個 Keycloak 節點更新共用資料庫中的資料時,所有其他節點都需要知道它,以便使其快取中的該資料失效。

work 快取是一個複寫的快取,用於傳送這些失效訊息。此快取中的項目/訊息的生命週期非常短暫,您不應預期此快取的大小會隨著時間推移而增加。

驗證工作階段

每當使用者嘗試驗證時,就會建立驗證工作階段。一旦驗證過程完成或由於達到其過期時間,它們就會自動銷毀。

authenticationSessions 分散式快取用於儲存驗證工作階段以及與驗證過程相關聯的任何其他資料。

藉由依賴可分散的快取,驗證工作階段可供叢集中的任何節點使用,以便使用者可以重新導向至任何節點,而不會遺失其驗證狀態。但是,生產就緒的部署應始終考慮工作階段親緣性,並偏好將使用者重新導向至他們的工作階段最初建立所在的節點。這樣做,您將避免節點之間不必要的狀態傳輸,並改善 CPU、記憶體和網路使用率。

使用者工作階段

一旦使用者通過驗證,就會建立使用者工作階段。使用者工作階段會追蹤您的活動使用者及其狀態,以便他們可以順暢地驗證任何應用程式,而無需再次詢問其憑證。對於每個應用程式,使用者會使用用戶端工作階段進行驗證,以便伺服器可以追蹤使用者已驗證的應用程式及其在每個應用程式基礎上的狀態。

每當使用者執行登出、用戶端執行權杖撤銷或由於達到其過期時間時,使用者和用戶端工作階段都會自動銷毀。

工作階段資料預設會儲存在資料庫中,並根據需求載入到下列快取中

  • sessions

  • clientSessions

藉由依賴可分散的快取,快取的使用者和用戶端工作階段可供叢集中的任何節點使用,以便使用者可以重新導向至任何節點,而無需從資料庫載入工作階段資料。但是,生產就緒的部署應始終考慮工作階段親緣性,並偏好將使用者重新導向至他們的工作階段最初建立所在的節點。這樣做,您將避免節點之間不必要的狀態傳輸,並改善 CPU、記憶體和網路使用率。

使用者工作階段和用戶端工作階段的這些記憶體內快取預設限制為每個節點 10000 個項目,這會減少較大型安裝的 Keycloak 的整體記憶體使用量。內部快取將針對每個快取項目僅以單一擁有者執行。請考慮記憶體消耗和資料庫使用率之間的權衡取捨,並為快取設定不同的大小,編輯 Keycloak 的快取組態檔案 (conf/cache-ispn.xml) 以為這些快取設定 <memory max-count="..."/>

揮發性使用者工作階段

預設情況下,使用者工作階段會儲存在資料庫中,並根據需求載入到快取中。可以設定 Keycloak 僅在快取中儲存使用者工作階段,並盡量減少資料庫的使用率。

由於此設定中的所有工作階段都儲存在記憶體中,因此會產生兩個與此相關的副作用:* 在所有 Keycloak 節點重新啟動時遺失工作階段 * 記憶體消耗增加

請按照下列步驟啟用此設定

  1. 由於快取是使用者和用戶端工作階段的唯一真實來源,請將快取設定為不限制項目數,並將每個項目複寫到至少兩個節點。為此,請使用以下更新編輯 Keycloak 的快取組態檔案 (conf/cache-ispn.xml),以用於快取 sessionsclientSessions

    • 移除 <memory max-count="..."/>

    • distributed-cache 標籤的 owners 屬性變更為 2 或更多

    sessions 快取的結果組態範例會如下所示。

    <distributed-cache name="sessions" owners="2">
        <expiration lifespan="-1"/>
    </distributed-cache>
  2. 使用下列命令停用 persistent-user-sessions 功能

    bin/kc.sh start --features-disabled=persistent-user-sessions ...

啟用 multi-site 功能時,無法停用 persistent-user-sessions

離線使用者工作階段

作為 OpenID Connect 提供者,伺服器也能够驗證使用者並發行離線權杖。與一般使用者和用戶端工作階段類似,當伺服器在成功驗證後發行離線權杖時,伺服器也會建立離線使用者工作階段和離線用戶端工作階段。

下列快取用於儲存離線工作階段

  • offlineSessions

  • offlineClientSessions

與一般使用者和用戶端工作階段快取類似,離線使用者和用戶端工作階段快取預設也限制為每個節點 10000 個項目。從記憶體中移除的項目會在需要時從資料庫根據需求載入。請考慮記憶體消耗和資料庫使用率之間的權衡取捨,並為快取設定不同的大小,編輯 Keycloak 的快取組態檔案 (conf/cache-ispn.xml) 以為這些快取設定 <memory max-count="..."/>

密碼暴力破解偵測

loginFailures 分散式快取用於追蹤失敗登入嘗試的資料。此快取需要「暴力破解保護」功能才能在多節點 Keycloak 設定中運作。

動作權杖

動作權杖用於使用者需要非同步確認動作的案例,例如在忘記密碼流程中傳送的電子郵件。actionTokens 分散式快取用於追蹤關於動作權杖的中繼資料。

設定快取最大大小

為了減少記憶體使用量,可以對儲存在給定快取中的項目數量設定上限。若要指定快取的上限,您必須提供以下命令列引數 --cache-embedded-${CACHE_NAME}-max-count=,其中 ${CACHE_NAME} 取代為您想要套用上限的快取名稱。例如,若要將 1000 的上限套用至 offlineSessions 快取,您會設定 --cache-embedded-offline-sessions-max-count=1000。無法在下列快取上定義上限:actionTokenauthenticationSessionsloginFailureswork

設定快取以實現可用性

分散式快取會將快取項目複寫到叢集中節點的子集,並將項目指派給固定的擁有者節點。

每個分散式快取(即資料的主要真實來源(authenticationSessionsloginFailuresactionTokens))預設有兩個擁有者,這表示兩個節點具有特定快取項目的複本。非擁有者節點會查詢特定快取的擁有者以取得資料。當兩個擁有者節點都離線時,所有資料都會遺失。

預設的擁有者數量足以在至少三個節點的叢集設定中,在 1 個節點(擁有者)故障時倖存下來。您可以根據可用性要求自由變更擁有者的數量。若要變更擁有者的數量,請開啟 conf/cache-ispn.xml,並將分散式快取的 owners=<value> 值變更為您想要的值。

指定您自己的快取組態檔案

若要指定您自己的快取組態檔案,請輸入此命令

bin/kc.[sh|bat] start --cache-config-file=my-cache-file.xml

組態檔案相對於 conf/ 目錄。

遠端伺服器的 CLI 選項

為了設定 Keycloak 伺服器以實現高可用性和多節點叢集設定,引入了下列 CLI 選項 cache-remote-hostcache-remote-portcache-remote-usernamecache-remote-password,以簡化 XML 檔案中的設定。一旦存在任何已宣告的 CLI 參數,就表示 XML 檔案中不存在與遠端儲存相關的組態。

連線至不安全的 Infinispan 伺服器

不建議在生產環境中停用安全性!

在開發或測試環境中,更容易啟動未受保護的 Infinispan 伺服器。對於這些使用案例,CLI 選項 cache-remote-tls-enabled 會停用 Keycloak 和 Infinispan 之間的加密 (TLS)。如果 Infinispan 伺服器設定為僅接受加密連線,Keycloak 將無法啟動。

CLI 選項 cache-remote-usernamecache-remote-password 是選用的,如果未設定,Keycloak 將連線至 Infinispan 伺服器,而不呈現任何憑證。如果 Infinispan 伺服器已啟用驗證,Keycloak 將無法啟動。

傳輸堆疊

傳輸堆疊可確保叢集中的分散式快取節點以可靠的方式進行通訊。Keycloak 支援各種傳輸堆疊

  • tcp

  • udp

  • kubernetes

  • ec2

  • azure

  • google

若要套用特定的快取堆疊,請輸入以下指令

bin/kc.[sh|bat] start --cache-stack=<stack>

啟用分散式快取時,預設堆疊會設定為 udp

可用的傳輸堆疊

下表顯示了無需任何額外配置,只需使用 --cache-stack 建置選項即可使用的傳輸堆疊

堆疊名稱 傳輸協定 探索

tcp

TCP

MPING(使用 UDP 多播)。

udp

UDP

UDP 多播

下表顯示了可使用 --cache-stack 執行階段選項和最基本配置的傳輸堆疊

堆疊名稱 傳輸協定 探索

kubernetes

TCP

DNS_PING(需要在 JAVA_OPTS 或 JAVA_OPTS_APPEND 環境變數中新增 -Djgroups.dns.query=<無頭服務 FQDN>)。

額外的傳輸堆疊

下表顯示 Keycloak 支援的傳輸堆疊,但需要一些額外的步驟才能運作。請注意,這些堆疊都不是 Kubernetes / OpenShift 堆疊,因此如果您想在 Google Kubernetes 引擎上執行 Keycloak,則無需啟用 google 堆疊。在這種情況下,請使用 kubernetes 堆疊。相反地,當您在 AWS EC2 執行個體上執行分散式快取設定時,您需要將堆疊設定為 ec2,因為 ec2 不支援像是 UDP 的預設探索機制。

堆疊名稱 傳輸協定 探索

ec2

TCP

NATIVE_S3_PING

google

TCP

GOOGLE_PING2

azure

TCP

AZURE_PING

雲端供應商特定的堆疊需要 Keycloak 的額外相依性。有關更多資訊和包含這些相依性的儲存庫連結,請參閱 Infinispan 文件

要將相依性提供給 Keycloak,請將對應的 JAR 檔放在 providers 目錄中,然後輸入以下指令來建置 Keycloak

bin/kc.[sh|bat] start --cache-stack=<ec2|google|azure>

自訂傳輸堆疊

如果沒有任何可用的傳輸堆疊足以滿足您的部署需求,您可以變更快取設定檔並定義自己的傳輸堆疊。

有關更多詳細資訊,請參閱 使用內嵌 JGroups 堆疊

定義自訂傳輸堆疊
<jgroups>
    <stack name="my-encrypt-udp" extends="udp">
    <SSL_KEY_EXCHANGE keystore_name="server.jks"
        keystore_password="password"
        stack.combine="INSERT_AFTER"
        stack.position="VERIFY_SUSPECT2"/>
        <ASYM_ENCRYPT asym_keylength="2048"
        asym_algorithm="RSA"
        change_key_on_coord_leave = "false"
        change_key_on_leave = "false"
        use_external_key_exchange = "true"
        stack.combine="INSERT_BEFORE"
        stack.position="pbcast.NAKACK2"/>
    </stack>
</jgroups>

<cache-container name="keycloak">
    <transport lock-timeout="60000" stack="my-encrypt-udp"/>
    ...
</cache-container>

預設情況下,設定給 cache-stack 選項的值優先於您在快取設定檔中定義的傳輸堆疊。如果您要定義自訂堆疊,請確保不使用 cache-stack 選項,自訂變更才會生效。

保護快取通訊

目前 Infinispan 快取實作應透過各種安全措施來保護,例如 RBAC、ACL 和傳輸堆疊加密。

JGroups 處理 Keycloak 伺服器之間的所有通訊,並支援 TCP 通訊的 Java SSL 通訊端。Keycloak 使用 CLI 選項來設定 TLS 通訊,而無需建立自訂的 JGroups 堆疊或修改快取 XML 檔案。

若要啟用 TLS,必須將 cache-embedded-mtls-enabled 設定為 true。這需要一個金鑰儲存區,其中包含要使用的憑證:cache-embedded-mtls-key-store-file 設定金鑰儲存區的路徑,而 cache-embedded-mtls-key-store-password 設定解密密碼。信任儲存區包含可接受連線的有效憑證,並且可以使用 cache-embedded-mtls-trust-store-file(信任儲存區的路徑)和 cache-embedded-mtls-trust-store-password(解密密碼)進行設定。為了限制未經授權的存取,請為每個 Keycloak 部署使用自我簽署憑證。

對於使用 UDPTCP_NIO2 的 JGroups 堆疊,請參閱 JGroups 加密文件,了解如何設定協定堆疊。

有關保護快取通訊的更多資訊,請參閱 Infinispan 安全指南

從快取公開指標

啟用指標時,會自動公開快取的指標。

若要為快取指標啟用長條圖,請將 cache-metrics-histograms-enabled 設定為 true。雖然這些指標提供了更多關於延遲分佈的深入分析,但收集它們可能會對效能產生影響,因此您應謹慎地在已經飽和的系統中啟用它們。

bin/kc.[sh|bat] start --metrics-enabled=true --cache-metrics-histograms-enabled=true

有關如何啟用指標的更多詳細資訊,請參閱 啟用 Keycloak 指標

相關選項

快取

定義高可用性的快取機制。

在生產模式下,預設使用 ispn 快取來建立多個伺服器節點之間的叢集。在開發模式下,預設使用 local 快取會停用叢集,用於開發和測試目的。

CLI: --cache
Env: KC_CACHE

ispn(預設)、local

cache-config-file

定義應從中載入快取設定的檔案。

組態檔案相對於 conf/ 目錄。

CLI: --cache-config-file
Env: KC_CACHE_CONFIG_FILE

cache-embedded-authorization-max-count

授權快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-authorization-max-count
Env: KC_CACHE_EMBEDDED_AUTHORIZATION_MAX_COUNT

cache-embedded-client-sessions-max-count

clientSessions 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-client-sessions-max-count
Env: KC_CACHE_EMBEDDED_CLIENT_SESSIONS_MAX_COUNT

僅在設定內嵌 Infinispan 叢集時可用

cache-embedded-keys-max-count

keys 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-keys-max-count
Env: KC_CACHE_EMBEDDED_KEYS_MAX_COUNT

cache-embedded-mtls-enabled

加密 Keycloak 伺服器之間的網路通訊。

CLI: --cache-embedded-mtls-enabled
Env: KC_CACHE_EMBEDDED_MTLS_ENABLED

truefalse(預設)

cache-embedded-mtls-key-store-file

金鑰儲存區檔案路徑。

金鑰儲存區必須包含 TLS 協定要使用的憑證。預設情況下,它會在 conf/ 目錄下尋找 cache-mtls-keystore.p12

CLI: --cache-embedded-mtls-key-store-file
Env: KC_CACHE_EMBEDDED_MTLS_KEY_STORE_FILE

cache-embedded-mtls-key-store-password

存取金鑰儲存區的密碼。

CLI: --cache-embedded-mtls-key-store-password
Env: KC_CACHE_EMBEDDED_MTLS_KEY_STORE_PASSWORD

cache-embedded-mtls-trust-store-file

信任儲存區檔案路徑。

它應該包含受信任的憑證或簽署憑證的憑證授權單位。預設情況下,它會在 conf/ 目錄下尋找 cache-mtls-truststore.p12

CLI: --cache-embedded-mtls-trust-store-file
Env: KC_CACHE_EMBEDDED_MTLS_TRUST_STORE_FILE

cache-embedded-mtls-trust-store-password

存取信任儲存區的密碼。

CLI: --cache-embedded-mtls-trust-store-password
Env: KC_CACHE_EMBEDDED_MTLS_TRUST_STORE_PASSWORD

cache-embedded-offline-client-sessions-max-count

offlineClientSessions 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-offline-client-sessions-max-count
Env: KC_CACHE_EMBEDDED_OFFLINE_CLIENT_SESSIONS_MAX_COUNT

僅在設定內嵌 Infinispan 叢集時可用

cache-embedded-offline-sessions-max-count

offlineSessions 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-offline-sessions-max-count
Env: KC_CACHE_EMBEDDED_OFFLINE_SESSIONS_MAX_COUNT

僅在設定內嵌 Infinispan 叢集時可用

cache-embedded-realms-max-count

realms 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-realms-max-count
Env: KC_CACHE_EMBEDDED_REALMS_MAX_COUNT

cache-embedded-sessions-max-count

sessions 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-sessions-max-count
Env: KC_CACHE_EMBEDDED_SESSIONS_MAX_COUNT

僅在設定內嵌 Infinispan 叢集時可用

cache-embedded-users-max-count

users 快取可以記憶體中儲存的最大項目數。

CLI: --cache-embedded-users-max-count
Env: KC_CACHE_EMBEDDED_USERS_MAX_COUNT

cache-metrics-histograms-enabled

為內嵌快取的指標啟用長條圖。

CLI: --cache-metrics-histograms-enabled
Env: KC_CACHE_METRICS_HISTOGRAMS_ENABLED

僅在啟用指標時可用

truefalse(預設)

cache-remote-host

遠端儲存設定的遠端伺服器的主機名稱。

它會取代透過 XML 檔案(請參閱 cache-config-file 選項)指定的設定檔中 remote-server 標籤的 host 屬性。如果指定此選項,則也需要 cache-remote-usernamecache-remote-password,且 XML 檔案中不應存在相關設定。

CLI: --cache-remote-host
Env: KC_CACHE_REMOTE_HOST

cache-remote-password

用於驗證遠端儲存的遠端伺服器的密碼。

它會取代透過 XML 檔案(請參閱 cache-config-file 選項)指定的設定檔中 digest 標籤的 password 屬性。如果指定此選項,則也需要 cache-remote-username,且 XML 檔案中不應存在相關設定。

CLI: --cache-remote-password
Env: KC_CACHE_REMOTE_PASSWORD

僅在設定遠端主機時可用

cache-remote-port

遠端儲存設定的遠端伺服器的連接埠。

它會取代透過 XML 檔案(請參閱 cache-config-file 選項)指定的設定檔中 remote-server 標籤的 port 屬性。

CLI: --cache-remote-port
Env: KC_CACHE_REMOTE_PORT

僅在設定遠端主機時可用

11222(預設)

cache-remote-tls-enabled

啟用 TLS 支援以與安全的遠端 Infinispan 伺服器進行通訊。

建議在生產環境中啟用。

CLI: --cache-remote-tls-enabled
Env: KC_CACHE_REMOTE_TLS_ENABLED

僅在設定遠端主機時可用

true(預設)、false

cache-remote-username

用於驗證遠端儲存的遠端伺服器的使用者名稱。

它會取代透過 XML 檔案(請參閱 cache-config-file 選項)指定的設定檔中 digest 標籤的 username 屬性。如果指定此選項,則也需要 cache-remote-password,且 XML 檔案中不應存在相關設定。

CLI: --cache-remote-username
Env: KC_CACHE_REMOTE_USERNAME

僅在設定遠端主機時可用

cache-stack

定義用於叢集通訊和節點探索的預設堆疊。

只有當 cache 設定為 ispn 時,此選項才會生效。預設值:udp。

CLI: --cache-stack
Env: KC_CACHE_STACK

tcpudpkubernetesec2azuregoogle 或任何

在此頁面上