用Kubernetes在Redis+Sentinel上运行的记录

配置Redis+Sentinel的原因

为了减轻Redis缓存服务器的访问压力并进行扩展,有时会采用可读写的Redis主服务器和只读的Redis从服务器的组合配置。我将在这里记录关于如何在Kubernetes上实现这一目标的方法。虽然可能会有人说可以使用Helm或Operator进行构建,但我仍然希望了解Redis在实现高可用性时的相关内容。

redis-master-slave.png

我在IBM Cloud Kubernetes Service (IKS) 上运行,使用的清单是云原生的清单,因此可以在任何云平台上运行。

Sentinel是Redis项目提供的一个功能,用于对Redis进行监视和选择主节点。为了实现可用性和主节点选择投票,在Sentinel中多个进程协同工作。

Sentinel会监视所有的Redis实例,并在主节点停止时选择下一个主节点。你可以通过向Sentinel查询来了解当前的主节点,当然也可以了解从节点。

Redis客户端应用程序会通过Sentinel查询Redis主节点的IP地址,并将写操作发送到Redis主节点。在读取操作中,会访问从节点以避免主节点过载。关于与Sentinel进行查询的编程语言客户端库,请参考参考资料中的链接。

redis-sentinel.png

启动 Redis + Sentinel 的高可用性配置。

那么,我们将在Kubernetes上创建上图所示的架构。

假设已经创建了 Kubernetes 集群,并且可以使用 kubectl 命令进行操作,我将继续编写。
此外,该配置直接使用了参考资料1中提供的内容。在这里,我们克隆了一个分叉的代码库。

git clone https://github.com/takara9/examples
cd examples/staging/storage/redis

# 起動用 Redisマスター + Sentinel のポッドをスタート
kubectl create -f redis-master.yaml

# Sentinelのサービスを起動  Sentinelにリクエストする時は、これにアクセスする
kubectl create -f redis-sentinel-service.yaml

# Redisサーバーを、レプリケーションコントローラー下で起動する
kubectl create -f redis-controller.yaml

# Sentinelサーバーも、レプリケーションコントローラー下で起動する
kubectl create -f redis-sentinel-controller.yaml

# レプリカ数を増やして、冗長化と性能アップを実施
kubectl scale rc redis --replicas=3
kubectl scale rc redis-sentinel --replicas=3

启动后,请确认Sentinel的服务名称和IP地址。

$ kubectl get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
kubernetes       ClusterIP   172.21.0.1       <none>        443/TCP     4d8h
redis-sentinel   ClusterIP   172.21.195.107   <none>        26379/TCP   92s

另外,确认Redis服务器和Sentinel Pod的IP地址列表。

i$ kubectl get po -o wide
NAME                   READY   STATUS   AGE     IP               NODE
redis-d62nc            1/1     Running  5m28s   172.30.94.152    10.193.10.14
redis-master           2/2     Running  6m2s    172.30.222.152   10.193.10.58
redis-sentinel-f49jh   1/1     Running  5m37s   172.30.94.150    10.193.10.14
redis-sentinel-m6dq8   1/1     Running  5m20s   172.30.222.153   10.193.10.58
redis-sentinel-p4jtb   1/1     Running  5m20s   172.30.94.153    10.193.10.14
redis-vnmsq            1/1     Running  5m28s   172.30.94.151    10.193.10.14

连接到Sentinel,找到Redis主节点,然后向Redis主节点写入测试数据。

我們可以使用redis-cli作為應用程式的客戶端,連接到Redis+Sentinel的配置。

$ kubectl run -it redis-cli --rm --image redis --restart=Never -- bash
If you don't see a command prompt, try pressing enter.
root@redis-cli:/data# 

链接到 Sentinel,并获取 Redis 主节点的 IP 地址。 Sentinel 的命令在参考资料2中可以找到。

root@redis-cli:/data# redis-cli -h redis-sentinel -p 26379
redis-sentinel:26379> SENTINEL get-master-addr-by-name mymaster
1) "172.30.222.152"
2) "6379"

为了确认数据同步从Redis主节点到从节点,将键和值设置在Redis主节点上。

redis-sentinel:26379> connect 172.30.222.152 6379
172.30.222.152:6379> set abc 1000
OK
172.30.222.152:6379> get abc
"1000"
172.30.222.152:6379> incr abc
(integer) 1001
172.30.222.152:6379> incr abc
(integer) 1002

列举Redis从服务器,并查看其IP地址和端口号。

redis-sentinel:26379> SENTINEL slaves mymaster
1)  1) "name"
    2) "172.30.94.151:6379"
<中略>
2)  1) "name"
    2) "172.30.94.152:6379"   

我会将从设备中采集的数据作同步处理,并核对是否成功连接。按照预期,我们能够成功提取数据。

172.30.222.152:6379> connect 172.30.94.151 6379
172.30.94.151:6379> get abc
"1002"
172.30.94.151:6379> connect 172.30.94.152 6379
172.30.94.152:6379> get abc
"1002"

停止主测试

查询Redis主节点的IP地址,并使用kubectl命令删除作为主节点的Pod,以确认故障转移。

redis-sentinel:26379> SENTINEL get-master-addr-by-name mymaster
1) "172.30.222.152"
2) "6379"

从另一个终端中删除主节点的Pod。
在启动时,只启动了Pod,但由于后来添加的复制控制器具有相同的选择器标签,因此复制控制器将视此Pod为受其管理,并在其被删除时启动新的Pod以维持副本数。

$ kubectl delete po redis-master
pod "redis-master" deleted

由复制控制器启动的Pod将作为Redis从服务器参与。然后,通过Sentinel的工作,进行投票以晋升为主服务器,并确定新的Redis主服务器。

redis-sentinel:26379> SENTINEL get-master-addr-by-name mymaster
1) "172.30.94.156"
2) "6379"

总结

既然已经使用了构建好的容器,考虑到生产使用,必须从容器的构建开始考虑。关于这一点,请参考资料1的GitHub。

我已经确认可以在Kubernetes上使用主从模式的可扩展缓存服务器。

请参考下面的资料;
以下是可供参考的资料;
请参照以下资料;
这些是供您参考的资料;
请使用以下参考资料。

    1. k8s Redis示例,https://github.com/kubernetes/examples/tree/master/staging/storage/redis

哨兵客户端,https://redis.io/topics/sentinel-clients

PHP Redis客户端库,https://github.com/jamescauwelier/PSRedis

Java Redis客户端库,https://github.com/redisson/redisson

广告
将在 10 秒后关闭
bannerAds