Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

Redis는 마이크로 서비스 아키텍처에서 널리 사용되는 고성능 키-값 스토리지 시스템입니다. Redis 클러스터 모드에서 제공하는 고급 기능을 사용하려면 클라이언트 코드를 변경해야하므로 애플리케이션 업그레이드 및 유지 관리에 약간의 어려움이 있습니다. Istio 및 Envoy를 사용하면 클라이언트 코드를 수정하지 않고 클라이언트 인식 Redis 클러스터 데이터 샤딩을 구현하고 읽기-쓰기 분리 및 트래픽 미러링과 같은 고급 트래픽 관리 기능을 제공 할 수 있습니다.

Redis 클러스터

Redis의 일반적인 용도는 데이터 캐시입니다. 애플리케이션 서버와 데이터베이스 서버 사이에 Redis 캐시 계층을 추가하면 애플리케이션 서버가 데이터베이스에 대한 많은 읽기 작업을 줄일 수 있으며, 응답 속도가 느려지거나 과도한 압력을받는 데이터베이스 서버의 가동 중지 시간까지 피할 수 있으며 전체 시스템의 견고성을 크게 향상시킬 수 있습니다. 데이터 캐시로서 Redis의 원리가 그림에 나와 있습니다.

Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

소규모 시스템에서 위 그림에 표시된 단일 Redis는 캐시 계층의 기능을 잘 구현할 수 있습니다. 시스템에 캐시해야하는 데이터 양이 많으면 하나의 Redis 서버가 모든 애플리케이션 서버의 캐싱 요구 사항을 충족 할 수 없습니다. 동시에 단일 Redis 인스턴스가 실패하면 많은 수의 읽기 요청이 백엔드 데이터베이스 서버로 직접 전송되어 일시적인 데이터베이스 서버가 발생합니다. 과도한 압력은 시스템의 안정성에 영향을 미칩니다. Redis 클러스터사용 하여 캐시 된 데이터를 조각화하고 다른 데이터를 다른 Redis 조각에 넣어 Redis 캐시 계층의 용량을 개선 할 수 있습니다. 각 Redis 샤드에서 여러 복제본 노드를 사용하여 캐시 된 읽기 요청의로드를 공유하고 Redis의 고 가용성을 달성 할 수도 있습니다. Redis Cluster를 사용하는 시스템은 다음과 같습니다.

Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

그림에서 볼 수 있듯이 Redis 클러스터 모드에서 클라이언트는 클러스터의 조각화 규칙에 따라 클러스터의 다른 Redis 노드에 서로 다른 키의 읽기 및 쓰기 작업을 보내야하므로 클라이언트는 Redis 클러스터의 토폴로지를 이해해야합니다. 이로 인해 클라이언트를 수정하지 않고 Redis 독립 노드 모드를 사용하는 애플리케이션을 Redis 클러스터로 원활하게 마이그레이션 할 수 없습니다. 또한 클라이언트가 Redis Cluster의 내부 토폴로지를 이해해야하기 때문에 클라이언트 코드와 Redis Cluster 운영 및 유지 관리의 결합으로 이어질 것입니다. 예를 들어 읽기-쓰기 분리 또는 트래픽 미러링을 달성하려면 각 클라이언트의 코드를 수정하고 재배포해야합니다. .

이 시나리오에서 우리는 애플리케이션 서버와 Redis 클러스터 사이에 Envoy 프록시 서버를 배치 할 수 있으며 Envoy는 애플리케이션에서 발행 한 캐시 읽기 및 쓰기 요청을 올바른 Redis 노드로 라우팅하는 일을 담당합니다. 마이크로 서비스 시스템에는 캐시 서버에 액세스해야하는 많은 애플리케이션 프로세스가 있습니다. 단일 실패 지점 및 성능 병목 현상을 방지하기 위해 사이드카 형태로 각 애플리케이션 프로세스에 Envoy 프록시를 배포합니다. 동시에 이러한 프록시 관리를 단순화하기 위해 다음 그림과 같이 Istio를 제어 플레인으로 사용하여 모든 Envoy 프록시를 균일하게 구성 할 수 있습니다.

Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

