k8s如何部署redis集群
redis集群搭建
1.1使用redis-cli创建集群
# 查看redis的pod对应的ip kubectl get pod -n jxbp -o wide >NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES redis-0 1/1 Running 0 18h 10.168.235.196 k8s-master <none> <none> redis-1 1/1 Running 0 18h 10.168.235.225 k8s-master <none> <none> redis-2 1/1 Running 0 18h 10.168.235.239 k8s-master <none> <none> redis-3 1/1 Running 0 18h 10.168.235.198 k8s-master <none> <none> redis-4 1/1 Running 0 18h 10.168.235.222 k8s-master <none> <none> redis-5 1/1 Running 0 18h 10.168.235.238 k8s-master <none> <none> # 进入到redis-0容器 kubectl exec -it redis-0 /bin/bash -n jxbp # 创建master节点(redis-0、redis-2、redis-4) redis-cli --cluster create 10.168.235.196:6379 10.168.235.239:6379 10.168.235.222:6379 -a jxbd > Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. >>> Performing hash slots allocation on 3 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 M: bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379 slots:[0-5460] (5461 slots) master M: 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379 slots:[5461-10922] (5462 slots) master M: a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379 slots:[10923-16383] (5461 slots) master 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 10.168.235.196:6379) M: bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379 slots:[0-5460] (5461 slots) master M: a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379 slots:[10923-16383] (5461 slots) master M: 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379 slots:[5461-10922] (5462 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
注意上面的master节点,会生成对应节点id:bcae187137a9b30d7dab8fe0d8ed4a46c6e39638
、a2cec159bbe2efa11a8f60287b90927bcb214729
、4367e4a45e557406a3112e7b79f82a44d4ce485e
,用于创建slave节点。
# 为每个master节点添加slave节点 # 10.168.235.196:6379的位置可以是任意一个master节点,一般我们用第一个master节点即redis-0的ip地址 # --cluster-master-id参数指定该salve节点对应的master节点的id # -a参数指定redis的密码 # redis-0的master节点,添加redis-1为slave节点 redis-cli --cluster add-node 10.168.235.225:6379 10.168.235.196:6379 --cluster-slave --cluster-master-id bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 -a jxbd # redis-2的master节点,添加redis-3为slave节点 redis-cli --cluster add-node 10.168.235.198:6379 10.168.235.239:6379 --cluster-slave --cluster-master-id a2cec159bbe2efa11a8f60287b90927bcb214729 -a jxbd # redis-4的master节点,添加redis-5为slave节点 redis-cli --cluster add-node 10.168.233.238:6379 10.168.235.222:6379 --cluster-slave --cluster-master-id 4367e4a45e557406a3112e7b79f82a44d4ce485e -a jxbd
显示以下信息,即为添加成功:
[OK] All nodes agree about slots configuration.
[OK] All 16384 slots covered.
[OK] New node added correctly.
坑:
一开始是想用headless的域名创建redis集群的,这样节点重启后就不需要更新ip,但是redis不支持使用域名,所以只能绕了一圈又回到固定ip的方法,和容器环境很不协调。
1.2redis集群状态验证(可选)
cluster info
# 进入到redis客户端,集群需要带上-c,有密码需要带上-a redis-cli -c -a jxbd # 查看redis集群信息 127.0.0.1:6379> 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:3 cluster_my_epoch:1 cluster_stats_messages_ping_sent:7996 cluster_stats_messages_pong_sent:7713 cluster_stats_messages_sent:15709 cluster_stats_messages_ping_received:7710 cluster_stats_messages_pong_received:7996 cluster_stats_messages_meet_received:3 cluster_stats_messages_received:15709
注意:
现在进入集群中的任意一个Pod中都可以访问Redis服务,前面我们创建了一个headless类型的Service,kubernetes集群会为该服务分配一个DNS记录,格式为:$(pod.name)
.$(headless server.name)
.${namespace}
.svc.cluster.local
,每次访问该服务名时,将会直接进入到redis的节点上。svc.cluster.local
可省略。 例如:
redis-cli -c -a jxbd -h redis-0.redis-hs.jxbp -p 6379
cluster nodes
# 查看redis集群状态 127.0.0.1:6379> cluster nodes 70220b45e978d0cb3df19b07e55d883b49f4127d 10.168.235.238:6379@16379 slave 4367e4a45e557406a3112e7b79f82a44d4ce485e 0 1670306292673 2 connected 122b89a51a9bf005e3d47b6d721c65621d2e9a75 10.168.235.225:6379@16379 slave bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 0 1670306290558 1 connected c2afcb9e83038a47d04bf328ead8033788548234 10.168.235.198:6379@16379 slave a2cec159bbe2efa11a8f60287b90927bcb214729 0 1670306291162 3 connected 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379@16379 master - 0 1670306291561 2 connected 5461-10922 bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379@16379 myself,master - 0 1670306291000 1 connected 0-5460 a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379@16379 master - 0 1670306292166 3 connected 10923-16383
可以看到3个master,3个slave节点,都是connected
状态。
get,set验证
# 会找到对应的槽进行set操作,去到10.168.235.222节点 set name1 llsydn -> Redirected to slot [12933] located at 10.168.235.222:6379 OK # set name1成功 10.168.235.222:6379> set name1 llsydn OK # get name1成功 10.168.235.222:6379> get name1 "llsydn"
master节点进行set操作,slave节点复制。主从复制
1.3重启pod,验证集群(可选)
# redis-1未重启之前 10.168.235.239:6379> cluster nodes 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379@16379 myself,master - 0 1670307319000 2 connected 5461-10922 bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379@16379 master - 0 1670307319575 1 connected 0-5460 70220b45e978d0cb3df19b07e55d883b49f4127d 10.168.235.238:6379@16379 slave 4367e4a45e557406a3112e7b79f82a44d4ce485e 0 1670307318000 2 connected 122b89a51a9bf005e3d47b6d721c65621d2e9a75 10.168.235.225:6379@16379 slave bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 0 1670307319781 1 connected c2afcb9e83038a47d04bf328ead8033788548234 10.168.235.198:6379@16379 slave a2cec159bbe2efa11a8f60287b90927bcb214729 0 1670307319071 3 connected a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379@16379 master - 0 1670307318000 3 connected 10923-16383 # 重启redis-1 kubectl delete pod redis-1 -n jxbp pod "redis-1" deleted # redis-1重启之后 10.168.235.239:6379> cluster nodes 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379@16379 myself,master - 0 1670307349000 2 connected 5461-10922 bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379@16379 master - 0 1670307349988 1 connected 0-5460 70220b45e978d0cb3df19b07e55d883b49f4127d 10.168.235.238:6379@16379 slave 4367e4a45e557406a3112e7b79f82a44d4ce485e 0 1670307349000 2 connected 122b89a51a9bf005e3d47b6d721c65621d2e9a75 10.168.235.232:6379@16379 slave bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 0 1670307350089 1 connected c2afcb9e83038a47d04bf328ead8033788548234 10.168.235.198:6379@16379 slave a2cec159bbe2efa11a8f60287b90927bcb214729 0 1670307350000 3 connected a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379@16379 master - 0 1670307348000 3 connected 10923-16383
可以看到重启后的,redis-1节点,虽然ip变了,但是redis集群,还是可以识别到新的ip,集群还是正常的。
10.168.235.225 ---> 10.168.235.232
1.4创建Service服务
前面我们创建了用于实现StatefulSet的Headless Service,但该Service没有Cluster Ip,因此不能用于外界访问。因此,我们需要创建一个专门为Redis集群提供访问和负载均衡的Service。
这里可以使用ClusterIP
,NodePort
。这里,我使用的是NodePort
。
vi redis-ss.yaml
--- apiVersion: v1 kind: Service metadata: labels: k8s.kuboard.cn/layer: db k8s.kuboard.cn/name: redis name: redis-ss namespace: jxbp spec: ports: - name: imdgss port: 6379 protocol: TCP targetPort: 6379 nodePort: 6379 selector: k8s.kuboard.cn/layer: db k8s.kuboard.cn/name: redis type: NodePort
创建名称为:redis-ss
的服务。
在K8S集群中暴露6379端口,并且会对labels name
为k8s.kuboard.cn/name: redis
的pod进行负载均衡。
然后在K8S集群中,就可以通过redis-ss:6379
,对redis集群进行访问。
kubectl get service -n jxbp >NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE redis-hs ClusterIP None <none> 6379/TCP 76m redis-ss NodePort 10.96.54.201 <none> 6379:6379/TCP 2s
1.5 Springboot项目配置
spring.redis.cluster.nodes=redis-ss:6379
1.6相关疑问分析
至此,大家可能会疑惑,那为什么没有使用稳定的标志,Redis Pod也能正常进行故障转移呢?这涉及了Redis本身的机制。因为,Redis集群中每个节点都有自己的NodeId(保存在自动生成的nodes.conf中),并且该NodeId不会随着IP的变化和变化,这其实也是一种固定的网络标志。换句话说,即使某个Redis Pod因重启而重新启动,该Pod仍将使用保存的NodeId来维持其身份。可以通过NFS查看redis-0节点配置文件nodes.conf
vi /opt/nfs/pv1/nodes.conf > f6d4993467a4ab1f3fa806f1122edd39f6466394 10.168.235.228:6379@16379 slave ebed24c8fca9ebc16ceaaee0c2bc2e3e09f7b2c0 0 1670316449064 2 connected ebed24c8fca9ebc16ceaaee0c2bc2e3e09f7b2c0 10.168.235.240:6379@16379 myself,master - 0 1670316450000 2 connected 5461-10922 955e1236652c2fcb11f47c20a43149dcd1f1f92b 10.168.235.255:6379@16379 master - 0 1670316449565 1 connected 0-5460 574c40485bb8f6cfaf8618d482efb06f3e323f88 10.168.235.224:6379@16379 slave 955e1236652c2fcb11f47c20a43149dcd1f1f92b 0 1670316449000 1 connected 91bd3dc859ce51f1ed0e7cbd07b13786297bd05b 10.168.235.237:6379@16379 slave fe0b74c5e461aa22d4d782f891b78ddc4306eed4 0 1670316450672 3 connected fe0b74c5e461aa22d4d782f891b78ddc4306eed4 10.168.235.253:6379@16379 master - 0 1670316450068 3 connected 10923-16383 vars currentEpoch 3 lastVoteEpoch 0
如上,第一列为NodeId,稳定不变;第二列为IP和端口信息,可能会改变。
这里,我们介绍NodeId的两种使用场景:
当某个Slave Pod断线重连后IP改变,但是Master发现其NodeId依旧, 就认为该Slave还是之前的Slave。
如果某个 Master Pod 断线,集群中的其他 Slave 会进行选举选出新的 Master。如果旧的Master上线后,集群发现它的NodeId仍然相同,那么它会成为新Master的从属节点。
以上是k8s如何部署redis集群的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

