Kubernetes——在 KubeSphere中部署高可用Redis集群

时间:2021-02-18 00:51:15


摘要

Redis 是在开发过程中经常用到的缓存中间件,在生产环境中为了考虑稳定性和高可用一般为集群模式的部署。 常规部署在虚拟机上的方式配置繁琐并且需要手动重启节点,而使用 K8s 进行 Redis 集群的部署有以下优点:

  • 安装便捷:使用镜像或者 yaml 配置文件即可一件安装
  • 自动调度:容器挂掉后会自动调度重启和资源分配
  • 缩扩容方便:在 扩容、缩容 方面的优点无需多说,一键伸缩
  • 稳定高效:K8s 在整个集群上进行调度,只要整个集群不挂掉总会调度到合适节点重启容器服务

一、配置 redis.conf 字典

在项目空间的 配置配置字典中创建进行配置字典的创建。

Kubernetes——在 KubeSphere中部署高可用Redis集群

key 值的内容为 redis.conf,value 值为:

cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-require-full-coverage no
cluster-migration-barrier 1
appendonly yes

Kubernetes——在 KubeSphere中部署高可用Redis集群

二、redis-cluster-pvc设置

redis-cluster-pvc存储卷设置

  • PVC 名称前缀:redis-pvc 容量:10G
  • 权限:读写
  • 挂载路径:/data

Kubernetes——在 KubeSphere中部署高可用Redis集群

三、创建 redis-cluster服务

在项目空间的 应用负载 :服务中创建进行Redis集群服务的创建

基本设置里名称就叫redis-cluster然后进行重头戏,下一步的容器组配置

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

注意: 如果集群构建失败后需要重新删除原有的pvc 重新构建新的pvc。

四、容器组配置

这一步的核心就是配置 Redis 的容器,集群数量就选择常规的三主三从,那容器的副本数量就是 6 个。

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

镜像选择 docker hub(可以选择私有仓库) 中 redis 的 5.0.7版本,并选择使用默认端口,CPU 和内存可以选择性预留, 如果不预留就是调度公共资源(最好是选择合适的,这样方便统计资源)。 选择使用默认端口的话下面的端口设置就是如上图一样都会使用 6379,还有就是配置启动命令。

Kubernetes——在 KubeSphere中部署高可用Redis集群

如上图配置:

  • 命令:redis-server
  • 参数:/etc/redis/redis.conf 参数指向的就是之前字典配置的内容,但是需要下一步存储设置里进行配置字典才能使用。

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

高级设置里是一些额外配置,可以根据自己场景选择调整配置,调成完成后点击创建 进行 Redis 集群容器的创建。

五、初始化 Redis 集群

5.1 IP 地址初始化集群

创建完 Redis 服务后点击 redis 的服务名称进入 redis 服务详情,详情如下图

Kubernetes——在 KubeSphere中部署高可用Redis集群

 6 个 redis 的容器组都启动成功了,接下来就是初始化集群;因为我们配置的 redis 的服务是有状态服务 (Headless) 所以访问模式可以通过内部 DNS, 访问格式是:(容器名称).( 容器 DNS).svc.cluster.local。随意执行下面的命令:

redis-cli -h redis-cluster-v1-5.redis-cluster.athena-mall.svc.cluster.local

redis-cli -h redis-cluster-v1-4.redis-cluster.athena-mall.svc.cluster.local

redis-cli -h redis-cluster-v1-3.redis-cluster.athena-mall.svc.cluster.local

redis-cli -h redis-cluster-v1-2.redis-cluster.athena-mall.svc.cluster.local

redis-cli -h redis-cluster-v1-1.redis-cluster.athena-mall.svc.cluster.local

redis-cli -h redis-cluster-v1-0.redis-cluster.athena-mall.svc.cluster.local

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

