k8s上部署redis高可用集群
介绍:
Redis Cluster通过分片(sharding)来实现数据的分布式存储,每个master节点都负责一部分数据槽(slot)。
当一个master节点出现故障时,Redis Cluster能够自动将故障节点的数据槽转移到其他健康的master节点上,从而保证集群的可用性和数据的完整性。
为了实现故障转移,Redis Cluster需要至少3个master节点。这是因为在选举新的master节点时,需要超过半数的master节点同意才能成功。如果只有两个master节点,当一个节点出现故障时,就无法满足选举新master节点的条件。
本方案采用StatefulSet进行redis的部署。它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序。在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
如果在k8s上搭建Redis sentinel,当master节点宕机后,sentinel选择新的节点当主节点,当原master恢复后,此时无法再次成为集群节点。因为在物理机上部署时,sentinel探测以及更改配置文件都是以IP的形式,集群复制也是以IP的形式,但是在容器中,虽然采用的StatefulSet的Headless Service来建立的主从,但是主从建立后,master、slave、sentinel记录还是解析后的IP,但是pod的IP每次重启都会改变,所有sentinel无法识别宕机后又重新启动的master节点,所以一直无法加入集群,虽然可以通过固定pod IP或者使用NodePort的方式来固定,或者通过sentinel获取当前master的IP来修改配置文件。 sentinel实现的是高可用Redis主从,检测Redis Master的状态,进行主从切换等操作,但是在k8s中,无论是dc或者ss,都会保证pod以期望的值进行运行,再加上k8s自带的活性检测,当端口不可用或者服务不可用时会自动重启pod或者pod的中的服务,所以当在k8s中建立了Redis主从同步后,相当于已经成为了高可用状态,并且sentinel进行主从切换的时间不一定有k8s重建pod的时间快。
yaml配置
vim一个配置文件redis-cluster.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:name: redis-cluster-confnamespace: cspy-test
data:redis.conf: |appendonly yescluster-enabled yescluster-config-file /var/lib/redis/nodes.confcluster-node-timeout 5000dir /var/lib/redisport 6379
---
#Headless service是StatefulSet实现稳定网络标识的基础
apiVersion: v1
kind: Service
metadata:name: redis-cluster-servicenamespace: cspy-testlabels:app: redis-cluster
spec:ports:- name: redis-cluster-portport: 6379clusterIP: Noneselector:app: redis-cluster
---
#通过StatefulSet创建6个redis的pod ,实现3主3从的redis集群
apiVersion: apps/v1
kind: StatefulSet
metadata:name: redis-cluster-appnamespace: cspy-test
spec:serviceName: "redis-cluster-service"replicas: 6selector:matchLabels:app: redis-clusterappCluster: redis-clustertemplate:metadata:labels:app: redis-clusterappCluster: redis-clusterspec:nodeSelector: #todo 去掉,由于资源不足才需要再masterkubernetes.io/hostname: "rwa-test1"tolerations: #todo 去掉- key: "node-role.kubernetes.io/master"operator: "Exists"effect: "NoSchedule" #todo 去掉containers:- name: redis-clusterimage: "redis:6.2.6-alpine"imagePullPolicy: IfNotPresentcommand:- "redis-server"args:- "/etc/redis/redis.conf"- "--protected-mode"- "no"resources:requests:cpu: "100m"memory: "100Mi"ports:- name: rediscontainerPort: 6379protocol: "TCP"- name: clustercontainerPort: 16379protocol: "TCP"volumeMounts:- name: "redis-cluster-conf"mountPath: "/etc/redis"- name: "redis-cluster-data"mountPath: "/var/lib/redis"volumes:- name: "redis-cluster-conf"configMap:name: "redis-cluster-conf"items:- key: "redis.conf"path: "redis.conf"volumeClaimTemplates:- metadata:name: redis-cluster-dataspec:accessModes: [ "ReadWriteMany" ]storageClassName: "nfs-storage1" #todo,改为自己的nfsresources:requests:storage: 100Mi #todo资源不足才用100
---
apiVersion: v1
kind: Service
metadata:name: redis-cluster-access-servicenamespace: cspy-testlabels:app: redis-cluster
spec:type: NodePortports:- name: redis-cluster-portprotocol: "TCP"port: 6379targetPort: 6379nodePort: 30479selector:app: redis-clusterappCluster: redis-cluster
运行
运用文件
kubectl apply -f redis-cluster.yaml
查看pod
# kubectl get pods -o wide -n cspy-test | grep redis
redis-cluster-app-0 1/1 Running 0 38s 10.244.0.167 rwa-test1 <none> <none>
redis-cluster-app-1 1/1 Running 0 32s 10.244.0.168 rwa-test1 <none> <none>
redis-cluster-app-2 1/1 Running 0 28s 10.244.0.169 rwa-test1 <none> <none>
redis-cluster-app-3 1/1 Running 0 24s 10.244.0.170 rwa-test1 <none> <none>
redis-cluster-app-4 1/1 Running 0 19s 10.244.0.171 rwa-test1 <none> <none>
redis-cluster-app-5 1/1 Running 0 16s 10.244.0.172 rwa-test1 <none> <none>
初始化集群
初始化集群采用redis-trib这个工具,直接yum安装redis-trib这个软件,执行初始化
yum -y install redis-trib
redis-trib create --replicas 1 10.244.0.167:6379 10.244.0.168:6379 10.244.0.169:6379 10.244.0.170:6379 10.244.0.171:6379 10.244.0.172:6379