이 기사의 후속 부분에서는 Istio 및 Envoy를 통해 Redis Cluster를 관리하고 클라이언트에 민감하지 않은 데이터 파티셔닝을 실현하고 읽기-쓰기 분리 및 트래픽 미러링과 같은 고급 라우팅 전략을 구현하는 방법을 소개합니다.

Istio 배포

Redis 프로토콜은 이미 Pilot에서 지원되지만 기능이 약합니다. Redis 프록시에 대한 기본 경로 만 구성 할 수 있으며 Redis 클러스터 모드는 지원하지 않습니다. Redis 필터 데이터 조각화, 읽기-쓰기 분리, 트래픽 미러링 및 기타 고급 트래픽 관리를 실현하는 것은 불가능합니다. 풍모. Istio가 Redis Cluster 관련 구성을 Envoy Sidecar에 전달할 수 있도록 EnvoyFilter의 "REPLCAE"작업을 지원하도록 EnvoyFilter 구성 관련 코드를 수정했습니다. EnvoyFilter 패치에 대한 수정 된 PR Implement REPLACE 작업이 Istio 커뮤니티에 제출되어 메인 브랜치에 병합되었으며 Istio의 후속 버전에서 릴리스 될 예정입니다.

이 기사를 작성하는 시점에서 최신 Istio 릴리스 버전 1.7.3은 아직이 PR을 통합하지 않았습니다. 그래서 저는 EnvoyFilter의 "REPLACE"작업을 활성화하기 위해 Pilot 이미지를 만들었습니다. Istio를 설치할 때 다음 명령 줄에 표시된 것처럼 istioctl 명령에 파일럿 이미지를 지정해야합니다.

$ 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 클러스터 배포

제발 다음 예에서 사용 된 관련 코드 다운로드 에서 https://github.com/zhaohuabing/istio-redis-culster를 :

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

이 예제에서는 "redis"네임 스페이스를 만들어 Redis 클러스터를 배포합니다.

$ 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 클러스터 생성

위의 단계에서 Statefulset을 사용하여 6 개의 Redis 노드를 배포했지만 현재이 6 개의 노드는 여전히 서로 독립적이며 클러스터를 형성하지 않습니다. 여기에서 Redis cluster create명령 을 사용하여 이러한 노드를 Redis 클러스터로 만듭니다.

$ 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 info명령을 사용하여 클러스터가 성공적으로 생성되었는지 확인하기 위해 구성 정보와 Redis 클러스터 클러스터 구성원 노드를 볼 수 있습니다 .

$ 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를 통해 Redis Cluster 관련 구성을 Envoy Sidecar로 전송하여 데이터 조각화, 읽기-쓰기 분리 및 트래픽 미러링을 포함하여 클라이언트를 변경하지 않고 Redis Cluster의 고급 기능을 활성화합니다.

Envoy Redis 클러스터 생성

Envoy는 백엔드 Redis 클러스터에 연결하기 위해 "envoy.clusters.redis"유형의 Envoy 클러스터를 제공합니다. Envoy는 클러스터를 통해 백엔드 Redis 클러스터의 토폴로지 (각 샤드가 담당하는 샤드 수 포함)를 얻습니다. 클라이언트에서 올바른 Redis 노드로 요청을 분배하기 위해 샤드에 포함 된 슬롯 및 노드.

EnvoyFilter를 사용하여 필요한 Envoy Redis 클러스터를 만듭니다.

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

Envoy Redis 프록시 생성

Istio의 기본 LDS는 TCP 프록시 필터로 구성되어 있으므로 Redis 프록시 필터로 교체해야합니다.

EnvoyFilter의 "REPLACE"작업은 아직 1.7.3에서 지원되지 않으므로 EnvoyFilter를 만들기 전에 먼저 EnvoyFilter의 CRD 정의를 업데이트해야합니다.

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

Envoy가 클라이언트의 Redis 작업 요청을 프록시 할 수 있도록 EnvoyFilter를 사용하여 TCP 프록시 필터를 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 클러스터 기능 확인

이제 모든 준비가 완료되었으므로 Redis Cluster의 다양한 기능을 확인해 보겠습니다.

Redis 데이터 샤딩

