在 Istio 中實現 Redis 叢集的資料分片、讀寫分離和流量映象

騰訊雲原生發表於2020-10-22

Redis 是一個高效能的 key-value 儲存系統,被廣泛用於微服務架構中。如果我們想要使用 Redis 叢集模式提供的高階特性,則需要對客戶端程式碼進行改動,這帶來了應用升級和維護的一些困難。利用 Istio 和 Envoy ,我們可以在不修改客戶端程式碼的前提下實現客戶端無感知的 Redis Cluster 資料分片,並提供讀寫分離、流量映象等高階流量管理功能。

Redis Cluster

Redis 的一個常見用途是用作資料快取記憶體。通過在應用伺服器和資料庫伺服器之間加入一個 Redis 快取層,可以減少應用伺服器對資料庫的大量讀操作,避免資料庫伺服器在大壓力下響應緩慢甚至當機的風險,顯著加強整個系統的健壯性。Redis 作為資料快取的原理如圖所示:

在一個小規模的系統中,上圖所示的單個 Redis 就可以很好地實現快取層的功能。當系統中需要快取的資料量較大時,一個 Redis 伺服器無法承擔所有應用伺服器的快取需求;同時單個 Redis 例項失效時也會導致大量讀請求被直接傳送到後端的資料庫伺服器上,導致資料庫伺服器瞬時壓力超標,影響系統的穩定性。我們可以採用 Redis Cluster 來對快取資料進行分片,將不同的資料放到不同的 Redis 分片中,以提高 Redis 快取層的容量能力。在每個 Redis 分片中,還可以採用多個 replica 節點對快取的讀請求進行負載分擔,並實現 Redis 的高可用。採用了 Redis Cluster 的系統如下圖所示:

從圖中可以看到,在 Redis Cluster 模式下,客戶端需要根據叢集的分片規則將不同 key 的讀寫操作傳送到叢集中不同的 Redis 節點上,因此客戶端需要了解 Redis Cluster 的拓撲結構,這導致我們無法在不修改客戶端的情況下將一個使用 Redis 獨立節點模式的應用平滑遷移到 Redis Cluster 上。另外,由於客戶端需要了解 Redis Cluster 的內部拓撲,也將導致客戶端程式碼和 Redis Cluster 運維上的耦合,例如要實現讀寫分離或者流量映象的話,就需要修改每個客戶端的程式碼並重新部署。

這種場景下,我們可以在應用伺服器和 Redis Cluster 之間放置一個 Envoy 代理伺服器,由 Envoy 來負責將應用發出的快取讀寫請求路由到正確的 Redis 節點上。一個微服務系統中存在大量需要訪問快取伺服器的應用程式,為了避免單點故障和效能瓶頸,我們以 Sidecar 的形式為每個應用程式部署一個 Envoy 代理。同時,為了簡化對這些代理的管理工作,我們可以採用 Istio 作為控制面來統一對所有 Envoy 代理進行配置,如下圖所示:

在本文的後續部分,我們將介紹如何通過 Istio 和 Envoy 來管理 Redis Cluster,實現客戶端無感知的資料分割槽,以及讀寫分離、流量映象等高階路由策略。

部署 Istio

Pilot 中已經支援了 Redis 協議,但功能較弱,只能為 Redis 代理配置一個預設路由,而且不支援 Redis Cluster 模式,無法實現 Redis filter 的資料分片、讀寫分離、流量映象等高階流量管理功能。為了讓 Istio 可以將 Redis Cluster 相關的配置下發到 Envoy Sidecar 上,我們修改了 EnvoyFilter 配置相關程式碼,以支援 EnvoyFilter 的 "REPLCAE" 操作。該修改的 PR Implement REPLACE operation for EnvoyFilter patch 已經提交到 Istio 社群,併合入到了主分支中,將在 Istio 後續的版本中釋出。

在撰寫本文的時候,最新的 Istio 釋出版本 1.7.3 中尚未合入該 PR。因此我構建了一個 Pilot 映象,以啟用 EnvoyFilter 的 "REPLACE" 操作。在安裝 Istio 時,我們需要在 istioctl 命令中指定採用該 Pilot 映象,如下面的命令列所示:

