构建容器化的 Redis 集群服务代理

数据库
存储
API
Redis
容器
0
0
## **Redis & Amazon ElastiCache for Redis & Amazon MemoryDB of Redis 简介** Redis 是一个 Key-Value 存储系统,是跨平台的非关系型数据库。Redis 是现在最受欢迎的 NoSQL 数据库之一,它是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。Redis 通常被称为数据结构服务器,因为值(Value)可以是字符串(String)、哈希(Hash)、列表(List)、集合(Sets)和有序集合(Sorted Sets)等类型。 [Amazon ElastiCache](https://aws.amazon.com/cn/elasticache/?trk=cndc-detail) for Redis 是速度超快的内存数据存储,能够提供亚毫秒级延迟来支持 Internet 范围内的实时应用程序。适用于 Redis 的 ElastiCache 基于开源 Redis 构建,可与 Redis API 兼容,能够与 Redis 客户端配合工作,并使用开放的 Redis 数据格式来存储数据。[Amazon ElastiCache](https://aws.amazon.com/cn/elasticache/?trk=cndc-detail) 是一项完全托管的服务。您无需执行硬件预置、软件修补、设置、配置、监控、故障恢复和备份等管理任务。ElastiCache 会持续监控您的集群,以保障您的 Redis 正常运行,使您可以集中精力开发更高价值的应用程序。支持 Redis 集群和非集群模式,能够通过自动故障转移支持提供高可用性。 MemoryDB of Redis 是一种持久的内存中数据库服务,可提供超快的性能。它专为具有微服务架构的现代应用程序而构建。MemoryDB 与 Redis 兼容,使您能够使用他们目前已经使用的同样灵活友好的 Redis 数据结构、API 和命令快速构建应用程序。使用 Memory DB,您的所有数据都存储在内存中,这使您能够实现微秒读取和单位数毫秒的写入延迟和高吞吐量。MemoryDB 还使用多可用区事务日志跨多个可用区(AZ)持久存储数据,以实现快速故障切换、数据库恢复和节点重启。Memory DB 既具有内存中的性能和多可用区持久性,可用作微服务应用程序的高性能主数据库,从而无需分别管理缓存和持久数据库。 ## **为什么 Redis Cluster 需要 Proxy** 在生产环境中,从容量、性能、扩缩容灵活性等方面考虑,很多客户选择了 Redis Cluster 的部署方式。但 Redis Cluster 也带来了额外的开发与使用成本。为了简化开发与使用,在很多场景下,我们需要为 Redis Cluster 搭建 proxy。Proxy 的主要优势有以下几点: 1. 语言便利:目前,只有 jedis 与 Redis Cluster 模式配合良好,为了在 Redis Cluster 进行稳定开发,需要程序员选择 java 语言;但在利用 proxy 的情况下,则有很多与 Redis single client 模式配合良好的语言可以选择,程序员可以根据自己的喜好选择语言。 2. 开发便捷:对于有大量用户的客户,特别是针对中国市场的客户,为了应对大量访问,Redis Cluster 的规模往往都比较大。大型的 Redis Cluster 带来了额外的开发/运维成本。为了简化开发工作,往往需要在集群与客户端之间寻求一个中间件,而 Redis Proxy 则是针对 Redis 集群的中间件。 3. 灵活连接:根据访问量的变化,Redis Cluster 的节点数量会有伸缩的情况。利用 proxy,客户端可以对节点数量变化透明。 4. 跨槽访问:Redis Cluster 模式不支持跨槽访问,在进行多 slot 数据操作时,往往需要在客户端完成访问拆分,将一个整体的数据访问拆分为多个单 slot 的数据访问操作;Redis Proxy 支持部分跨槽访问操作,例如 MSET/MGET/DEL,减轻了数据访问开发工作。 根据这一系列的实际需求,催生出了诸如 Redis-Cluster-Proxy、Overlord Proxy、Envoy Proxy 等多款 proxy 产品。其中,Redis-Cluster-Proxy、Overlord Proxy 均以主机部署方式为主,而 Envoy Proxy 则能以主机和容器化方式进行部署,特别是容器化部署方式,对于大部分应用都已实现容器化的客户来说,比较友好。 ## **Envoy Proxy 简介** Envoy 是一个开源的服务代理,专为云原生应用程序而设计。Envoy 最初由 Lyft 构建,是专为单个服务和应用程序设计的高性能 C++分布式代理,以及专为大型微服务“服务网格”架构设计的通信总线和“通用数据平面”。 主要特性: 1. 进程外体系结构:Envoy 是一个独立的高性能服务器,内存占用量小。它能与任何应用程序语言或框架一起运行。 2. HTTP/2 和 GRPC 支持:Envoy 对 HTTP/2 和 gRPC 的连接有良好的支持。它是一个透明的 HTTP / 1.1 到 HTTP / 2 代理。 3. 高级负载平衡:Envoy 支持高级负载均衡功能,包括自动重试、断路、全局速率限制、请求重影、区域本地负载均衡等。 4. 用于配置管理的 API:Envoy 提供了强大的 API 来动态管理其配置。 5. 可观察性:7 层流量的深度可观测性、原生支持分布式跟踪、以及 MongoDB、DynamoDB 等数据库的 wire-level 可观测性。 Envoy Proxy 应用场景较多,本文利用 Envoy Proxy 实现对 Redis Cluster 的连接代理。 ## **部署 Envoy Proxy** 1)制作 Envoy Proxy 镜像,上传至 ECR a. 编辑 envoy.yaml,包括:服务端口、连接字符串。本文档中,Proxy 服务端口为 7480,连接字符串为 Redis cluster 的地址与端口。 ```js envoy.yaml: static_resources: listeners: - name: redis_listener address: socket_address: address: 0.0.0.0 port_value: 7480 filter_chains: - filters: - name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.redis_proxy.v3.RedisProxy stat_prefix: egress_redis settings: op_timeout: 5s prefix_routes: catch_all_route: cluster: redis_cluster clusters: - name: redis_cluster cluster_type: name: envoy.clusters.redis typed_config: "@type": type.googleapis.com/google.protobuf.Struct value: cluster_refresh_rate: 10s cluster_refresh_timeout: 4s connect_timeout: 4s dns_lookup_family: V4_ONLY lb_policy: CLUSTER_PROVIDED load_assignment: cluster_name: redis_cluster endpoints: lb_endpoints: endpoint: address: socket_address: { address: envoy-k8s1.xxxxxx.clustercfg.memorydb.us-west-2.amazonaws.com, port_value: 6379 } admin: address: socket_address: address: 0.0.0.0 port_value: 9901 ``` b. 根据 DockerFile 生成 Proxy 镜像,并上传至 ECR ```js Dockerfile: FROM envoyproxy/envoy-dev:latest COPY ./envoy.yaml /etc/envoy.yaml RUN chmod go+r /etc/envoy.yaml #CMD ["/usr/local/bin/envoy", "-c", "/etc/envoy.yaml", "--service-cluster", "proxy"] # Enable logging at debug level CMD ["/usr/local/bin/envoy", "-c", "/etc/envoy.yaml", "--service-cluster", "proxy", "--log-path", "/tmp/envoy_log.txt", "--log-level", "debug"] ``` 2)在 EKS 上部署 Envoy Proxy,并暴露服务。 本文档中,我们会部署 2 个 Envoy Proxy POD,并设置一定的 CPU/内存上限。容器镜像为上一步操作中上传至 ECR 的 Proxy 镜像。 ```js eks-redis-deployment-envoy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: "envoy-redis-proxy" labels: ec: "redis-pod" app: envoy spec: replicas: 2 revisionHistoryLimit: 2 selector: matchLabels: ec: "redis-pod" app: envoy strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: ec: "redis-pod" app: envoy spec: containers: - image: "xxxxxxx.dkr.ecr.us-west-2.amazonaws.com/envoy:proxy-redis" ports: - containerPort: 7480 name: envoy resources: limits: cpu: 200m memory: 400Mi requests: cpu: 100m memory: 200Mi restartPolicy: Always terminationGracePeriodSeconds: 30 ``` 检查 POD 状态: ```js NAME READY STATUS RESTARTS AGE centos-pod-test 1/1 Running 0 2m4s envoy-blue-proxy-55c6fd6988-4rdbb 1/1 Running 0 2m8s envoy-blue-proxy-55c6fd6988-bs99w 1/1 Running 0 2m8s ``` 检查服务状态: ```js NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-blue-proxy ClusterIP 10.100.95.27 <none> 7480/TCP 2m13s kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 36m ``` ## **功能测试** 连接测试: ```js kubectl exec -it envoy-blue-centos -- /bin/bash [root@centos-pod-test redis-stable]# redis-cli -h 10.100.95.27 -p 7480 10.100.95.27:7480> ping PONG 10.100.95.27:7480> set a 1 OK 10.100.95.27:7480> exit [root@centos-pod-test redis-stable]# exit exit ``` 跨槽 MGET/MSET 测试: ![image.png](https://dev-media.amazoncloud.cn/52aa40eb60754245a9f86d5e8ba5a38a_image.png "image.png") 可以通过 envoy proxy 实现跨槽的 MGET/MSET 操作。 ![image.png](https://dev-media.amazoncloud.cn/aea627d7ba7b40419817c2558d2769f1_image.png "image.png") 对比直连 redis cluster,跨槽的 MGET/MSET 操作失败。 ## **性能测试** 我们采用 redis-benchmark 对 Proxy 模式和直连模式进行对比测试,分别测试非 pipeline 和 pipeline 两种场景。 Proxy 模式: ![image.png](https://dev-media.amazoncloud.cn/c3058956306e4749b83e5351207c051c_image.png "image.png") 直连模式: ![image.png](https://dev-media.amazoncloud.cn/c5cf9927d26943f296c8b58c2a8f180a_image.png "image.png") 结果分析: 1\. 非 pipeline 场景 SET、GET、MSET 三类操作,Proxy 模式和直连模式性能基本一致,Proxy 基本没有性能损耗。 2\. pipeline 场景 SET、GET 操作,Proxy 模式对比直连模式,有 0.5ms 的性能损耗 Proxy 模式的 MSET 测试,延迟较高,除了 proxy 本身性能损耗外,还要考虑实际业务上的 key 分布情况,case by case 地进行真实业务的测试。 ## **总结** Envoy proxy 以容器化的方式部署在 EKS 集群,具有较高的部署灵活性,特别是针对大部分应用已经容器化的客户,这一部署方式比较友好;同时,利用 K8s 本身的特点,减轻 Envoy proxy 的运维工作,对比主机部署的方式,在运维便捷性上有较大提升。针对 Envoy proxy 在实际业务中的性能,建议在实际场景中进行充分测试,以调整 proxy 本身的资源配置来匹配对应的工作负载。 ![640 (1).gif](https://dev-media.amazoncloud.cn/3415fa51fc90483eaf1fa5c2cd89f07b_640%20%281%29.gif "640 (1).gif")
0
目录
关闭