EnvoyFilter에 정의 된 구성을 Istio를 통해 Envoy로 전송 한 후 Envoy는 백엔드 Redis 클러스터의 토폴로지를 자동으로 검색하고 클라이언트 요청의 키에 따라 Redis 클러스터의 올바른 노드에 요청을 자동으로 배포 할 수 있습니다.

Redis 클러스터를 생성하는 이전 단계의 명령 줄 출력에 따르면 Redis 클러스터의 토폴로지를 볼 수 있습니다. 클러스터에는 세 개의 샤드가 있고 각 샤드는 마스터 노드와 슬레이브 (복제본) 노드가 있습니다. 클라이언트는 다음 그림과 같이 동일한 포드에 배포 된 Envoy 프록시를 통해 Redis 클러스터에 액세스합니다.

Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

Redis 클러스터에있는 각 샤드의 마스터 및 슬레이브 노드 주소 :

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 클러스터에 배포하는 경우 Redis 클러스터에있는 각 노드의 IP 주소 및 토폴로지는 약간 다를 수 있지만 기본 구조는 비슷해야합니다.

클라이언트 set요청 에서 Rdeis Cluster에 여러 가지 키를 보내려고 합니다.

$ 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]의 데이터를 봅니다. 마스터 노드는 redis-cluster-0이고 슬레이브 노드는 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 Shard [1]의 데이터를 확인합니다. 마스터 노드는 redis-cluster-1, 슬레이브 노드는 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

샤드 [2]의 데이터를 확인하고 마스터 노드는 redis-cluster-2이고 슬레이브 노드는 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 클러스터의 세 개의 샤드에 배포됩니다. 데이터 배포 프로세스는 Envoy Redis 프록시에 의해 자동으로 구현됩니다. 클라이언트는 백엔드 Redis 클러스터를 인식하지 않습니다. 클라이언트의 경우 Redis 클러스터와의 상호 작용은 단일 Redis 노드와의 상호 작용과 동일합니다.

이 방법을 사용하면 애플리케이션 비즈니스의 규모가 점진적으로 확장되고 단일 Redis 노드에 대한 압력이 너무 높을 때 시스템의 Redis를 단일 노드에서 클러스터 모드로 원활하게 마이그레이션 할 수 있습니다. 클러스터 모드에서는 서로 다른 키의 데이터가 서로 다른 데이터 샤드에 캐시됩니다. 샤드의 복제본 노드 수를 늘려 샤드를 확장하거나 샤드 수를 늘려 전체 클러스터를 확장 할 수 있습니다. , 사업 확장으로 인한 데이터 압력 증가에 대처하기 위해. Envoy는 Redis 클러스터 클러스터 토폴로지를 인식하고 Envoy에서 데이터 배포를 완료하므로 전체 마이그레이션 및 확장 프로세스에 클라이언트가 필요하지 않으며 온라인 비즈니스의 정상적인 운영에 영향을 미치지 않습니다.

Redis 읽기-쓰기 분리

Redis 샤드에는 일반적으로 하나의 마스터 노드와 하나 이상의 슬레이브 (복제본) 노드가 있으며 마스터 노드는 작업을 작성하고 데이터 변경 사항을 슬레이브 노드에 동기화하는 역할을합니다. 애플리케이션의 읽기 작업 압력이 높으면 샤드에 복제본을 더 추가하여 읽기 작업의로드를 공유 할 수 있습니다. Envoy Redis Rroxy는 다양한 읽기 전략 설정을 지원합니다.

  • MASTER : 마스터 노드에서만 데이터를 읽습니다.이 모드는 클라이언트가 강력한 데이터 일관성을 요구할 때 필요합니다. 이 모드는 마스터에 많은 부담을 주므로 동일한 샤드에서 읽기 작업을 공유하는 데 여러 노드를 사용할 수 없습니다.
  • PREFER_MASTER : 먼저 마스터 노드에서 데이터를 읽고 마스터 노드를 사용할 수없는 경우 Replica 노드에서 데이터를 읽습니다.
  • REPLICA : Replica 노드에서만 데이터 읽기 Master에서 Replica로 데이터 복제 과정이 비동기식으로 수행되기 때문에 이러한 방식으로 만료 된 데이터를 읽을 수 있으므로 클라이언트의 데이터 일관성 요구 사항이 높지 않은 시나리오에 적합합니다. 이 모드에서는 여러 복제본 노드를 사용하여 클라이언트의 읽기로드를 공유 할 수 있습니다.
  • PREFER_REPLICA : 먼저 Replica 노드에서 데이터를 읽고 Replica 노드를 사용할 수 없을 때 마스터 노드에서 읽습니다.
  • ANY : 모든 노드에서 데이터를 읽습니다.