$ cd istio-1.7.3/bin
$ ./istioctl install --set components.pilot.hub=zhaohuabing --set components.pilot.tag=1.7.3-enable-ef-replace

備註:如果你採用的 Istio 版本新於 1.7.3,並且已經合入了該 PR,則可以直接採用 Istio 版本中預設的 Pilot 映象。

部署 Redis Cluster

請從 https://github.com/zhaohuabing/istio-redis-culster 下載下面示例中需要用到的相關程式碼:

$ git clone https://github.com/zhaohuabing/istio-redis-culster.git
$ cd istio-redis-culster

我們建立一個 "redis" namespace 來部署本例中的 Redis Cluster。

$ kubectl create ns redis
namespace/redis created

部署 Redis 伺服器的 Statefulset 和 Configmap。

$ kubectl apply -f k8s/redis-cluster.yaml -n redis
configmap/redis-cluster created
statefulset.apps/redis-cluster created
service/redis-cluster created

驗證 Redis 部署

確認 Redis 節點已經啟動並正常執行:

$ kubectl get pod -n redis
NAME              READY   STATUS    RESTARTS   AGE
redis-cluster-0   2/2     Running   0          4m25s
redis-cluster-1   2/2     Running   0          3m56s
redis-cluster-2   2/2     Running   0          3m28s
redis-cluster-3   2/2     Running   0          2m58s
redis-cluster-4   2/2     Running   0          2m27s
redis-cluster-5   2/2     Running   0          117s

建立 Redis Cluster

在上面的步驟中,我們採用 Statefulset 部署了6個 Redis 節點,但目前這6個節點還是相互獨立的,並未形成一個叢集。下面我們採用 Redis 的 cluster create 命令將這些節點組成一個 Redis Cluster。

$ kubectl exec -it redis-cluster-0 -n redis -- redis-cli --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 ' -n redis)
Defaulting container name to redis.
Use 'kubectl describe pod/redis-cluster-0 -n redis' to see all of the containers in this pod.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.16.0.72:6379 to 172.16.0.138:6379
Adding replica 172.16.0.201:6379 to 172.16.1.52:6379
Adding replica 172.16.0.139:6379 to 172.16.1.53:6379
M: 8fdc7aa28a6217b049a2265b87bff9723f202af0 172.16.0.138:6379
   slots:[0-5460] (5461 slots) master
M: 4dd6c1fecbbe4527e7d0de61b655e8b74b411e4c 172.16.1.52:6379
   slots:[5461-10922] (5462 slots) master
M: 0b86a0fbe76cdd4b48434b616b759936ca99d71c 172.16.1.53:6379
   slots:[10923-16383] (5461 slots) master
S: 94b139d247e9274b553c82fbbc6897bfd6d7f693 172.16.0.139:6379
   replicates 0b86a0fbe76cdd4b48434b616b759936ca99d71c
S: e293d25881c3cf6db86034cd9c26a1af29bc585a 172.16.0.72:6379
   replicates 8fdc7aa28a6217b049a2265b87bff9723f202af0
S: ab897de0eca1376558e006c5b0a49f5004252eb6 172.16.0.201:6379
   replicates 4dd6c1fecbbe4527e7d0de61b655e8b74b411e4c
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.16.0.138:6379)
M: 8fdc7aa28a6217b049a2265b87bff9723f202af0 172.16.0.138:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 4dd6c1fecbbe4527e7d0de61b655e8b74b411e4c 172.16.1.52:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 94b139d247e9274b553c82fbbc6897bfd6d7f693 172.16.0.139:6379
   slots: (0 slots) slave
   replicates 0b86a0fbe76cdd4b48434b616b759936ca99d71c
M: 0b86a0fbe76cdd4b48434b616b759936ca99d71c 172.16.1.53:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: ab897de0eca1376558e006c5b0a49f5004252eb6 172.16.0.201:6379
   slots: (0 slots) slave
   replicates 4dd6c1fecbbe4527e7d0de61b655e8b74b411e4c
S: e293d25881c3cf6db86034cd9c26a1af29bc585a 172.16.0.72:6379
   slots: (0 slots) slave
   replicates 8fdc7aa28a6217b049a2265b87bff9723f202af0
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

