Kubernetes 部署 结合 ShardingSphere-JDBC(客户端分片模式)和 MySQL Operator 的架构指南

在 Kubernetes 中部署结合 ShardingSphere-JDBC(客户端分片模式)和 MySQL Operator 的架构,需要分别部署这两个核心组件,并进行集成配置。以下是一个详细的安装部署指南:


核心组件理解

  1. ShardingSphere-JDBC:
    • 工作在 应用层,是一个 JDBC 驱动扩展
    • 应用 直接依赖 ShardingSphere-JDBC Jar 包。
    • 分片、读写分离、加密等逻辑由 应用代码执行
    • 不需要 独立部署的 Proxy 服务。
  2. MySQL Operator:
    • 用于在 K8s 上自动化管理 MySQL 集群(如主从复制、Group Replication/InnoDB Cluster)。
    • 提供 高可用备份恢复扩缩容 能力。
    • 常见 Operator:Oracle MySQL Operator、Presslabs MySQL Operator (vitess-operator 也支持 MySQL,但更复杂)。

部署步骤详解

阶段 1:部署 MySQL Operator 与 MySQL 集群

这里以 Presslabs MySQL Operator (mysql-operator) 为例,因其流行度较高且支持 Group Replication。

  1. 添加 Helm Repo & 安装 Operator:

    helm repo add presslabs https://presslabs.github.io/charts
    helm repo update
    # 安装 Operator CRD 和 Controller
    helm install my-mysql-operator presslabs/mysql-operator -n mysql-operator --create-namespace
    
  2. 创建 MySQL 集群 (InnoDB Cluster):

    • 创建命名空间 (如 mysql): kubectl create ns mysql
    • 创建 mysql-cluster.yaml:
      apiVersion: mysql.presslabs.org/v1alpha1
      kind: MysqlCluster
      metadata:
        name: my-shard-cluster  # 集群名,后续在 JDBC URL 中引用
        namespace: mysql
      spec:
        secretName: mysql-root-secret  # 包含 root 密码的 Secret
        replicas: 3                    # 3 节点 Group Replication (最小推荐)
        podSpec:
          image: percona:8.0            # 或 mysql:8.0, mariadb:10.11
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
        volumeSpec:
          persistentVolumeClaim:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "standard" # 替换为你的 StorageClass
            resources:
              requests:
                storage: 10Gi
        mysqlConf:
          innodbBufferPoolSize: 512M    # 根据内存调整
      
    • 创建 root 密码 Secret:
      kubectl create secret generic mysql-root-secret -n mysql \
        --from-literal=password=your-strong-password-here
      
    • 部署集群: kubectl apply -f mysql-cluster.yaml -n mysql
    • 等待集群就绪:
      kubectl get mysqlcluster/my-shard-cluster -n mysql -w
      # 查看 Pods
      kubectl get pods -n mysql -l mysql.presslabs.org/cluster=my-shard-cluster -w
      # 查看 Service (用于连接)
      kubectl get svc -n mysql -l mysql.presslabs.org/cluster=my-shard-cluster
      
      关键 Service:
      • my-shard-cluster-mysql-primary (或 -master): 主节点 (读写)
      • my-shard-cluster-mysql-replicas (或 -readonly): 只读副本 (负载均衡)
      • my-shard-cluster-mysql: 所有节点的服务 (常用于 Operator 管理)

阶段 2:准备 ShardingSphere-JDBC 配置

核心:创建 config-sharding.yaml 文件

# config-sharding.yaml
dataSources:
  ds_0: # 数据源名称 (逻辑名,可自定义)
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource # 推荐使用 HikariCP
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: "jdbc:mysql://my-shard-cluster-mysql-primary.mysql.svc.cluster.local:3306/db0?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=utf8" # 指向 MySQL 集群主节点 Service
    username: root
    password: your-strong-password-here # 强烈建议使用 Secret 注入
  # 如果你的分片策略需要多个物理库 (如分库分表),在此处定义 ds_1, ds_2...
  # ds_1:
  #   ... (指向另一个 MySQL 集群或同一个集群的不同 schema)

rules:
- !SHARDING
  tables:
    t_order: # 逻辑表名
      actualDataNodes: ds_0.t_order_${0..3} # 物理表:ds_0 库中的 t_order_0 到 t_order_3
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_inline
    # ... 定义其他需要分片的表

  shardingAlgorithms:
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 4} # 分片算法:按 order_id 取模分4表
    # ... 定义其他分片算法

  # 绑定表(可选,优化关联查询)
  bindingTables:
    - t_order, t_order_item
  # 广播表(可选,所有库都有全量数据)
  broadcastTables:
    - t_config

