POLARDB for MySQL集群自带读写分离功能。应用程序只需连接一个集群地址,写请求会自动发往主节点,读请求会自动根据各节点的负载(当前未完成的请求数)发往主节点或只读节点。

功能优势

  • 读一致性

    在POLARDB的链路中间层进行读写分离时,中间层会追踪(track)各个节点已经应用(apply)的重做日志(redolog)位点,即日志序号(LSN);同时,每次数据更新时将此次更新的位点记录为Session LSN。当POLARDB收到新的请求时,将Session LSN与各个节点的LSN进行比较,仅将请求发往LSN早于Session LSN的节点,从而保证会话的一致性。表面上看该方案可能导致主库压力大,但是因为POLARDB是物理复制,速度极快,在上述场景中,当更新完成后,返回客户端结果时复制就同步在进行,而当下一个读请求到来时主从极有可能已经完成,然后大多数应用场景都是读多写少,所以经验证在该机制下即保证了会话一致性,也保证了读写分离负载均衡的效果。


    示意图
  • 原生支持读写分离,提升性能

    如果您在云上通过自己搭建代理层实现读写分离,在数据到达数据库之前需要经历多个组件的语句解析和转发,对响应延迟有较大的影响。而POLARDB读写分离在已有的高安全链路中直接内置,没有任何额外的组件来消耗时间,能够有效降低延迟,提升处理速度。

  • 维护方便

    在传统模式下,您需要在应用程序中配置主节点和每个只读节点的连接地址,并且对业务逻辑进行拆分,才能实现将写请求发往主节点而将读请求发往各个节点。

    POLARDB提供集群地址,应用程序连接该地址后即可对主节点和只读节点进行读写操作,读写请求会被自动转发,转发逻辑完全对使用者透明,可降低维护成本。

    同时,您只需添加只读节点的个数,即可不断扩展系统的处理能力,应用程序无需做任何修改。

  • 节点健康检查,提升数据库系统的可用性

    读写分离模块自动对集群内的所有节点进行健康检查,当发现某个节点宕机或者延迟超过阈值后,将不再分配读请求给该节点,读写请求在剩余的健康节点间进行分配。以此确保单个只读节点发生故障时,不会影响应用的正常访问。当节点被修复后,POLARDB会自动将该节点纳回请求分配体系内。

  • 免费使用,降低资源及维护成本

    免费提供读写分离功能,无需支付任何额外费用。

转发逻辑

  • 可读可写模式转发逻辑:
    • 只发往主节点
      • 所有DML操作(INSERT、UPDATE、DELETE)。
      • 所有DDL操作(建表/库、删表/库、变更表结构、权限等)。
      • 所有事务中的请求。
      • 用户自定义函数。
      • 存储过程。
      • EXECUTE语句。
      • Multi Statements
      • 使用到临时表的请求。
      • SELECT last_insert_id()。
      • 所有对用户变量的查询和更改。
      • SHOW PROCESSLIST。
      • KILL(SQL语句中的KILL,非命令KILL)。
    • 发往只读节点或主节点
      • 非事务中的读请求。
      • COM_STMT_EXECUTE命令。
    • 总是发往所有节点
      • 所有系统变量的更改。
      • USE命令。
      • COM_STMT_PREPARE命令。
      • COM_CHANGE_USER/COM_QUIT/COM_SET_OPTION等命令。
  • 只读模式转发逻辑:
    • 不允许执行DDL、DML操作。
    • 所有请求按照负载均衡的方式转发到各只读节点。
    • 所有请求不会转发到可读可写节点。

使用限制

  • 若执行了Multi Statements或存储过程,当前连接的后续请求会全部路由到主节点,需断开当前连接并重新连接才能恢复读写分离。
  • 集群地址在只读模式下,不支持set环境变量, 例如set @endtime=now(); select * from tab where dt < @endtime, 可能导致查询无法获得正确的环境变量。
  • 使用视图时无法保证会话一致性,例如CREATE VIEW tab2 AS SELECT * FROM tab1; INSERT INTO tab1(key, value) (1, 1); SELECT * FROM tab2 where key=1;可能会因为延迟而查不到结果。

申请或修改集群地址

  1. 进入POLARDB控制台
  2. 选择地域。
  3. 找到目标集群,单击集群名称列的集群ID
  4. 基本信息访问信息里找到集群地址(推荐)
  5. 单击申请,在弹出的对话框中单击确认,刷新后即可看到集群地址。
    说明 存量集群若未申请集群读写分离连接地址的需要手动申请集群地址,新购集群自动开通集群地址。若已有集群地址,请直接查看第6步。
  6. 单击修改,设置新的集群地址,并单击提交
    修改集群地址

FAQs

  1. 为什么刚插入的语句,立即查的时候查不到?

    答:读写分离的架构下,主从复制会有延迟,但POLARDB支持会话一致性,即同一个会话内保证能读到之前的更新。

  2. 为什么只读库没有压力?

    答:默认情况下事务中的请求都会路由到主库,若是用sysbench做压测,0.5版本的sysbench可以加上--oltp-skip-trx=on,1.0版本的sysbench可以加上--skip-trx=on去掉事务,若业务上因为事务较多导致只读库负载过低,可以提交工单开启读写分离下的分布式事务。

  3. 为什么某个节点的请求数比别的节点多?

    答:当前是根据负载来分发请求的,负载小的节点接收的请求数会更多。

  4. 是否支持0毫秒延迟的读取?

    答:POLARDB集群的主节点和只读节点在正常负载情况下,具有毫秒级的延迟,读写分离连接地址暂时不支持在数据写入后0毫秒的读取。如果要求0毫秒延迟的读取,可使用主地址(动态指向POLARDB主节点)将读写请求发给主节点。

  5. 新增的只读节点会自动加入到读写分离吗?

    新增只读节点之后新建的读写分离连接会转发请求到该只读节点。新增只读节点之前建立的读写分离连接不会转发请求到新增的只读节点,需要断开该连接并重新建立连接,例如,重启应用。

相关API

API 描述
CreateDBEndpointAddress 创建POLARDB集群的公网地址
CreateDBClusterEndpoint 创建POLARDB自定义集群地址
DescribeDBClusterEndpoints 查询POLARDB集群的地址信息
ModifyDBClusterEndpoint 修改POLARDB集群地址属性
ModifyDBEndpointAddress 修改POLARDB集群默认访问地址前缀
DeleteDBEndpointAddress 释放POLARDB集群地址(除了自定义集群地址的私网地址)
DeleteDBClusterEndpoint 释放POLARDB自定义集群地址