驗證 Redis Cluster

我們可以採用 cluster info 命令檢視 Redis Cluster 的配置資訊和 Cluster 中的成員節點,以驗證叢集是否建立成功。

$ kubectl exec -it redis-cluster-0 -c redis -n redis -- redis-cli cluster info 
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:206
cluster_stats_messages_pong_sent:210
cluster_stats_messages_sent:416
cluster_stats_messages_ping_received:205
cluster_stats_messages_pong_received:206
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:416

部署測試用客戶端

我們部署一個客戶端,以用於傳送測試命令:

$ kubectl apply -f k8s/redis-client.yaml -n redis
deployment.apps/redis-client created

通過 Istio 下發 Redis Cluster 相關的 Envoy 配置

在下面的步驟中,我們將通過 Istio 向 Envoy Sidecar 下發 Redis Cluster 相關配置,以在無需改動客戶端的情況下啟用 Redis Cluster 的高階功能,包括資料分片、讀寫分離和流量映象。

建立 Envoy Redis Cluster

Envoy 提供了 "envoy.clusters.redis" 型別的 Envoy Cluster 來連線後端的 Redis Cluster,Envoy 會通過該 Cluster 獲取後端 Redis Cluster 的拓撲結構,包括有多少個分片(shard),每個分片負責哪些 slot,以及分片中包含哪些節點,以將來自客戶端的請求分發到正確的 Redis 節點上。

採用 EnvoyFilter 來建立所需的 Envoy Redis Cluster:

$ kubectl apply -f istio/envoyfilter-custom-redis-cluster.yaml
envoyfilter.networking.istio.io/custom-redis-cluster created

建立 Envoy Redis Proxy

Istio 預設下發的 LDS 中配置的是 TCP proxy filter,我們需要將其替換為 Redis Proxy filter。

由於 1.7.3 中尚不支援 EnvoyFilter 的 "REPLACE" 操作,我們首先需要更新 EnvoyFilter 的 CRD 定義,然後才能建立該 EnvoyFilter:

$ kubectl apply -f istio/envoyfilter-crd.yaml 
customresourcedefinition.apiextensions.k8s.io/envoyfilters.networking.istio.io configured

採用 EnvoyFilter 來將 TCP proxy filter 替換為 Redis Proxy filter,以使 Envoy 可以代理來自客戶端的 Redis 操作請求:

$ sed -i .bak "s/\${REDIS_VIP}/`kubectl get svc redis-cluster -n redis -o=jsonpath='{.spec.clusterIP}'`/" istio/envoyfilter-redis-proxy.yaml
$ kubectl apply -f istio/envoyfilter-redis-proxy.yaml
envoyfilter.networking.istio.io/add-redis-proxy created

驗證 Redis Cluster 功能

現在一切就緒,下面我們來驗證 Redis Cluster 的各項功能。

Redis 資料分片

我們通過 Istio 將 EnvoyFilter 中定義的配置下發到 Envoy 後,Envoy 就能夠自動發現後端 Redis Cluster 的拓撲結構,並根據客戶端請求中的 key 將請求自動分發到 Redis Cluster 中正確的節點上。

根據前面建立 Redis Cluster 步驟中的命令列輸出,我們可以看出該 Redis Cluster 的拓撲結構:Cluster 中有三個分片,每個分片中有一個 Master 節點,一個 Slave(Replica) 節點。客戶端通過和其部署在同一個 Pod 中的 Envoy Proxy 訪問 Redis Cluster,如下圖所示:

Redis Cluster 中各個分片的 Master 和 Slave 節點地址:

Shard[0] Master[0]  redis-cluster-0 172.16.0.138:6379   replica  redis-cluster-4 172.16.0.72:6379  -> Slots 0 - 5460 
Shard[1] Master[1]  redis-cluster-1 172.16.1.52:6379    replica  redis-cluster-5 172.16.0.201:6379 -> Slots 5461 - 10922
Shard[2] Master[2]  redis-cluster-2 172.16.1.53:6379    replica  redis-cluster-3 172.16.0.139:6379 -> Slots 10923 - 16383

