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

功能优势

  • 读一致性

    当客户端通过读写分离地址与后端建立连接后,读写分离中间件会自动与主节点和各个只读节点建立连接。在同一个连接内(同一个session内),读写分离中间件会根据各个数据库节点的数据同步程度,来选择合适的节点,在保证数据正确的基础上(写操作之后的读有正确的结果),实现读写请求的负载均衡。

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

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

  • 维护方便

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

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

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

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

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

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

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

转发逻辑

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

功能特性

PolarDB的读写分离功能主要包含以下特性。

  • 负载均衡

    PolarDB支持基于负载的自动调度策略,读请求将在多个只读节点中按照活跃连接数自动调度,来保证多个只读节点间的负载均衡。

    负载均衡包括主库是否接受读和事务拆分功能:
    • 主库是否接受读(原主库不接受读)

      开启主库是否接受读后,普通的读请求将不再发往主节点。而事务内,一致性要求的读请求还是会被发往主节点,以保证业务的需求。另外,当所有只读节点出现故障后,读请求也会发往主节点。如果业务对一致性的要求较低,可以通过设置一致性级别为最终一致性来减少读请求到主节点,也可以通过事务拆分功能来减少真正事务前的读请求发往主节点。 广播的请求(例如SET或PREPARE)还是会被发往主节点。

      说明
      • 仅当读写模式可读可写(自动读写分离)时,支持设置主库是否接受读配置。主库是否接受读功能默认关闭,如何修改主库是否接受读设置,请参见配置数据库代理
      • 主库是否接受读配置更改后会立即生效。
    • 事务拆分

      开启事务拆分前,数据库代理会将事务内的所有请求都发送到主节点来保证一个会话连接中事务读写的一致性,但这会导致主节点负载过大。开启事务拆分后,数据库代理会识别当前事务的状态,在保证业务中读写一致性的前提下,将正式启动事务前的读请求通过负载均衡模块分流至只读节点。详情请参见事务拆分

  • 一致性级别

    由于PolarDB使用异步复制的方式进行主从同步,该模式在读写分离模式下,可能出现一个写请求之后的读请求无法获得最新的写结果,导致不一致。PolarDB提供了最终一致性、会话读一致性以及全局一致性级别供您选择,详情请参见一致性级别

  • 连接池

    PolarDB支持会话级连接池和事务级连接池,您可以根据业务场景选择合适的连接池,帮助降低因大量连接导致的数据库负载压力,详情请参见连接池

  • 连接保持

    PolarDB新增支持连接保持功能,避免由于一些运维操作(如升级配置、主备切换或升级小版本等)或非运维操作故障(如节点所在服务器故障)导致的连接闪断或新建连接短暂失败的问题,进一步提高PolarDB的高可用性。具体请参见连接保持

Hint语法使用说明

PolarDB支持如下Hint语法:
注意
  • Hint的路由优化级别最高,不受一致性级别和事务拆分的约束,使用前请进行评估。
  • 仅读写模式为可读可写(自动读写分离)的集群地址支持Hint语法,只读模式下的集群地址和主地址均不支持Hint语法。关于集群地址的读写模式信息,请参见集群地址的读写模式
  • 支持在SQL语句前加上/*FORCE_MASTER*//*FORCE_SLAVE*/强制指定这条SQL的路由方向。

    例如select * from test默认会路由到只读节点,改为/*FORCE_MASTER*/ select * from test就会路由到主节点。

  • 支持在SQL语句前加上/*force_node='<节点ID>'*/强制指定在某节点执行某查询命令。

    例如/*force_node='pi-bpxxxxxxxx'*/ show processlist,该show processlist命令只在pi-bpxxxxxxxx节点执行。如果该节点发生故障,则返回报错force hint server node is not found, please check.

  • 支持在SQL语句前加上/*force_proxy_internal*/set force_node = '<节点ID>'强制指定在某节点执行所有查询命令。

    例如/*force_proxy_internal*/set force_node = 'pi-bpxxxxxxxx',执行该命令后,后续所有查询命令只发往pi-bpxxxxxxxx节点,如果该节点发生故障,则返回报错set force node 'rr-bpxxxxx' is not found, please check.

    说明
    • 若您需要通过MySQL官方命令行执行上述Hint语句,请在命令行中加上-c参数,否则该Hint会被MySQL官方命令行过滤导致Hint失效,具体请参见MySQL官方命令行
    • 通常不建议使用/*force_proxy_internal*/语法,会导致后续所有查询请求都发往该节点,读写分离失效。
    • Hint语句里不要有改变环境变量的语句,例如/*FORCE_SLAVE*/ set names utf8; 等,这类语句可能导致后续的业务出错。