1. K8s를 사용하는 이유
1. 리소스 격리
현재 Redis 클러스터는 리소스 활용도를 높이고 비용을 절감하기 위해 여러 비즈니스 라인의 Redis 클러스터를 혼합합니다. CPU 리소스 격리가 없기 때문에 특정 Redis 노드의 CPU 사용량이 너무 높아서 다른 Redis 클러스터 노드가 CPU 리소스를 놓고 경쟁하여 지연 지터가 발생하는 경우가 종종 있습니다. 다양한 클러스터가 혼합되어 있기 때문에 이러한 유형의 문제는 신속하게 찾기가 어렵고 운영 및 유지 관리 효율성에 영향을 미칩니다. K8s 컨테이너화된 배포는 CPU 요청 및 CPU 제한을 지정할 수 있어 리소스 경합을 피하면서 리소스 활용도를 향상시킵니다.
2. 자동 배포
현재 물리적 머신에서 Redis 클러스터를 배포하는 프로세스는 매우 번거롭습니다. 무료 리소스가 있는 머신을 찾고, 많은 구성 파일을 수동으로 수정한 다음, 노드를 배포해야 합니다. 마지막으로 redis_trib 도구를 사용하여 클러스터를 생성하면 새 클러스터를 초기화하는 데 종종 한두 시간 정도 걸립니다.
K8s는 StatefulSet을 통해 Redis 클러스터를 배포하고 configmap을 사용하여 구성 파일을 관리합니다. 새 클러스터를 배포하는 데 몇 분밖에 걸리지 않아 운영 및 유지 관리 효율성이 크게 향상됩니다.
2. K8s
클라이언트는 LVS의 VIP를 통해 통합 액세스되고 Redis Proxy를 통해 Redis 클러스터 클러스터에 서비스 요청을 전달합니다. 여기서는 요청을 전달하기 위해 Redis Proxy를 소개합니다.
1. Redis 클러스터 배포 방법
Redis는 StatefulSet으로 배포되므로 노드의 RDB/AOF를 분산 스토리지에 유지할 수 있는 StatefulSet을 선택하는 것이 가장 합리적입니다. 노드가 다시 시작되고 다른 머신으로 이동하면 마운트된 PVC(PertantVolumeClaim)를 통해 원본 RDB/AOF를 얻어 데이터를 동기화할 수 있습니다.
Ceph 블록 서비스는 우리가 선택한 영구 스토리지 PV(PerciousVolume)입니다. Ceph의 읽기 및 쓰기 성능은 로컬 하드 디스크의 성능보다 떨어지므로 읽기 및 쓰기 지연이 100~200밀리초 증가합니다. Redis의 RDB/AOF 쓰기는 비동기식이므로 분산 스토리지의 읽기 및 쓰기 대기 시간은 서비스에 영향을 미치지 않습니다.
2. 프록시 선택
오픈 소스 Redis Proxy가 많이 있습니다. 일반적인 오픈 소스 Redis Proxy는 다음과 같습니다.
Redis 클러스터를 관리하기 위해 Redis Cluster를 계속 사용하기를 희망하므로 Codis와 Twemproxy 더 이상 고려되지 않습니다. redis-cluster-proxy는 Redis Cluster 프로토콜을 지원하는 Redis 버전 6.0에서 공식적으로 출시된 Proxy입니다. 그러나 현재 안정적인 버전이 없어 당분간 대규모로 적용할 수 없습니다.
유일한 대안은 Cerberus와 Predixy입니다. 다음은 K8s 환경에서 진행한 Cerberus와 Predixy의 성능 테스트 결과입니다.
테스트 환경
테스트 도구: redis-benchmark
Proxy CPU: 2 core
Client CPU: 2 core
Redis Cluster : 마스터 노드 3개, 노드당 CPU 1개
테스트 결과
Predixy는 동일한 작업 부하 및 구성에서 더 높은 QPS를 달성할 수 있으며 지연 시간도 Cerberus에 매우 가깝습니다. 전체적으로 Predixy의 성능은 Cerberus에 비해 33%~60% 높고, 데이터의 키/값이 클수록 Predixy의 장점이 더욱 뚜렷하므로 결국 Predixy를 선택했습니다.
비즈니스 및 K8s 환경에 적응하기 위해 온라인 출시 전 Predixy에 많은 변경을 가했으며 백엔드 Redis Cluster의 동적 전환, 블랙 및 화이트 목록, 비정상 작동 감사 등 많은 새로운 기능을 추가했습니다.
3. Proxy 배포 방법
Stateless 및 경량 배포 특성으로 인해 Proxy를 배포 방법으로 사용하고 로드 밸런싱(LB)을 통해 서비스를 제공하면 쉽게 동적 확장 및 축소가 가능합니다. 동시에 우리는 Redis 클러스터를 온라인으로 추가하고 전환할 수 있는 프록시용 백엔드 Redis 클러스터를 동적으로 전환하는 기능을 개발했습니다.
4. 프록시 자동 확장 및 축소 방법
K8s 기본 HPA(Horizontal Pod Autoscaler)를 사용하여 프록시의 동적 확장 및 축소를 구현합니다. 모든 프록시 포드의 평균 CPU 사용량이 특정 임계값을 초과하면 HPA가 자동으로 프록시의 복제본 수를 1씩 증가시킵니다. 그 후 LVS는 새 프록시 포드를 감지하고 트래픽의 일부를 차단합니다. CPU 사용량이 지정된 임계값을 초과하면 용량이 확장됩니다. 여전히 요구 사항을 충족하지 않으면 확장 논리가 계속 트리거됩니다. 그러나 확장이 성공한 후 5분 이내에는 CPU 사용량이 아무리 낮아지더라도 축소 논리가 트리거되지 않으므로 잦은 확장 및 축소가 클러스터 안정성에 미치는 영향을 피할 수 있습니다.
HPA는 클러스터의 최소(MINPODS) 및 최대(MAXPODS) 포드 수를 구성할 수 있습니다. 클러스터 부하가 아무리 낮더라도 MINPODS 미만의 포드 수로 축소되지는 않습니다. MINPODS와 MAXPODS의 가치를 결정하기 위해서는 고객이 실제 비즈니스 조건을 판단하는 것이 좋습니다.
3. 프록시를 사용하는 이유
1. Redis 포드를 다시 시작하면 IP가 변경될 수 있습니다
Redis 클러스터를 사용하는 Redis 클라이언트는 클라이언트가 다시 시작될 때 Redis 클러스터에 대한 입구를 찾기 위해 클러스터의 일부 IP 및 포트를 구성해야 합니다. 물리적 머신 클러스터에 배포된 Redis 노드의 경우 인스턴스가 다시 시작되거나 머신이 다시 시작되더라도 IP 및 포트는 변경되지 않고 클라이언트는 여전히 Redis 클러스터의 토폴로지를 찾을 수 있습니다. 그러나 K8s에 배포된 Redis 클러스터의 경우 Pod가 다시 시작될 때(원래 K8s 노드에서 다시 시작하더라도) IP가 변경되지 않고 유지된다는 보장이 없으므로 클라이언트가 다시 시작될 때 IP를 찾지 못할 수 있습니다. Redis 클러스터 입구.
클라이언트와 Redis 클러스터 사이에 프록시를 추가하면 Redis 클러스터 정보가 클라이언트로부터 보호됩니다. 프록시는 Redis 클러스터의 토폴로지 변경을 동적으로 감지할 수 있습니다. 클라이언트는 LVS의 IP:포트만 사용하면 됩니다. 요청 지점을 프록시로 전달하면 Redis 스마트 클라이언트 없이 Redis의 독립 실행형 버전을 사용하는 것처럼 Redis 클러스터를 사용할 수 있습니다.
2. Redis는 높은 연결 부하를 처리합니다
버전 6.0 이전에는 Redis가 대부분의 작업을 단일 스레드에서 처리했습니다. Redis 노드에 대한 연결이 많으면 Redis는 이러한 연결을 처리하기 위해 많은 CPU 리소스를 소비해야 하므로 지연 시간이 늘어납니다. Proxy를 사용하면 Proxy에 많은 수의 연결이 유지되고 Proxy와 Redis 인스턴스 간에는 소수의 연결만 유지됩니다. 이렇게 하면 Redis에 대한 부담이 줄어들고 연결 증가로 인한 Redis 지연 시간의 증가를 방지할 수 있습니다.
3. 클러스터 마이그레이션 및 전환에는 애플리케이션 재시작 필요
사용 중에 비즈니스가 성장함에 따라 Redis 클러스터의 데이터 볼륨이 계속 증가합니다. 각 노드의 데이터 볼륨이 너무 높으면 BGSAVE 시간이 발생합니다. 확장되어 클러스터 가용성이 감소합니다. 동시에 QPS가 증가하면 각 노드의 CPU 사용량도 증가합니다. 이 문제는 확장 클러스터를 추가하여 해결해야 합니다. 현재 Redis 클러스터의 수평 확장성은 그리 좋지 않으며 기본 슬롯 마이그레이션 솔루션은 매우 비효율적입니다. 새 노드를 추가한 후 Lettuce와 같은 일부 클라이언트는 보안 메커니즘으로 인해 새 노드를 인식할 수 없습니다. 또한 마이그레이션 시간은 전혀 예측할 수 없으며 마이그레이션 과정에서 문제가 발생하면 되돌릴 방법이 없습니다.
물리적 시스템 클러스터에 대한 현재 확장 계획은 다음과 같습니다.
요청 시 새 클러스터를 생성합니다.
동기화 도구를 사용하여 이전 클러스터의 데이터를 새 클러스터로 동기화합니다. 정확하다면 비즈니스와 통신하고 서비스를 다시 시작한 후 새 클러스터로 전환하세요.
전체 프로세스가 번거롭고 위험하며 비즈니스를 다시 시작해야 합니다.
Redis는 AUTH를 통해 인증 작업을 구현하며 클라이언트는 여전히 비밀번호를 저장해야 합니다. 프록시를 사용하면 클라이언트는 프록시 비밀번호를 통해서만 Redis에 액세스하면 되며 Redis 비밀번호를 알 필요가 없습니다. 또한 프록시는 FLUSHDB 및 CONFIG SET과 같은 작업을 제한하여 고객이 실수로 데이터를 지우거나 Redis 구성을 수정하는 것을 방지하여 시스템 보안을 크게 향상시킵니다.동시에 Redis는 감사 기능을 제공하지 않습니다. 프록시 서버에 고위험 작업에 대한 로깅 기능을 추가하여 전체 성능에 영향을 주지 않고 감사 기능을 제공합니다.
4. 프록시로 인한 문제
1. 하나의 홉으로 인한 지연
프록시는 클라이언트와 Redis 데이터에 액세스할 때 먼저 프록시에 액세스해야 합니다. 그런 다음 Redis에 액세스하면 홉이 하나 더 늘어나 지연이 늘어납니다. 테스트 결과에 따르면 홉을 1개 추가하면 지연 시간이 0.2~0.3ms 증가하지만 이는 일반적으로 기업에서는 허용되는 수준입니다.
2. Pod 드리프트로 인해 IP 변경이 발생합니다K8s에서는 배포를 통해 프록시가 구현되므로 노드 재시작으로 인한 IP 변경 문제도 있습니다. K8s LB 솔루션은 프록시의 IP 변경을 감지하고 LVS 트래픽을 다시 시작된 프록시로 동적으로 전환할 수 있습니다.
3. LVS로 인한 지연 시간아래 표에 표시된 테스트에서 다양한 데이터 길이의 가져오기/설정 작업으로 인해 발생하는 LVS 지연 시간은 0.1ms 미만입니다.
5. K8s가 제공하는 이점
1. 간편한 배포
운영 및 유지 관리 플랫폼을 통해 K8s API를 호출하여 클러스터를 배포하므로 운영 및 유지 관리 효율성이 크게 향상됩니다.
2. 포트 관리 문제 해결현재 물리적 시스템에 배포된 Xiaomi의 Redis 인스턴스는 포트로 구분되며, 오프라인 포트는 재사용할 수 없습니다. 즉, 회사 전체의 각 Redis 인스턴스에는 고유한 포트가 있습니다. . 현재 65,535개의 항만 중 40,000개 이상이 사용되었습니다. 현재 사업 발전률에 따르면 항만 자원은 2년 안에 고갈될 것입니다. K8s 배포를 통해 각 Redis 인스턴스에 해당하는 K8s Pod는 독립적인 IP를 갖게 되며, 포트 고갈 문제 및 복잡한 관리 문제가 발생하지 않습니다.
3. 낮은 고객 사용 기준애플리케이션의 경우 VIP에 연결하려면 비지능형 클라이언트의 독립형 버전만 사용해야 합니다. 이는 사용 임계값을 낮추고 번거롭고 복잡한 매개변수 설정을 방지합니다. VIP와 포트는 정적으로 고정되어 있으므로 애플리케이션은 Redis 클러스터의 토폴로지 자체를 처리할 필요가 없습니다.
4. 클라이언트 성능 향상
지능적이지 않은 클라이언트를 사용하면 클라이언트의 로드도 줄일 수 있습니다. 스마트 클라이언트는 요청을 보낼 Redis 노드를 결정하기 위해 클라이언트의 키를 해시해야 하기 때문입니다. QPS가 상대적으로 높습니다. 이 경우 클라이언트 컴퓨터의 CPU 리소스가 소비됩니다. 물론 클라이언트 애플리케이션 마이그레이션을 더 쉽게 만들기 위해 프록시가 스마트 클라이언트 프로토콜을 지원하도록 만들었습니다.
5. 동적 업그레이드 및 용량 확장
Proxy는 Redis 클러스터를 동적으로 추가하고 전환하는 기능을 지원하므로 Redis 클러스터의 클러스터 업그레이드 및 용량 확장 및 전환 프로세스가 비즈니스 종료를 전혀 인식할 수 없습니다. 예를 들어, 비즈니스 측면에서는 30노드 Redis 클러스터를 사용하고 있는데, 비즈니스 규모의 증가로 인해 데이터 볼륨과 QPS가 급격히 증가하여 클러스터 크기도 두 배로 커져야 합니다. 원래 물리적 시스템에서 용량을 확장하는 경우 다음 프로세스가 필요합니다.
리소스를 조정하고 60개 노드로 구성된 새 클러스터를 배포합니다.
현재 클러스터의 데이터를 다음으로 마이그레이션하도록 마이그레이션 도구를 수동으로 구성합니다.
데이터가 올바른지 확인한 후 비즈니스 당사자에게 Redis 클러스터 연결 풀 토폴로지를 수정하고 서비스를 다시 시작하도록 알립니다.
Redis Cluster는 온라인 확장을 지원하지만 확장 과정 중 슬롯 재배치가 온라인 비즈니스에 영향을 미치고 마이그레이션 시간도 통제할 수 없기 때문에 이 단계에서는 이 방법을 거의 사용하지 않으며 가끔씩만 사용하게 됩니다. 자원이 심각하게 부족할 때.
새로운 K8s 아키텍처에서 마이그레이션 프로세스는 다음과 같습니다.
API 인터페이스를 통해 한 번의 클릭으로 60개 노드의 새 클러스터를 생성합니다.
또한 API를 통해 한 번의 클릭으로 클러스터 동기화 도구를 생성합니다. 데이터를 새 클러스터로 마이그레이션하는 인터페이스
데이터가 올바른지 확인한 후 프록시에 명령을 보내 새 클러스터 정보를 추가하고 전환을 완료합니다.
전체 과정에서 비즈니스 종료를 전혀 인식하지 못합니다.
클러스터 업그레이드도 매우 편리합니다. 비즈니스 측에서 특정 지연 결함을 수용할 수 있으면 사용량이 적은 시간 동안 StatefulSet 롤링 업그레이드를 통해 달성할 수 있습니다. 비즈니스에서 지연 요구 사항이 있는 경우 새 클러스터를 생성하여 달성할 수 있습니다. 클러스터 및 데이터 마이그레이션.
6. 서비스 안정성 및 리소스 활용도 향상
K8s의 리소스 격리 기능을 사용하여 다양한 유형의 애플리케이션을 혼합 배포할 수 있습니다. 이는 자원 활용도를 향상시킬 뿐만 아니라 서비스 안정성도 보장합니다.
6. 문제 발생
1. Pod를 다시 시작하면 데이터가 손실됩니다.
K8s Pod에 문제가 발생하여 다시 시작하면 너무 빠른 다시 시작 속도로 인해 Redis 클러스터 클러스터가 삭제되기 전에 삭제됩니다. 포드가 다시 시작됩니다. 포드의 Redis가 슬레이브인 경우 아무런 영향을 미치지 않습니다. 그러나 Redis가 마스터이고 AOF가 없는 경우 다시 시작하면 원래 메모리 데이터가 모두 지워집니다. Redis는 이전에 저장된 RDB 파일을 다시 로드하지만 RDB 파일은 실시간 데이터가 아닙니다. 나중에 슬레이브는 자신의 데이터를 이전 RDB 파일의 데이터 미러와 동기화하므로 일부 데이터가 손실됩니다.
StatefulSet을 배포할 때 Pod 이름은 특정 명명 형식을 따르고 고정된 숫자를 포함하므로 StatefulSet은 상태 저장 서비스입니다. Redis 클러스터를 초기화할 때 인접한 번호가 매겨진 Pod를 마스터-슬레이브 관계로 설정합니다. Pod를 다시 시작할 때 Pod 이름을 통해 해당 슬레이브를 확인합니다. Pod를 다시 시작하기 전에 슬레이브 노드에 클러스터 장애 조치 명령을 보내 살아남은 슬레이브 노드가 마스터가 되도록 합니다. 이러한 방식으로 다시 시작한 후 노드는 자동으로 슬레이브 노드로 클러스터에 참여합니다.
LVS 매핑 지연
Proxy의 포드는 LVS를 통해 로드 밸런싱됩니다. LVS의 백엔드 IP:포트 매핑이 적용되는 데 특정 지연이 있습니다. 프록시 노드가 갑자기 오프라인되면 일부 연결이 끊어집니다. 프록시 운영 및 유지 관리가 비즈니스에 미치는 영향을 최소화하기 위해 프록시 배포 템플릿에 다음 옵션을 추가했습니다.
lifecycle: preStop: exec: command: - sleep - "171"
클러스터 축소, 프록시 버전의 롤링 업데이트 및 기타 K8 제어 가능과 같은 일반 프록시 포드 오프라인의 경우 Pod가 오프라인이 되면 LVS에 메시지를 보내고 Pod가 오프라인이 되기 전에 171초를 기다립니다. 이 시간은 LVS가 비즈니스를 인식하지 못한 채 이 Pod의 트래픽을 다른 Pod로 점진적으로 전환하는 데 충분합니다.
2. K8s StatefulSet은 Redis 클러스터 배포 요구 사항을 충족할 수 없습니다
K8s 기본 StatefulSet은 Redis 클러스터 배포 요구 사항을 완전히 충족할 수 없습니다.
Redis 클러스터에서는 마스터-대기 관계가 있는 노드를 동일한 클러스터에 배포할 수 없습니다. 기계 . 이는 이해하기 쉽습니다. 머신이 다운되면 데이터 샤드를 사용할 수 없게 됩니다.
2) Redis 클러스터는 클러스터에 있는 마스터 노드의 절반 이상이 실패하는 것을 허용하지 않습니다. 왜냐하면 마스터 노드의 절반 이상이 실패하면 가십 프로토콜의 요구 사항을 충족할 만큼 노드 투표가 충분하지 않기 때문입니다. Redis Cluster의 마스터와 백업은 언제든지 전환될 수 있으므로 동일한 머신의 모든 노드가 마스터 노드인 상황을 피할 수 없으므로 배포 중에 클러스터 노드의 1/4 이상을 허용할 수 없습니다. 동일한 머신에 배포됩니다.
위 요구 사항을 충족하기 위해 기본 StatefulSet은 반선호도 기능을 사용하여 동일한 클러스터가 동일한 머신에 하나의 노드만 배포하도록 보장할 수 있지만 이 머신 활용도는 매우 낮습니다.
그래서 우리는 Redis 노드를 배포하기 위해 다양한 전략을 사용하는 StatefulSet: RedisStatefulSet를 기반으로 CRD를 개발했습니다. RedisStatefulSet에 Redis를 관리하기 위한 일부 기능이 추가되었습니다. 이에 대해서는 다른 기사에서 계속 자세히 논의하겠습니다.
7. 요약
수십 개의 Redis 클러스터가 6개월 이상 K8s에 배포 및 실행되었으며 이러한 클러스터에는 그룹 내의 여러 비즈니스가 포함됩니다. K8s의 신속한 배포 및 오류 마이그레이션 기능 덕분에 이러한 클러스터의 운영 및 유지 관리 워크로드는 물리적 시스템의 Redis 클러스터보다 훨씬 낮으며 안정성이 완전히 검증되었습니다.
작동 및 유지 관리 과정에서도 많은 문제가 발생했습니다. 기사에 언급된 기능 중 상당수는 실제 요구에 따라 개선되었습니다. 다음 과정에서는 자원 활용 효율성과 서비스 품질을 향상시키기 위해 여전히 많은 문제를 점진적으로 해결해야 합니다.
1. 혼합 배포 vs. 독립적 배포
물리적 머신의 Redis 인스턴스는 독립적으로 배포됩니다. 모든 Redis 인스턴스는 단일 물리적 머신에 배포되므로 관리에 유리하지만 리소스 활용률이 높지 않습니다. . Redis 인스턴스는 CPU, 메모리, 네트워크 IO를 사용하지만 기본적으로 저장 공간이 낭비됩니다. Redis 인스턴스가 K8s에 배포되면 다른 유형의 서비스가 위치한 머신에 배포될 수 있습니다. 이는 머신의 활용도를 향상시킬 수 있지만, 제거되는 경우 고가용성 및 대기 시간 요구 사항이 있는 Redis와 같은 서비스의 경우. 기계에 메모리가 부족하기 때문에 허용되지 않습니다. 이를 위해서는 운영 및 유지 관리 담당자가 Redis 인스턴스가 배포된 모든 머신의 메모리를 모니터링해야 합니다. 메모리가 부족하면 마스터를 차단하고 노드를 마이그레이션하지만 이로 인해 운영 및 유지 관리 작업량이 증가합니다.
하이브리드 배포에 다른 높은 네트워크 처리량 애플리케이션이 있는 경우 Redis 서비스에 부정적인 영향을 미칠 수도 있습니다. K8s의 반친화성 기능은 이러한 애플리케이션이 없는 머신에 Redis 인스턴스를 선택적으로 배포할 수 있지만 머신 리소스가 부족한 경우 이러한 상황을 피할 수 없습니다.
2. Redis 클러스터 관리
Redis 클러스터는 중앙 노드가 없는 P2P 클러스터 아키텍처로 전파 및 조정하여 클러스터의 온라인 및 오프라인 상태를 자동으로 복구합니다. Redis 클러스터의 일부 노드 상태(예: 클러스터 토폴로지의 노드 실패 또는 핸드셰이크 상태 또는 분할 브레인)가 나타납니다. 이러한 비정상적인 상태에 대해서는 Redis CRD에 더 많은 기능을 추가하여 점진적으로 문제를 해결하고 운영 및 유지 관리 효율성을 더욱 향상시킬 수 있습니다.
3. 감사 및 보안
Redis는 Auth 비밀번호 인증 보호 기능만 제공하고 권한 관리가 부족하여 보안이 상대적으로 낮습니다. Proxy를 통해 비밀번호를 통해 클라이언트 유형을 구분할 수 있으며, 관리자와 일반 사용자는 서로 다른 비밀번호를 사용하여 로그인하고, 실행 가능한 작업 권한도 다르기 때문에 권한 관리, 작업 감사 등의 기능을 구현할 수 있습니다.
4. 다중 Redis 클러스터 지원
가십 프로토콜의 한계로 인해 단일 Redis 클러스터는 수평 확장 기능이 제한됩니다. 클러스터 크기가 300개 노드인 경우 노드 마스터 선택과 같은 토폴로지 변경의 효율성이 크게 향상됩니다. 줄인. 동시에 단일 Redis 인스턴스의 용량이 너무 높아서는 안 되기 때문에 단일 Redis 클러스터가 TB 이상의 데이터 규모를 지원하기는 어렵습니다. 프록시를 통해 키를 논리적으로 분할할 수 있으므로 단일 프록시를 여러 Redis 클러스터에 연결할 수 있습니다. 클라이언트 관점에서 이는 더 큰 데이터 규모를 지원할 수 있는 Redis 클러스터에 연결하는 것과 같습니다.
위 내용은 Redis 클러스터 인스턴스 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!