備註:如果你在自己的 K8s cluster 中部署該示例,那麼 Redis Cluster 中各個節點的 IP 地址和拓撲結構可能稍有不同,但基本結構應該是類似的。

我們嘗試從客戶端向 Rdeis Cluster 傳送一些不同 key 的 set 請求:

$ kubectl exec -it `kubectl get pod -l app=redis-client -n redis -o jsonpath="{.items[0].metadata.name}"` -c redis-client -n redis -- redis-cli -h redis-cluster
redis-cluster:6379> set a a
OK
redis-cluster:6379> set b b
OK
redis-cluster:6379> set c c
OK
redis-cluster:6379> set d d
OK
redis-cluster:6379> set e e
OK
redis-cluster:6379> set f f
OK
redis-cluster:6379> set g g
OK
redis-cluster:6379> set h h
OK

從客戶端來看,所有的請求都成功了,我們可以使用 scan 命令在伺服器端檢視各個節點中的資料:

檢視分片 Shard[0] 中的資料,master 節點是 redis-cluster-0 slave 節點是 redis-cluster-4。

$ kubectl exec redis-cluster-0 -c redis -n redis -- redis-cli --scan
b
f
$ kubectl exec redis-cluster-4 -c redis -n redis -- redis-cli --scan
f
b

檢視分片 Shard[1] 中的資料,master 節點是 redis-cluster-1 slave 節點是 redis-cluster-5。

$ kubectl exec redis-cluster-1 -c redis -n redis -- redis-cli --scan
c
g
$ kubectl exec redis-cluster-5 -c redis -n redis -- redis-cli --scan
g
c

檢視分片 Shard[2] 中的資料,master 節點是 redis-cluster-2 slave 節點是 redis-cluster-3。

$ kubectl exec redis-cluster-2 -c redis -n redis -- redis-cli --scan
a
e
d
h
$ kubectl exec redis-cluster-3 -c redis -n redis -- redis-cli --scan
h
e
d
a

從上面的驗證結果中可以看到,客戶端設定的資料被分發到了 Redis Cluster 中的三個分片中。該資料分發過程是由 Envoy Redis Proxy 自動實現的,客戶端並不感知後端的 Redis Cluster,對客戶端而言,和該 Redis Cluster 的互動與和一個單一 Redis 節點的互動是相同的。

採用該方法,我們可以在應用業務規模逐漸擴張,單一 Redis 節點壓力過大時,將系統中的 Redis 從單節點無縫遷移到叢集模式。在叢集模式下,不同 key 的資料被快取在不同的資料分片中,我們可以增加分片中 Replica 節點的數量來對一個分片進行擴容,也可以增加分片個數來對整個叢集進行擴充套件,以應對由於業務不斷擴充套件而增加的資料壓力。由於 Envoy 可以感知 Redis Cluster 叢集拓撲,資料的分發由 Envoy 完成,整個遷移和擴容過程無需客戶端,不會影響到線上業務的正常執行。

Redis 讀寫分離

在一個 Redis 分片中,通常有一個 Master 節點,一到多個 Slave(Replica)節點,Master 節點負責寫操作,並將資料變化同步到 Slave 節點。當來自應用的讀操作壓力較大時,我們可以在分片中增加更多的 Replica,以對讀操作進行負載分擔。Envoy Redis Rroxy 支援設定不同的讀策略:

  • MASTER: 只從 Master 節點讀取資料,當客戶端要求資料強一致性時需要採用該模式。該模式對 Master 壓力較大,在同一個分片內無法採用多個節點對讀操作進行負載分擔。
  • PREFER_MASTER: 優先從 Master 節點讀取資料,當 Master 節點不可用時,從 Replica 節點讀取。
  • REPLICA: 只從 Replica 節點讀取資料,由於 Master 到 Replica 的資料複製過程是非同步執行的,採用該方式有可能讀取到過期的資料,因此適用於客戶端對資料一致性要求不高的場景。該模式下可以採用多個 Replica 節點來分擔來自客戶端的讀負載。
  • PREFER_REPLICA: 優先從 Replica 節點讀取資料,當 Replica 節點不可用時,從 Master 節點讀取。
  • ANY: 從任意節點讀取資料。

