RDS MySQL数据库代理在读写(读写分离)模式下提供了三种一致性级别:最终一致性、会话一致性和全局一致性。本文介绍三种一致性级别的基本功能和适用场景,帮助您根据实际业务需求选择合适的一致性级别。
关于RDS数据库代理的使用问题和更多相关信息,欢迎加入用户钉钉群(106730000316)进行咨询、反馈和交流 。
背景信息
RDS MySQL使用Binlog复制来同步主节点和只读节点的数据。当主节点提交事务时,产生的Binlog Event会被发送到只读节点,只读节点通过接收和应用Binlog Event来实现和主节点的数据同步。虽然基于Binlog复制确保了最终一致性,但在高并发或高负载情况下,只读节点上的数据可能出现延迟,导致从只读节点上读到的数据不一致。
为了解决数据不一致问题,RDS MySQL数据库代理提供了三种一致性级别:最终一致性、会话一致性和全局一致性。您可以根据业务需求选择合适的一致性级别。
一致性介绍
功能介绍
RDS MySQL数据库代理默认采用最终一致性级别,在Binlog复制不中断的情况下,读请求直接发送到只读节点。由于只读节点的数据在Binlog复制下是最终一致的,因此代理上的读请求也是最终一致的。RDS MySQL代理支持设置延迟阈值,限制只读实例的最大延迟时间。一旦只读节点的延迟超过该阈值,读请求将不再被发送到该节点。
设置最终一致性会话后,只读节点读取结果如下图所示:
此外,复制延迟可能导致不同只读节点上的数据存在差异。例如,在一个会话中连续执行如下查询,最终查询结果可能有所不同:
SET AUTOCOMMIT = 1;INSERT INTO t1(id, price) VALUES (111, 96);UPDATE t1 SET price = 100 WHERE id = 111;SELECT price FROM t1;
这些查询的结果可能会因复制延迟而有所变化。
适用场景
一致性需求较弱,更希望尽量减轻主节点压力,使更多读请求路由到只读节点时,您可以选择最终一致性。
功能介绍
为应对最终一致性导致查询结果不准确的问题,业务系统通常会将读请求拆分:高一致性要求的读请求发往主节点,低一致性要求的读请求发往只读节点。然而,这种做法不仅增加了应用复杂度,还会使主节点承担更多的读请求,影响读写分离的效果。
为了解决上述问题,RDS MySQL代理提供了会话一致性。与最终一致性直接将读请求发送到只读节点不同,会话一致性下,代理会记录前一个更新操作在主节点上的数据位点(基于GTID确定)。代理仅将读请求发送到已同步该位点数据的只读节点,确保读请求能查询到当前会话中已更新的数据,从而保证会话内的数据一致性。
设置会话一致性后,只读节点读取结果如下图所示:
适用场景
单个会话内存在一致性依赖,推荐使用会话一致性,该级别对性能影响相对较小而且能满足大多数应用场景。
功能介绍
在某些应用场景中,不仅会话内部存在逻辑上的因果依赖关系,不同会话之间也存在依赖关系,要求各会话读取的数据必须完全一致。此时,会话一致性无法满足需求。RDS MySQL代理通过提供全局一致性来解决这一问题。与会话一致性不同,全局一致性下,代理会在每次读操作前记录当前主节点上的数据位点(基于GTID确定),并仅将读请求发送到已完成相应数据位点同步的只读节点,确保读请求能查询到所有会话已更新的数据,从而保证了全局数据的一致性。
设置全局一致性后,只读节点读取结果如下图所示:
适用场景
会话间存在一致性依赖,并且业务为读多写少的场景,建议使用全局一致性。
关于会话一致性和全局一致性的实现原理,请参见附录:会话一致性和全局一致性实现原理。
选择一致性级别
一致性级别越高(全局一致性 > 会话一致性 > 最终一致性),读写分离性能越低。
一般情况下,推荐使用会话一致性,不仅对性能影响较小,且能满足大多数应用场景的需求。
如果不同会话间需要较高的一致性,并且写入压力不大,可以选择全局一致性。
一致性级别 | 对读写分离性能影响 | 数据一致性强度 | 数据一致性范围 |
一致性级别 | 对读写分离性能影响 | 数据一致性强度 | 数据一致性范围 |
最终一致性 | 无 | 低 | 最终结果一致 |
会话一致性 | 中 | 中 | 单个会话内一致 |
全局一致性 | 高 | 高 | 跨会话一致 |
设置一致性级别
前提条件
数据库代理的读写属性为读写(读写分离),详情请参见设置读写属性和读权重。
RDS MySQL实例版本为8.0或5.7,且内核小版本满足:
MySQL 5.7需大于等于20210630。
MySQL 8.0需大于等于20210930。
注意事项
当使用会话一致性或全局一致性时,代理需要等待数据位点同步(最大等待时间为一致性读超时时间),这可能导致业务延迟增加。
如果只读节点存在复制延迟,使用全局一致性可能会使更多读请求路由到主节点,导致主节点负载增大,并进一步增加业务延迟。
一致性级别默认值为最终一致性。
操作步骤
访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
在左侧导航栏,单击数据库代理。
在连接信息区域,在目标代理连接地址的操作列,单击修改配置。
根据需求选择一致性级别。
当选择最终一致性或会话一致性级别时,可以按需开启延迟阈值。默认开启的延迟阈值为30 s。
当选择会话一致性或全局一致性级别时,可以按需设置一致性读超时时间,如果不设置,默认值为10 ms。
附录:会话一致性和全局一致性实现原理
为了实现会话一致性和全局一致性,RDS MySQL代理记录每个只读节点的Executed_Gtid_Set
(已提交事务集合),以确定每个只读节点上的数据位点(GTID,全局事务号)。在每次读请求开始前,代理会设置读请求所需的GTID,并将读请求路由至已达到该GTID位点的只读节点。若只读节点未满足GTID要求,则等待其同步至指定的GTID位点后再进行路由。RDS MySQL代理支持通过设置一致性读超时时间来限定最大等待时间,若超时内无符合GTID位点的只读节点,则请求将被发送到主节点。
读请求所需的GTID根据一致性级别不同而变化:
会话一致性:当前会话中最新执行事务对应的GTID。
全局一致性:当前集群中最新执行事务对应的GTID。
相关API
API | 描述 |
API | 描述 |
查询RDS实例数据库代理详细信息。 | |
查询RDS实例数据库代理的连接地址信息。 | |
修改RDS实例数据库代理连接地址访问策略。 |
- 本页导读 (1)
- 背景信息
- 一致性介绍
- 选择一致性级别
- 设置一致性级别
- 前提条件
- 注意事项
- 操作步骤
- 附录:会话一致性和全局一致性实现原理
- 相关API