重要说明:

  1. jdbcUrl: 指向 MySQL Operator 创建的 primary/master Service (my-shard-cluster-mysql-primary.mysql.svc.cluster.local:3306)。这是写入节点
  2. username/password: 使用 MySQL root 用户或为应用创建专用用户。务必通过 K8s Secret 注入密码!
  3. actualDataNodes: 定义逻辑表映射到的物理库和表。如果只分表不分库,数据源 (ds_0) 只有一个,指向主库。
  4. 分片算法 (shardingAlgorithms): 根据业务需求配置 (取模、范围、哈希、自定义等)。
  5. 读写分离 (可选):
    • dataSources 中定义主库 (writeDataSourceName)
    • 定义只读数据源 (readDataSourceNames) 列表,指向 replicas/readonly Service (my-shard-cluster-mysql-replicas.mysql.svc.cluster.local:3306)。
    • rules 中添加 !READWRITE_SPLITTING 规则。ShardingSphere-JDBC 会根据 SQL 类型自动路由读写。

阶段 3:集成 ShardingSphere-JDBC 到应用

  1. 应用依赖:

    • 在应用的 pom.xml (Maven) 或 build.gradle (Gradle) 中添加 ShardingSphere-JDBC 核心依赖:
      <!-- ShardingSphere JDBC 核心 -->
      <dependency>
          <groupId>org.apache.shardingsphere</groupId>
          <artifactId>shardingsphere-jdbc-core</artifactId>
          <version>5.3.0</version> <!-- 使用最新稳定版 -->
      </dependency>
      <!-- MySQL Connector/J -->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.33</version> <!-- 与 MySQL 服务器版本匹配 -->
      </dependency>
      <!-- HikariCP (推荐) -->
      <dependency>
          <groupId>com.zaxxer</groupId>
          <artifactId>HikariCP</artifactId>
          <version>5.0.1</version>
      </dependency>
      
  2. 配置加载:

    • 方案 A (推荐 - ConfigMap + 文件系统)
      • config-sharding.yaml 创建为 ConfigMap:
        kubectl create configmap shardingsphere-config -n your-app-namespace --from-file=config-sharding.yaml
        
      • 在应用 Deployment 中将此 ConfigMap 挂载到容器内的某个路径 (如 /etc/shardingsphere/config-sharding.yaml)。
      • 修改应用代码,从该文件路径加载 ShardingSphere 配置:
        String configFile = "/etc/shardingsphere/config-sharding.yaml";
        DataSource dataSource = YamlShardingSphereDataSourceFactory.createDataSource(new File(configFile));
        
    • 方案 B (嵌入式 - 环境变量/启动参数):
      • config-sharding.yaml 的内容转换为 YAML 字符串Properties
      • 通过 ConfigMap 设置成环境变量或命令行参数。
      • 在应用启动时读取环境变量/参数,构建 Map<String, DataSource>ShardingSphereRuleConfiguration,使用 ShardingSphereDataSourceFactory.createDataSource(...) 创建 DataSource(更复杂)
  3. 数据库密码安全:

    • 绝对不要 将明文密码写在 config-sharding.yaml 或代码中!
    • config-sharding.yamlpassword 字段使用占位符 (如 ${MYSQL_DS_PASSWORD})。
    • 创建一个 K8s Secret 存储数据库密码:
      kubectl create secret generic app-db-secret -n your-app-namespace \
        --from-literal=ds-password=your-actual-db-password
      
    • 在应用的 Deployment 中,将该 Secret 的值注入为环境变量:
      env:
        - name: MYSQL_DS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-db-secret
              key: ds-password
      
    • 应用启动时,ShardingSphere-JDBC 会自动解析 ${MYSQL_DS_PASSWORD} 并使用环境变量的值填充。
  4. 使用 DataSource:

    • 将 ShardingSphere 创建的 DataSource 注入到你的应用框架 (如 Spring Boot 的 DataSource Bean) 或直接在你的 DAO/JDBC 代码中使用。
    • 应用代码几乎无需修改,像使用普通 JDBC DataSource 一样操作数据库。ShardingSphere-JDBC 在底层透明处理分片、路由等逻辑。

阶段 4:部署应用

  1. 构建应用容器镜像 (包含应用代码、JDK、ShardingSphere JDBC 依赖)。
  2. 创建应用 Deployment:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: your-sharding-app
      namespace: your-app-namespace
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: your-sharding-app
      template:
        metadata:
          labels:
            app: your-sharding-app
        spec:
          containers:
          - name: app
            image: your-registry/your-sharding-app:latest
            env:
              - name: MYSQL_DS_PASSWORD # 注入数据库密码
                valueFrom:
                  secretKeyRef:
                    name: app-db-secret
                    key: ds-password
            volumeMounts:
              - name: shardingsphere-config
                mountPath: /etc/shardingsphere # 挂载 ConfigMap
                readOnly: true
          volumes:
            - name: shardingsphere-config
              configMap:
                name: shardingsphere-config # 引用之前创建的 ConfigMap
    # ... (根据需要添加 Service, Ingress 等)
    
  3. 应用 Service/Ingress: 创建 Service 暴露应用端口,如果需要外部访问,创建 Ingress。