在前面下發的 EnvoyFilter 中,我們將 Envoy Redis Proxy 的讀策略設定為了 "REPLICA", 因此客戶端的讀操作應該只會被髮送到 Replica 節點。讓我們使用下面的命令來驗證讀寫分離的策略:

通過客戶端發起一系列 key 為 "b" 的 getset 操作:

$ kubectl exec -it `kubectl get pod -l app=redis-client -n redis -o jsonpath="{.items[0].metadata.name}"` -c redis-client -n redis -- redis-cli -h redis-cluster

redis-cluster:6379> get b
"b"
redis-cluster:6379> get b
"b"
redis-cluster:6379> get b
"b"
redis-cluster:6379> set b bb
OK
redis-cluster:6379> get b
"bb"
redis-cluster:6379> 

在前面的 Redis Cluster 拓撲中,我們已經得知 key "b" 屬於 Shard[0] 這個分片。我們可以通過命令 redis-cli monitor 檢視該分片中 Master 和 Replica 節點中收到的命令。

Master 節點:

$ kubectl exec redis-cluster-0 -c redis -n redis -- redis-cli monitor

Slave 節點:

$ kubectl exec redis-cluster-4 -c redis -n redis -- redis-cli monitor

從下圖中可以看到,所有 get 請求都被 Envoy 傳送到了 Replica 節點上。

Redis 流量映象

Envoy Redis Proxy 支援流量映象,即將客戶端傳送的請求同時傳送到一個映象 Redis 伺服器/叢集上。流量映象是一個非常有用的功能,我們可以使用流量映象將生產環境中的線上資料匯入到測試環境中,以使用線上資料對應用進行儘可能真實的模擬測試,同時又不會影響到線上使用者的正常使用。

我們建立一個單節點的 Redis 節點,用做映象伺服器:

$ kubectl apply -f k8s/redis-mirror.yaml -n redis 
deployment.apps/redis-mirror created
service/redis-mirror created

採用 EnvoFilter 來啟用映象策略:

$ sed -i .bak "s/\${REDIS_VIP}/`kubectl get svc redis-cluster -n redis -o=jsonpath='{.spec.clusterIP}'`/" istio/envoyfilter-redis-proxy-with-mirror.yaml
$ kubectl apply -f istio/envoyfilter-redis-proxy-with-mirror.yaml
envoyfilter.networking.istio.io/add-redis-proxy configured

通過客戶端發起一系列 key 為 "b" 的 getset 操作:

$ kubectl exec -it `kubectl get pod -l app=redis-client -n redis -o jsonpath="{.items[0].metadata.name}"` -c redis-client -n redis -- redis-cli -h redis-cluster
redis-cluster:6379> get b
"b"
redis-cluster:6379> get b
"b"
redis-cluster:6379> get b
"b"
redis-cluster:6379> set b bb
OK
redis-cluster:6379> get b
"bb"
redis-cluster:6379> set b bbb
OK
redis-cluster:6379> get b
"bbb"
redis-cluster:6379> get b
"bbb"

可以通過命令 redis-cli monitor 分別檢視 Master、Replica 和映象節點中收到的命令。

Master 節點:

$ kubectl exec redis-cluster-0 -c redis -n redis -- redis-cli monitor

Slave 節點:

$ kubectl exec redis-cluster-4 -c redis -n redis -- redis-cli monitor

映象 節點:

$ kubectl exec -it `kubectl get pod -l app=redis-mirror -n redis -o jsonpath="{.items[0].metadata.name}"` -c redis-mirror -n redis -- redis-cli monitor

從下圖中可以看到,所有 set 請求都被 Envoy 傳送到了一份映象節點上。

實現原理

在上面的步驟中,我們在 Istio 中建立了兩個 EnvoyFilter 配置物件。這兩個 EnvoyFilter 修改了 Envoy 代理的配置,主要包括兩部分內容:Redis Proxy Network Filter 配置和 Redis Cluster 配置。