主要看上图的这两个参数,nodes 为 1 表明当前节点只有 1 个,cluster_size 表明当前没有 master 节点,所以目前还不是集群结构,info 属性的详解在此列出:

  • cluster_state:ok 状态表示集群可以正常接受查询请求。fail 状态表示,至少有一个哈希槽没有被绑定(说明有哈希槽没有被绑定到任意一个节点),或者在错误的状态(节点可以提供服务但是带有 FAIL 标记),或者该节点无法联系到多数 master 节点。
  • cluster_slots_assigned:已分配到集群节点的哈希槽数量(不是没有被绑定的数量)。16384 个哈希槽全部被分配到集群节点是集群正常运行的必要条件。
  • cluster_slots_ok:哈希槽状态不是 FAIL 和 PFAIL 的数量。
  • cluster_slots_pfail:哈希槽状态是 PFAIL 的数量。只要哈希槽状态没有被升级到 FAIL 状态,这些哈希槽仍然可以被正常处理。PFAIL 状态表示我们当前不能和节点进行交互,但这种状态只是临时的错误状态。
  • cluster_slots_fail: 哈希槽状态是 FAIL 的数量。如果值不是 0,那么集群节点将无法提供查询服务,除非 cluster-require-full-coverage 被设置为 no。
  • cluster_known_nodes:集群中节点数量,包括处于握手状态还没有成为集群正式成员的节点。
  • cluster_size:至少包含一个哈希槽且能够提供服务的 master 节点数量。
  • cluster_current_epoch:集群本地 Current Epoch 变量的值。这个值在节点故障转移过程时有用,它总是递增和唯一的。
  • cluster_my_epoch:当前正在使用的节点的 Config Epoch 值。这个是关联在本节点的版本值。
  • cluster_stats_messages_sent:通过 node-to-node 二进制总线发送的消息数量。
  • cluster_stats_messages_received:通过 node-to-node 二进制总线接收的消息数量。

先尝试使用 ip + port 的方式初始化集群,但是在 K8s 中启动服务 ip 都会变化,所以最终的结果还是要用 DNS 方式进行集群初始化。 执行本步后再想修改为 DNS 地址初始化需要从来一遍,如果不想麻烦的同学可以直接跳过。

Kubernetes——在 KubeSphere中部署高可用Redis集群

记录 redis 集群的所有 ip+port,初始化命令如下:

redis-cli --cluster create 10.233.70.30:6379 10.233.70.32:6379 10.233.90.41:6379 10.233.90.43:6379 10.233.96.47:6379 10.233.96.50:6379 --cluster-replicas 1

进入 redis 集群随意一个节点的终端执行上面的命令。

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

如上图集群初始化就完成了,再输入命令 redis-cli 进入命令端,再执行 cluster info 查看集群信息。

Kubernetes——在 KubeSphere中部署高可用Redis集群

现在我们的集群节点有了 6 个,master 节点也有了三个,集群建立完成,后面的操作选择 master 节点进行操作。

Kubernetes——在 KubeSphere中部署高可用Redis集群

在对集群节点进行验证的时候如果遇到上图的错误 (error) MOVED 2589 10.233.70.30:6379 是因为 redis-cli 没有开启集群模式,将命令修改为 redis-cli -c 就切换为集群模式了。

5.2 使用内部 DNS 初始化

使用 ip 地址的方式在每次 K8s 调度 redis 后 ip 都会发生变化,所以在 K8s 集群中使用 ip 方式初始化集群并不太合适, 但是如果使用内部 DNS 直接跟上面一样初始化集群会出现错误,因为 redis 对域名的支持并不太好,所以这时候可以用 Redis-tribe。

Kubernetes——在 KubeSphere中部署高可用Redis集群

Kubernetes——在 KubeSphere中部署高可用Redis集群

apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test-project
labels:
app: redis-cluster-tools
name: redis-cluster-tools
spec:
replicas: 1
selector:
matchLabels:
app: redis-cluster-tools
template:
metadata:
labels:
app: redis-cluster-tools
name: pos-redis
spec:
containers:
- name: pos-redis
image: sunnywang/redis-tools-ubuntu:v0.5.1
imagePullPolicy: IfNotPresent
args:
- /bin/bash
- -c
- sleep 3600

创建好后在容器组内找到 redis-cluster-tools。

Kubernetes——在 KubeSphere中部署高可用Redis集群

点击容器名称进入容器详情再进入到终端里。先执行以下命令初始化 master 节点,这时候之前的内部DNS的域名就有用了。

redis-trib.py create `dig +short redis-cluster-v1-0.redis-cluster.test-project.svc.cluster.local`:6379 `dig +short redis-cluster-v1-1.redis-cluster.test-project.svc.cluster.local`:6379 `dig +short redis-cluster-v1-2.redis-cluster.test-project.svc.cluster.local`:6379

Kubernetes——在 KubeSphere中部署高可用Redis集群

 接下来给每个master节点绑定对应的副本节点,总共三个:

