当前位置: 首页 > article >正文

mysql一主多从 k8s部署实际案例

一、Kubernetes配置(MySQL主从集群)

  1. 主库StatefulSet配置(master-mysql.yaml):
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql-master
spec:serviceName: "mysql-master"replicas: 1selector:matchLabels:app: mysql-mastertemplate:metadata:labels:app: mysql-masterspec:containers:- name: mysqlimage: mysql:8.0env:- name: MYSQL_ROOT_PASSWORDvalue: "root123"- name: MYSQL_DATABASEvalue: "app_db"# 主库配置参数args:- "--server-id=1"- "--log-bin=mysql-bin"- "--binlog_do_db=app_db"- "--gtid-mode=ON"- "--enforce-gtid-consistency=ON"ports:- containerPort: 3306volumeMounts:- name: mysql-datamountPath: /var/lib/mysqlvolumeClaimTemplates:- metadata:name: mysql-dataspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "standard"resources:requests:storage: 20Gi
  1. 从库StatefulSet配置(slave-mysql.yaml):
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql-slave
spec:serviceName: "mysql-slave"replicas: 2  # 两个从库实例selector:matchLabels:app: mysql-slavetemplate:metadata:labels:app: mysql-slavespec:containers:- name: mysqlimage: mysql:8.0env:- name: MYSQL_ROOT_PASSWORDvalue: "root123"# 从库配置参数args:- "--server-id=$HOSTNAME_SLICE"  # 动态生成唯一server-id- "--relay-log=mysql-relay"- "--read-only=ON"- "--gtid-mode=ON"- "--enforce-gtid-consistency=ON"- "--skip-slave-start"  # 等待手动配置主从复制ports:- containerPort: 3306volumeMounts:- name: mysql-datamountPath: /var/lib/mysqlvolumeClaimTemplates:- metadata:name: mysql-dataspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "standard"resources:requests:storage: 20Gi

二、Java读写分离实现(Spring Boot示例)

  1. 数据源配置(application.yml):
spring:datasource:master:jdbc-url: jdbc:mysql://mysql-master:3306/app_dbusername: rootpassword: root123driver-class-name: com.mysql.cj.jdbc.Driverslaves:- jdbc-url: jdbc:mysql://mysql-slave-0:3306/app_dbusername: rootpassword: root123- jdbc-url: jdbc:mysql://mysql-slave-1:3306/app_dbusername: rootpassword: root123
  1. 动态数据源配置类:
/*** 动态数据源配置*/
@Configuration
@EnableTransactionManagement
@MapperScan("com.example.mapper")
public class DynamicDataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().build();}@Beanpublic DataSource slaveDataSource() {// 创建从库数据源列表List<DataSource> slaves = new ArrayList<>();// 这里需要根据实际配置动态加载从库数据源// ...(具体实现根据配置加载多个从库)// 负载均衡策略(轮询)return new LoadBalancedDataSource(slaves);}@Beanpublic DataSource dynamicDataSource(@Qualifier("masterDataSource") DataSource master,@Qualifier("slaveDataSource") DataSource slave) {DynamicDataSource dynamicDataSource = new DynamicDataSource();Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("master", master);targetDataSources.put("slave", slave);dynamicDataSource.setTargetDataSources(targetDataSources);dynamicDataSource.setDefaultTargetDataSource(master);return dynamicDataSource;}
}
  1. 数据源路由实现:
/*** 动态数据源路由器*/
public class DynamicDataSource extends AbstractRoutingDataSource {private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();@Overrideprotected Object determineCurrentLookupKey() {return CONTEXT_HOLDER.get();}public static void setDataSource(String dataSource) {CONTEXT_HOLDER.set(dataSource);}public static void clearDataSource() {CONTEXT_HOLDER.remove();}
}
  1. 自定义注解实现读写分离:
