Apache ShardingSphere 的读写分离功能

Apache ShardingSphere 的读写分离功能

核心目标: 将数据库的写入操作(INSERT, UPDATE, DELETE)定向到主库(Master),将查询操作(SELECT)定向到从库(Slave),从而提升系统的读性能和整体吞吐量,缓解单点数据库的压力。

核心概念

  1. 主库 (Primary / Master): 负责处理所有写操作(DML)和事务性读操作的核心数据库。通常只有一个(或一个活跃的主库)。
  2. 从库 (Replica / Slave): 通过主从复制(如 MySQL Replication, PostgreSQL Streaming Replication)从主库异步或半同步复制数据的数据库。主要负责处理读操作(查询)。可以有多个,用于负载均衡和高可用。
  3. 读写分离数据源: ShardingSphere 在应用层创建的一个逻辑数据源。应用通过 JDBC 连接这个逻辑数据源,ShardingSphere 根据 SQL 类型自动路由到背后的真实主库或某个从库。

ShardingSphere 读写分离实现原理

  1. 配置:

    • 定义真实数据源: 配置一个主库数据源(primaryDataSourceName)和多个从库数据源(replicaDataSourceNames)。
    • 配置负载均衡策略: 指定当有多个从库时,如何选择其中一个来处理读请求。内置策略:
      • ROUND_ROBIN: 轮询。
      • RANDOM: 随机。
      • WEIGHT: 基于权重的负载均衡(需配置权重)。
      • 自定义策略: 实现 ReplicaLoadBalanceAlgorithm 接口。
    • 配置规则 (ReadwriteSplittingRuleConfiguration): 将真实数据源、主库名、从库名列表、负载均衡策略组合成一个逻辑数据源(readwriteSplittingDataSourceName)的规则。
  2. SQL 解析与路由:

    • 应用向 ShardingSphere 的逻辑数据源发起 SQL 请求。
    • ShardingSphere 的 SQL 解析引擎解析 SQL 语句,判断其类型:
      • 写操作 (INSERT, UPDATE, DELETE, DDL): 强制路由到主库。
      • 读操作 (SELECT): 路由到配置的从库池中的一个从库(根据负载均衡策略选择)。
    • 特殊情况:
      • 事务内的读操作: 为了保证事务内读取到最新写入的数据(避免主从延迟导致的不一致),默认情况下,事务内的所有查询也会被路由到主库。这是关键点!
      • Hint 强制主库路由: 即使是非事务中的读操作,如果业务要求必须读取绝对最新的数据(如刚写入后立即查询),可以使用 ShardingSphere 提供的 Hint 管理器 (HintManager) 强制将当前查询(或后续一系列操作)路由到主库。例如:
        try (HintManager hintManager = HintManager.getInstance()) {
            hintManager.setWriteRouteOnly(); // 强制后续操作走主库
            // 执行你的查询语句,此时会路由到主库
        }
        
      • 非事务内且无 Hint 的读操作: 正常路由到从库。
  3. SQL 执行:

    • 根据路由决策,ShardingSphere 通过对应的数据库驱动,获取到目标主库或从库的真实数据库连接。
    • 将 SQL 语句通过该连接发送到真实的数据库执行。
  4. 结果归并:

    • 对于读操作(SELECT),ShardingSphere 接收从库返回的结果集。
    • 由于读写分离通常只路由到一个从库(不像分片会路由到多个库),所以这里的结果归并相对简单,主要是将单个结果集封装返回给应用。如果是分库分表+读写分离的组合场景,归并会更复杂。

核心优势

  1. 提升读性能: 将读压力分散到多个从库,显著提升系统的查询吞吐量和响应速度。
  2. 提升整体吞吐量: 主库专注于写操作和关键事务读,从库处理大量查询,系统整体处理能力增强。
  3. 高可用基础: 在主库故障时,可以快速将一个从库提升为新的主库(通常需要配合数据库本身的主从切换机制和 ShardingSphere 的高可用配置),提高系统可用性。读写分离本身不直接提供故障切换,但为高可用架构奠定了基础。
  4. 透明性: 对应用代码基本无侵入。应用像使用单个数据库一样使用逻辑数据源,路由细节由 ShardingSphere 屏蔽。