앞서 발행 한 EnvoyFilter에서 Envoy Redis Proxy의 읽기 전략을 "REPLICA"로 설정 했으므로 클라이언트 읽기 작업은 Replica 노드로만 전송되어야합니다. 다음 명령을 사용하여 읽기-쓰기 분리 전략을 확인하겠습니다.

일련의 주요 클라이언트를 시작하면 다음 get과 같은 set작업 이 "b"됩니다 .

$ 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 클러스터 토폴로지에서 키 "b"가 Shard [0] 샤드에 속한다는 것을 배웠습니다. redis-cli monitor받은 명령 슬라이스 마스터 및 복제본 노드를 보도록 명령 수 있습니다 .

마스터 노드 :

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

슬레이브 노드 :

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

그림에서 볼 수 있듯이 모든 get요청은 Replica Envoy 노드로 전송됩니다.

Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

Redis 트래픽 미러링

Envoy Redis 프록시는 트래픽 미러링을 지원합니다. 즉, 클라이언트에서 보낸 요청이 미러링 된 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

일련의 주요 클라이언트를 시작하면 다음 get과 같은 set작업 이 "b"됩니다 .

$ 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보기에 의해 명령 마스터, 복제본 및 미러링 된 노드가 각각 수신됩니다.

마스터 노드 :

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

슬레이브 노드 :

$ 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 a mirror 노드로 전송됩니다.

Istio에서 Redis 클러스터의 데이터 샤딩, 읽기-쓰기 분리 및 트래픽 미러링을 실현합니다.

구현 원칙

위의 단계에서 Istio에 두 개의 EnvoyFilter 구성 개체를 만들었습니다. 이 두 EnvoyFilter는 주로 Redis 프록시 네트워크 필터 구성과 Redis 클러스터 구성의 두 부분을 포함하는 Envoy 프록시의 구성을 수정합니다.

아래 EnvoyFilter는 Pilot for Redis 서비스에서 만든 리스너의 TCP 프록시 네트워크 필터를 대체하고 "type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy"유형의 네트워크 필터로 대체합니다. 이 Redis 프록시의 기본 경로는 "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"유형의 클러스터를 생성합니다. "custom-redis-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 클러스터 구성을 균일하게 관리하는 방법을 설명합니다. Istio 및 Envoy를 사용하면 Redis Cluster를 사용하여 클라이언트의 코딩 및 구성을 크게 단순화 할 수 있으며 Redis Cluster의 운영 및 유지 관리 전략을 온라인으로 수정하여 읽기-쓰기 분리 및 트래픽 미러링과 같은 고급 트래픽 관리를 달성 할 수 있음을 알 수 있습니다. 물론 Istio와 Envoy의 도입으로 전체 시스템의 복잡성이 줄어들지는 않았지만 분산 된 애플리케이션 코드에서 서비스 그리드 인프라 계층까지 Redis Cluster의 유지 관리가 집중되었습니다. 대다수의 애플리케이션 개발자에게 해당하는 비즈니스 가치는 주로 애플리케이션 코드에서 비롯되며 이러한 인프라에 많은 에너지를 투자하는 것은 비용 효율적이지 않습니다. 서비스 메시 인프라 자체의 설치, 유지 관리 및 업그레이드에주의를 기울이지 않고 마이크로 서비스 애플리케이션을위한 Service Mesh의 트래픽 관리 및 서비스 거버넌스 기능을 빠르게 도입하려면 Tencent Cloud에서 클라우드 네이티브 서비스 메시 서비스 TCM (Tencent Cloud Mesh)을 직접 채택하는 것이 좋습니다. 그리고 다른 문제.

참조 문서

추천

출처blog.51cto.com/14120339/2542940