Redis集群模式通过分片将Redis实例部署到多个服务器,提高可扩展性和可用性。搭建步骤如下:创建奇数个Redis实例,端口不同;创建3个sentinel实例,监控Redis实例并进行故障转移;配置sentinel配置文件,添加监控Redis实例信息和故障转移设置;配置Redis实例配置文件,启用集群模式并指定集群信息文件路径;创建nodes.conf文件,包含各Redis实例的信息;启动集群,执行create命令创建集群并指定副本数量;登录集群执行CLUSTER INFO命令验证集群状态;使

如何清空 Redis 数据:使用 FLUSHALL 命令清除所有键值。使用 FLUSHDB 命令清除当前选定数据库的键值。使用 SELECT 切换数据库,再使用 FLUSHDB 清除多个数据库。使用 DEL 命令删除特定键。使用 redis-cli 工具清空数据。

使用 Redis 指令需要以下步骤:打开 Redis 客户端。输入指令(动词 键 值)。提供所需参数(因指令而异)。按 Enter 执行指令。Redis 返回响应,指示操作结果(通常为 OK 或 -ERR)。

Redis 使用单线程架构,以提供高性能、简单性和一致性。它利用 I/O 多路复用、事件循环、非阻塞 I/O 和共享内存来提高并发性,但同时存在并发性受限、单点故障和不适合写密集型工作负载的局限性。