重要注意事项

  1. 数据延迟: 这是读写分离架构的 核心挑战。主从复制是异步或半同步的,从库的数据相对于主库存在一定延迟(几毫秒到几秒甚至分钟,取决于网络、负载、复制机制)。应用必须能容忍这种延迟:
    • 刚写入的数据可能查不到: 写入主库成功后立即查询从库,可能查不到刚写入的数据。
    • 解决方案:
      • 关键读走主库: 对一致性要求高的读操作,使用事务或 Hint 强制路由到主库。
      • 业务容忍: 设计业务逻辑时考虑最终一致性,允许短暂延迟。
      • 监控延迟: 监控主从延迟,延迟过大时告警并可能自动将读切回主库。
  2. 事务内读一致性: 默认事务内读走主库保证了强一致性,但也牺牲了部分读性能扩展。理解这个默认行为非常重要。
  3. 主库压力: 所有写操作和事务内读操作都集中在主库,主库仍然是性能和单点的瓶颈。读写分离主要解决压力。
  4. 从库数量与成本: 增加从库能提升读能力,但也增加硬件成本、维护成本和主库复制压力。
  5. 负载均衡策略选择: 根据从库的硬件配置(权重)或简单的流量分发(轮询/随机)选择合适的策略。

配置方式 (概要 - 具体看文档/YAML示例)

ShardingSphere 支持多种配置方式,核心是定义 ReadwriteSplittingRuleConfiguration

  1. Java 代码配置: 直接使用 ShardingSphere 的 API 构建配置对象 (ReadwriteSplittingRuleConfiguration, ShardingSphereDataSource)。
  2. YAML 配置: (最常用) 在 server.yaml (全局) 或数据源规则配置文件中定义读写分离规则。
    rules:
      - !READWRITE_SPLITTING
        dataSources:
          pr_ds: # 逻辑数据源名称
            writeDataSourceName: primary_ds # 主库数据源名称
            readDataSourceNames: # 从库数据源名称列表
              - replica_ds_0
              - replica_ds_1
            loadBalancerName: round_robin # 负载均衡器名称
        loadBalancers:
          round_robin:
            type: ROUND_ROBIN # 负载均衡器类型
    
  3. Spring Boot Starter: 使用 application.properties/application.yml 配置,格式与 YAML 配置类似,属性名遵循 Spring Boot 的规范。

学习建议与下一步

  1. 动手实践: 搭建一个简单的主从复制环境(如 Docker 启动 MySQL 主从),然后使用 ShardingSphere (JDBC 或 Proxy) 配置读写分离规则。编写测试代码,分别执行写操作和读操作,观察 SQL 实际执行的数据库。特别测试事务内的读操作和 Hint 的效果。
  2. 结合场景思考: 思考你的业务场景中哪些查询可以容忍延迟?哪些查询必须强一致?如何利用 Hint 或事务?
  3. 理解延迟影响: 深刻理解主从延迟可能带来的业务影响,并在设计和开发中规避或处理。
  4. 进阶:
    • 结合分库分表: 读写分离常与分库分表结合使用,构建更强大的分布式数据库解决方案。学习 sharding 规则如何与 readwrite_splitting 规则协同工作。
    • 高可用集成: 了解如何配置数据库发现(如 MGR, Raft)和故障转移,让 ShardingSphere 在主库故障时能感知并切换到新的主库。
    • 数据加密 / 影子库: 了解 ShardingSphere 的其他特性如何与读写分离结合使用。
  5. 查阅官方示例: Apache ShardingSphere GitHub 仓库提供了丰富的读写分离配置和使用示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值