验证集群状态,集群节点状态为OK,共有6个节点
#kubectl exec -ti redis-cluster-app-0 -n cspy-test -- redis-cli -c
>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:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:306
cluster_stats_messages_pong_sent:300
cluster_stats_messages_sent:606
cluster_stats_messages_ping_received:295
cluster_stats_messages_pong_received:306
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:606>role
1) "master"
2) (integer) 266
3) 1) 1) "10.244.0.170"2) "6379"3) "266"
>cluster nodes
c6435c77d80324dd8eeb8f6d2e34f0957e874dd2 10.244.0.169:6379@16379 master - 0 1731492697504 3 connected 10923-16383
b14509f7de9b7c17ea6ee48c34b5984b565f10b3 10.244.0.170:6379@16379 slave ba68bf3c1ebc4a55b49d8f30c9fd8e47fa44dcd6 0 1731492698407 1 connected
71d211e3f6af4601fb906a8160971e43585a3045 10.244.0.172:6379@16379 slave c6435c77d80324dd8eeb8f6d2e34f0957e874dd2 0 1731492697404 3 connected
d8047ef122f4485b4ce6dfa33befa03d49442b5b 10.244.0.171:6379@16379 slave e252d4fefcd71d83f57b72a314fdc33774863360 0 1731492697000 2 connected
ba68bf3c1ebc4a55b49d8f30c9fd8e47fa44dcd6 10.244.0.167:6379@16379 myself,master - 0 1731492697000 1 connected 0-5460
e252d4fefcd71d83f57b72a314fdc33774863360 10.244.0.168:6379@16379 master - 0 1731492696400 2 connected 5461-10922
redis主从切换测试
删除一个pod为redis的master
# kubectl delete pods redis-cluster-app-1
pod “redis-cluster app-0” deleted
删除pod后,k8s会自动重建一个名称为“redis-cluster-app-1”并加入到集群中,但IP不一定是原来的IP;再次通过cluster nodes或者role查看集群角色,redis-cluster-app-1由master变为salve,集群整体依然是6个
参考:https://blog.csdn.net/hlroliu/article/details/105859200
相关文章:
k8s上部署redis高可用集群
介绍: Redis Cluster通过分片(sharding)来实现数据的分布式存储,每个master节点都负责一部分数据槽(slot)。 当一个master节点出现故障时,Redis Cluster能够自动将故障节点的数据槽转移到其他健…...
C++的类和对象
在C中,类(class)和对象(object)是面向对象编程(OOP)的核心概念。以下是它们的详细介绍: 1. 类(Class) 定义: 类是用来定义一个新的数据类型&…...
自动驾驶系列—深入解析自动驾驶车联网技术及其应用场景
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
机器学习(1)
一、机器学习 机器学习(Machine Learning, ML)是人工智能(Artificial Intelligence, AI)的一个分支,它致力于开发能够从数据中学习并改进性能的算法和模型。机器学习的核心思想是通过数据和经验自动优化算法ÿ…...
深入理解 Redis跳跃表 Skip List 原理|图解查询、插入
1. 简介 跳跃表 ( skip list ) 是一种有序数据结构,通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。 在 Redis 中,跳跃表是有序集合键的底层实现之一,那么这篇文章我们就来讲讲跳跃表的实现原理。 2. …...
Halcon HImage 与 Qt QImage 的相互转换(修订版)
很久以前,我写过一遍文章来介绍 HImage 和 QImage 之间的转换方法。(https://blog.csdn.net/liyuanbhu/article/details/91356988) 这个代码其实是有些问题的。因为我们知道 QImage 中的图像数据不一定是连续的,尤其是图像的宽度…...
【Golang】——Gin 框架中的模板渲染详解
Gin 框架支持动态网页开发,能够通过模板渲染结合数据生成动态页面。在这篇文章中,我们将一步步学习如何在 Gin 框架中配置模板、渲染动态数据,并结合静态资源文件创建一个功能完整的动态网站。 文章目录 1. 什么是模板渲染?1.1 概…...
CSS:导航栏三角箭头
用CSS实现导航流程图的样式。可根据自己的需求进行修改,代码精略的写了一下。 注:场景一和场景二在分辨率比较低的情况下会有一个1px的缝隙不太优雅,自行处理。有个方法是直接在每个外面包一个DIV,用动态样式设置底色。 场景一、…...
onlyoffice Command service(命令服务)使用示例
一、说明 文档在这里:https://api.onlyoffice.com/docs/docs-api/additional-api/command-service/ 命令服务提供有几个简单的接口封装。也提供了前端和后端同时操作文档的可能。 二、正文 命令服务地址:https://documentserver/coauthoring/Com…...
QSS 设置bug
问题描述: 在QWidget上add 一个QLabel,但是死活不生效 原因: c 主程序如下: QWidget* LOGO new QWidget(logo_wnd);LOGO->setFixedSize(logo_width, 41);LOGO->setObjectName("TittltLogo");QVBoxLayout* tit…...
交换排序——快速排序
交换排序——快速排序 7.7 交换排序——快速排序快速排序概念c语言的库函数qsort快速排序框架quickSort 7.7 交换排序——快速排序 快速排序概念 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法(下文简称快排),其基本思想为&a…...
nodejs入门(1):nodejs的前后端分离
一、引言 我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的,当然,我肯定是很多年的计算机基础的,万变不离其宗。 现在web网站都流行所谓的前后端结构,不知不觉我也开始受到这个影响,以前都是前端直接操作…...
笔记|M芯片MAC (arm64) docker上使用 export / import / commit 构建amd64镜像
很简单的起因,我的东西最终需要跑在amd64上,但是因为mac的架构师arm64,所以直接构建好的代码是没办法跨平台运行的。直接在arm64上pull下来的docker镜像也都是arm64架构。 检查镜像架构: docker inspect 8135f475e221 | grep Arc…...
gorm框架
连接 需要下载mysql的驱动 go get gorm.io/driver/mysql go get gorm.io/gorm 约定 主键:GORM 使用一个名为ID 的字段作为每个模型的默认主键。表名:默认情况下,GORM 将结构体名称转换为 snake_case 并为表名加上复数形式。 例如…...
免费送源码:Java+Springboot+MySQL Springboot多租户博客网站的设计 计算机毕业设计原创定制
Springboot多租户博客网站的设计 摘 要 博客网站是当今网络的热点,博客技术的出现使得每个人可以零成本、零维护地创建自己的网络媒体,Blog站点所形成的网状结构促成了不同于以往社区的Blog文化,Blog技术缔造了“博客”文化。本文课题研究的“…...
【ASR技术】WhisperX安装使用
介绍 WhisperX 是一个开源的自动语音识别(ASR)项目,由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型,通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别(large-v2 为 70 倍实时…...
【计算机网络】协议定制
一、结构化数据传输流程 这里涉及协议定制、序列化/反序列化的知识 对于序列化和反序列化,有现成的解决方案:①json ②probuff ③xml 二、理解发送接收函数 我们调用的所有发送/接收函数,根本就不是把数据发送到网络中!本质都是…...
【SQL】mysql常用命令
为方便查询,特整理MySQL常用命令。 约定:$后为Shell环境命令,>后为MySQL命令。 1 常用命令 第一步,连接数据库。 $ mysql -u root -p # 进入MySQL bin目录后执行,回车后输入密码连接。# 常用参数&…...
阿里云引领智算集群网络架构的新一轮变革
阿里云引领智算集群网络架构的新一轮变革 云布道师 11 月 8 日~ 10 日在江苏张家港召开的 CCF ChinaNet(即中国网络大会)上,众多院士、教授和业界技术领袖齐聚一堂,畅谈网络未来的发展方向,聚焦智算集群网络的创新变…...
几何合理的分片段感知的3D分子生成 FragGen - 评测
FragGen 来源于 2024 年 3 月 25 日 预印本的文章,文章题目是 Deep Geometry Handling and Fragment-wise Molecular 3D Graph Generation, 作者是 Odin Zhang,侯廷军,浙江大学药学院。FragGen 是一个基于分子片段的 3D 分子生成模…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
HTTPS证书一年多少钱?
HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...
华为OD机考- 简单的自动曝光/平均像素
import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…...