/*** 数据源选择注解*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {DataSourceType value() default DataSourceType.MASTER;
}public enum DataSourceType {MASTER, SLAVE
}
  1. AOP切面实现:
@Aspect
@Component
public class DataSourceAspect {@Before("@annotation(dataSource)")public void beforeSwitchDS(JoinPoint point, DataSource dataSource) {DataSourceType value = dataSource.value();if (value == DataSourceType.MASTER) {DynamicDataSource.setDataSource("master");} else {DynamicDataSource.setDataSource("slave");}}@Before("execution(* com.example.service..*.save*(..)) || " +"execution(* com.example.service..*.update*(..)) || " +"execution(* com.example.service..*.delete*(..))")public void writeOperations() {DynamicDataSource.setDataSource("master");}@AfterReturning("execution(* com.example.service..*.*(..))")public void afterReturning() {DynamicDataSource.clearDataSource();}
}

三、部署说明

  1. 集群初始化步骤:
# 部署主库
kubectl apply -f kubernetes/mysql/master-mysql.yaml# 等待主库启动完成后部署从库
kubectl apply -f kubernetes/mysql/slave-mysql.yaml# 验证Pod状态
kubectl get pods -l app=mysql-master
kubectl get pods -l app=mysql-slave
  1. 主从复制配置(在从库Pod中执行):
# 进入从库容器
kubectl exec -it mysql-slave-0 -- bash# 在MySQL中执行
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='root',
MASTER_PASSWORD='root123',
MASTER_AUTO_POSITION=1;START SLAVE;

四、架构特点说明

  1. 数据一致性保障:
  • 使用GTID实现事务一致性
  • 半同步复制配置(需在MySQL配置中额外添加)
  • 自动故障转移机制(建议配合k8s探针使用)
  1. 读写分离策略:
  • 写操作强制路由主库
  • 读操作自动负载均衡
  • 事务中强制使用主库
  1. 扩展性设计:
  • 从库数量可动态调整(修改StatefulSet replicas)
  • 自动水平扩展从库集群
  • 支持多可用区部署(需配置亲和性策略)

注意事项:

  1. 生产环境需配置Secret管理数据库密码
  2. 建议添加MySQL连接池配置(如HikariCP)
  3. 需要配置合适的持久化存储方案
  4. 建议添加监控和报警机制(Prometheus+Granafa)
http://www.lryc.cn/news/2393210.html

相关文章:

  • Visual Studio 2022 设置自动换行
  • 沉浸式 “飞进” 鸟巢:虚拟旅游新体验​
  • Ubuntu 下同名文件替换后编译链接到旧内容的现象分析
  • 【Linux网络篇】:简单的TCP网络程序编写以及相关内容的扩展
  • 22.代理模式:思考与解读
  • Scratch节日 | 粽子收集
  • stl三角面元文件转颗粒VTK文件
  • Java String的使用续 -- StringBuilder类和StringBuffer
  • Android学习之定时任务
  • WEB安全--RCE--webshell HIDS bypass4
  • 基于python+Django+Mysql的校园二手交易市场
  • 从零打造算法题刷题助手:Agent搭建保姆级攻略
  • Oracle 12c新增的数字转换验证VALIDATE_CONVERSION函数
  • 参数/非参数检验和连续/离散/分类等变量类型的关系
  • 懒人云电脑方案:飞牛NAS远程唤醒 + 节点小宝一键唤醒、远程控制Windows!
  • 【Python】第一弹:对 Python 的认知
  • 直播预告 | 聚焦芯必达|打造可靠高效的国产 MCU 与智能 SBC 汽车解决方案
  • Java源码中有哪些细节可以参考?(持续更新)
  • GelSight Mini触觉传感器:7μm精度+3D 映射,赋能具身智能精密操作
  • day 23 机器学习管道(pipeline)
  • shell编程笔记
  • 鸿蒙仓颉开发语言实战教程:自定义组件
  • 基于Spring Boot+Vue 网上书城管理系统设计与实现(源码+文档+部署讲解)
  • opencvsharp usb摄像头录像 c# H264编码
  • ch12 课堂参考代码 及 题目参考思路
  • uniapp 实现腾讯云 IM 消息已读回执
  • JavaScript 性能优化按层次逐步分析
  • 三分钟打通Stable Diffusion提示词(附实战手册)
  • 【Linux网络篇】:初步理解应用层协议以及何为序列化和反序列化
  • RK3588 Opencv-ffmpeg-rkmpp-rkrga编译与测试