下面的 EnvoyFilter 替換了 Pilot 為 Redis Service 建立的 Listener 中的 TCP Proxy Network Filter,將其替換為一個 "type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy" 型別的 Network Filter。 該 Redis Proxy 的預設路由指向 "custom-redis-cluster",並且配置了讀寫分離策略和流量映象策略。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: add-redis-proxy
  namespace: istio-system
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      listener:
        name: ${REDIS_VIP}_6379             # Replace REDIS_VIP with the cluster IP of "redis-cluster service
        filterChain:
          filter:
            name: "envoy.filters.network.tcp_proxy"
    patch:
      operation: REPLACE
      value:
        name: envoy.redis_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy
          stat_prefix: redis_stats
          prefix_routes:
            catch_all_route:
              request_mirror_policy:            # Send requests to the mirror cluster
              - cluster: outbound|6379||redis-mirror.redis.svc.cluster.local
                exclude_read_commands: True     # Mirror write commands only:
              cluster: custom-redis-cluster
          settings:
            op_timeout: 5s
            enable_redirection: true
            enable_command_stats: true
            read_policy: REPLICA               # Send read requests to replica

下面的 EnvoyFilter 在 Pilot 下發的 CDS 中建立了一個 "envoy.clusters.redis" 型別的 Cluster: "custom-redis-cluster",該 Cluster 會採用 CLUSTER SLOTS 命令 向 Redis 叢集中的一個隨機節點查詢叢集的拓撲結構,並在本地儲存該拓撲結構,以將來自客戶端的請求分發到叢集中正確的 Redis 節點上。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-redis-cluster
  namespace: istio-system
spec:
  configPatches:
  - applyTo: CLUSTER
    patch:
      operation: INSERT_FIRST
      value:
        name: "custom-redis-cluster"
        connect_timeout: 0.5s
        lb_policy: CLUSTER_PROVIDED
        load_assignment:
          cluster_name: custom-redis-cluster
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: redis-cluster-0.redis-cluster.redis.svc.cluster.local
                    port_value: 6379
            - endpoint:
                address:
                  socket_address:
                    address: redis-cluster-1.redis-cluster.redis.svc.cluster.local
                    port_value: 6379
            - endpoint:
                address:
                  socket_address:
                    address: redis-cluster-2.redis-cluster.redis.svc.cluster.local
                    port_value: 6379
            - endpoint:
                address:
                  socket_address:
                    address: redis-cluster-3.redis-cluster.redis.svc.cluster.local
                    port_value: 6379
            - endpoint:
                address:
                  socket_address:
                    address: redis-cluster-4.redis-cluster.redis.svc.cluster.local
                    port_value: 6379
            - endpoint:
                address:
                  socket_address:
                    address: redis-cluster-5.redis-cluster.redis.svc.cluster.local
                    port_value: 6379
        cluster_type:
          name: envoy.clusters.redis
          typed_config:
            "@type": type.googleapis.com/google.protobuf.Struct
            value:
              cluster_refresh_rate: 5s
              cluster_refresh_timeout: 3s
              redirect_refresh_interval: 5s
              redirect_refresh_threshold: 5

小結

本文介紹瞭如何使用 Envoy 為微服務應用提供客戶端無感知的 Redis 資料分片,以及如何通過 Istio 來統一管理系統中多個 Envoy 代理的 Redis Cluster 配置。我們可以看到,採用 Istio 和 Envoy 可以大大簡化客戶端使用 Redis Cluster 的編碼和配置工作,並且可以線上修改 Redis Cluster 的運維策略,實現讀寫分離、流量映象等高階流量管理。當然,引入 Istio 和 Envoy 並未減少整個系統的複雜度,而是將 Redis Cluster 維護的工作從各個分散的應用程式碼中集中到了服務網格基礎設施層。對應廣大應用開放者來說,其業務價值主要來自於應用程式碼,將大量精力投入此類基礎設施是不太划算的。建議直接採用騰訊雲上的雲原生 Service Mesh 服務 TCM(Tencent Cloud Mesh),為微服務應用快速引入 Service Mesh 的流量管理和服務治理能力,而無需再關注 Service Mesh 基礎設施自身的安裝、維護、升級等事項。

參考文件

【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多幹貨!!

相關文章