阶段 5:验证与测试

  1. 检查 Pod 状态:

    kubectl get pods -n mysql   # MySQL 集群状态
    kubectl get pods -n your-app-namespace # 应用状态
    kubectl logs -f <your-app-pod-name> -n your-app-namespace # 查看应用日志,注意 ShardingSphere 初始化日志
    
  2. 连接 MySQL 主节点验证数据分布:

    kubectl run -it --rm mysql-client -n mysql --image=mysql:8.0 -- \
      mysql -h my-shard-cluster-mysql-primary.mysql.svc.cluster.local -uroot -p'your-root-password'
    > USE db0;
    > SHOW TABLES; # 应看到 t_order_0, t_order_1, t_order_2, t_order_3 等物理表
    > SELECT * FROM t_order_0; # 检查数据是否按预期分布在不同的物理表
    
  3. 执行应用功能测试:

    • 通过应用 API 或 UI 执行 CRUD 操作。
    • 观察应用日志中 ShardingSphere 的 SQL 路由日志 (需开启相应日志级别)。
    • 验证数据是否正确写入预期的物理分片表。
    • 如果配置了读写分离,验证读操作是否路由到了只读副本 (replicas Service)。

关键注意事项

  1. 版本兼容性:
    • 确保 ShardingSphere-JDBC、MySQL Connector/J、MySQL Server、MySQL Operator 版本相互兼容。查阅官方文档。
  2. 分片键选择:
    • 选择业务意义明确、分布均匀的列作为分片键 (如 user_id, order_id)。避免热点。
  3. 事务:
    • 跨分片的分布式事务是复杂问题。ShardingSphere 支持 XA (2PC) 和 BASE (Seata) 事务,但都有性能或复杂度开销。尽量设计业务,让单个事务内的操作落在同一个分片内 (同一库)
  4. DDL 管理:
    • ShardingSphere-JDBC 不自动同步 DDL 到所有物理表。创建/修改表结构需要在所有物理库/表上手动执行,或通过工具同步。谨慎操作
  5. 连接池配置:
    • config-sharding.yamldataSource 部分,可以配置 HikariCP (或 Druid) 的连接池参数 (如 maximumPoolSize, connectionTimeout),优化数据库连接管理。
  6. 监控:
    • MySQL Operator 监控: 部署 Prometheus Operator 并配置监控 MySQL 集群 (如使用 mysqld-exporter)。
    • ShardingSphere-JDBC 监控: 启用 ShardingSphere 的 Metrics (支持 Prometheus) 或使用其自带的治理中心功能。监控 SQL 执行、连接池、路由情况。
    • 应用监控: 使用应用性能监控 (APM) 工具 (如 SkyWalking, Pinpoint) 追踪 SQL 性能。
  7. 备份恢复:
    • 利用 MySQL Operator 提供的备份功能 (通常基于 Percona XtraBackup) 定期备份集群。测试恢复流程。
  8. 高可用与故障转移:
    • MySQL Operator 通常能自动处理主节点故障转移。确保应用配置的 jdbcUrl 指向的是稳定的 Service (primary/master),而不是具体的 Pod IP。Operator 会在故障转移后更新 Service 指向新的主节点。
    • 应用本身也需要部署多个副本 (replicas > 1) 并通过 Service 负载均衡,实现应用层高可用。
  9. 资源规划:
    • 根据业务负载,合理设置 MySQL Pod 和 应用 Pod 的 CPU/Memory Requests/Limits。
    • 为 PersistentVolume 预留足够空间并监控使用情况。

总结

在 Kubernetes 上部署 ShardingSphere-JDBC + MySQL Operator 的架构,核心在于:

  1. 独立部署 MySQL 集群:使用 Operator (如 Presslabs) 在 K8s 上自动化部署和管理高可用的 MySQL InnoDB Cluster。
  2. 应用集成 ShardingSphere-JDBC
    • 应用直接引入 ShardingSphere-JDBC 依赖。
    • 将精心设计的 config-sharding.yaml (分片规则 + 指向 MySQL 主节点 Service 的 JDBC URL) 通过 ConfigMap 挂载到应用容器。
    • 使用 Secret 安全地管理数据库密码并通过环境变量注入。
    • 应用启动时加载该 YAML 配置文件创建 ShardingSphere DataSource
  3. 透明分片:应用代码像使用普通 JDBC 一样操作数据库,ShardingSphere-JDBC 在底层透明处理分片逻辑。

这种架构结合了 Kubernetes 的容器编排、Operator 的数据库自动化管理能力和 ShardingSphere-JDBC 强大的数据分片扩展能力,非常适合需要在云原生环境下构建大规模、高性能、可扩展的数据库应用的场景。务必做好详细的规划、测试和监控。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值