理解 Redis 源码的最佳方法是逐步进行:熟悉 Redis 基础知识。选择一个特定的模块或功能作为起点。从模块或功能的入口点开始,逐行查看代码。通过函数调用链查看代码。熟悉 Redis 使用的底层数据结构。识别 Redis 使用的算法。

Redis 使用哈希表存储数据,支持字符串、列表、哈希表、集合和有序集合等数据结构。Redis 通过快照 (RDB) 和追加只写 (AOF) 机制持久化数据。Redis 使用主从复制来提高数据可用性。Redis 使用单线程事件循环处理连接和命令,保证数据原子性和一致性。Redis 为键设置过期时间,并使用 lazy 删除机制删除过期键。

要从 Redis 读取队列,需要获取队列名称、使用 LPOP 命令读取元素,并处理空队列。具体步骤如下:获取队列名称:以 "queue:" 前缀命名,如 "queue:my-queue"。使用 LPOP 命令:从队列头部弹出元素并返回其值,如 LPOP queue:my-queue。处理空队列:如果队列为空,LPOP 返回 nil,可先检查队列是否存在再读取元素。

Redis 作为消息中间件,支持生产-消费模型,可持久化消息并保证可靠交付。使用 Redis 作为消息中间件可实现低延迟、可靠和可扩展的消息传递。