0 节点->3 节点: 

redis-trib.py replicate --master-addr `dig +short redis-cluster-v1-0.redis-cluster.test-project.svc.cluster.local`:6379 --slave-addr `dig +short redis-cluster-v1-3.redis-cluster.test-project.svc.cluster.local`:6379
1 节点->4 节点: 

redis-trib.py replicate --master-addr `dig +short redis-cluster-v1-1.redis-cluster.test-project.svc.cluster.local`:6379 --slave-addr `dig +short redis-cluster-v1-4.redis-cluster.test-project.svc.cluster.local`:6379
2 节点->5 节点: 

redis-trib.py replicate --master-addr `dig +short redis-cluster-v1-2.redis-cluster.test-project.svc.cluster.local`:6379 --slave-addr `dig +short redis-cluster-v1-5.redis-cluster.test-project.svc.cluster.local`:6379

Kubernetes——在 KubeSphere中部署高可用Redis集群

 随便进入一个集群节点的终端,还是执行 cluster info 命令,查看集群信息。

Kubernetes——在 KubeSphere中部署高可用Redis集群

使用基础命令进行验证,验证集群模式的 redis-cli 需要加-c

Kubernetes——在 KubeSphere中部署高可用Redis集群

六、集群压测

为了满足redis的集群需要,需要我们对构建的集群完成相关压测,同时调整相关资源,保证redis能够满足生产需要。

Redis 自带了一个叫 redis-benchmark 的工具来模拟 N 个客户端同时发出 M 个请求。(类似于 Apache ab 程序)。 你可以使用 redis-benchmark -h 来查看基准参数。redis 性能测试工具可选参数如下所示:

序号

选项

描述

默认值

1

-h

指定服务器主机名

127.0.0.1

2

-p

指定服务器端口

6379

3

-s

指定服务器 socket

4

-c

指定并发连接数

50

5

-n

指定请求数

10000

6

-d

以字节的形式指定 SET/GET 值的数据大小

2

7

-k

1=keep alive 0=reconnect

1

8

-r

SET/GET/INCR 使用随机 key, SADD 使用随机值

9

-P

通过管道传输 请求

1

10

-q

强制退出 redis。仅显示 query/sec 值

11

--csv

以 CSV 格式输出

12

-l (L 的小写字母)

生成循环,永久执行测试

13

-t

仅运行以逗号分隔的测试命令列表

14

-I (i 的大写字母)

Idle 模式。仅打开 N 个 idle 连接并等待。

压测示例;压测需要一段时间,因为它需要依次压测多个命令的结果,如:get、set、incr、lpush等等, 所以我们需要耐心等待,如果只需要压测某个命令,如:set,那么可以在以上的命令后加一个参数-t:

redis-benchmark -h 127.0.0.1 -p 6379 -n 100000 -c 50 -t set
# redis-benchmark -h 10.233.111.125 -p 6379 -n 100000 -c 50 -t set
====== SET ======
100000 requests completed in 6.05 seconds
50 parallel clients
3 bytes payload
keep alive: 1

93.28% <= 1 milliseconds
97.62% <= 2 milliseconds
98.18% <= 3 milliseconds
98.26% <= 4 milliseconds
98.27% <= 24 milliseconds
98.30% <= 72 milliseconds
98.32% <= 77 milliseconds
98.42% <= 78 milliseconds
98.68% <= 79 milliseconds
98.91% <= 80 milliseconds
99.42% <= 81 milliseconds
99.80% <= 82 milliseconds
99.91% <= 83 milliseconds
99.94% <= 84 milliseconds
99.96% <= 85 milliseconds
100.00% <= 86 milliseconds
100.00% <= 86 milliseconds
16528.93 requests per second

使用 pipelining

默认情况下,每个客户端都是在一个请求完成之后才发送下一个请求 (benchmark 会模拟 50 个客户端除非使用 -c 指定特别的数量), 这意味着服务器几乎是按顺序读取每个客户端的命令。Also RTT is payed as well. 真实世界会更复杂,Redis 支持 /topics/pipelining,使得可以一次性执行多条命令成为可能。 Redis pipelining 可以提高服务器的 TPS。

# redis-benchmark -h 10.233.111.125 -p 6379 -n 100000 -c 50 -t set,get -P 16 -q
SET: 195694.72 requests per second
GET: 83472.46 requests per second

博文参考