读写分离集群开发原则

本章节主要介绍 DM 数据库读写分离集群在使用过程中需要注意事项。

读写分离集群

读写分离集群是基于即时归档或实时归档实现的高性能数据库集群,不但提供数据保护、容灾等数据守护基本功能,还具有读写操作自动分离、负载均衡等特性。读写分离集群最多可以配置 8 个即时备库或 8 个实时备库,提供数据同步、备库故障自动处理、故障恢复自动数据同步等功能,也支持自动故障切换和手动故障切换两种守护模式。

适用场景

软件 版本
操作系统 Redhat 7 及以上版本
DM 数据库 DM 8.0 及以上版本
CPU 架构 x86、ARM、龙芯、飞腾等国内外主流 CPU

系统概述

在一个高并发的事务型系统中,当写事务占的比例相对读事务相对较小时,可以借助 DM 数据库的主备系统备机可读的特点,将读事务转移到备机执行,减少单节点的并发压力,通过增加备机节点资源,提高系统的并发能力,增强系统性能。

DM 数据库提供一种独具创新的主备方案,即时归档主备系统,该系统可通过客户端来实现读写事务的自动分离,读事务在备机执行,写事务在主机执行,减轻主机的负载。备机可以配置多个,备机配置的越多,更能分担主机的压力,系统整体并发效率越高。

读写分离流程

DM 数据库使用 JDBC 驱动与服务器结合的方式实现读写分离,大致流程如下:

  • 用户登录后,客户端首先连接到主机,主机根据即时归档的配置,获取一个有效的备机信息,并返回给客户端。
  • 客户端根据主机返回的备机 IP 和端口,建立与该备机的连接。
  • 客户端执行语句时先在备机上执行,如果是只读事务,则只在备机上执行。
  • 如果系统收到客户端试图在备机模式下修改数据等错误,则说明该事务是写事务,则转移到主机上执行。
  • 一旦主机上执行的写事务提交,则下次继续从备机开始执行。
  • 为了实现负载均衡,防止出现读事务过多占用备机资源、主机空闲的情况,客户端采用一定的算法进行均衡,主机上也会执行一部分读事务。

读写分离流程图:

读写分离

归档流程

读写分离集群可以配置为即时归档,也可以配置为实时归档,这两种配置方式仅仅是归档流程上有差别,读写分离集群的特性仍然是一致的。即时归档流程与实时归档流程差异如下:

  • 主库先将日志写入本地联机 REDO 日志文件中,再发送 RLOG_PKG 到备库。
  • 备库日志重演时机有两种选择:
    • 事务一致模式。要求备库在重演 REDO 日志完成后再响应主库。
    • 高性能模式。与实时归档一样,收到 REDO 日志后,马上响应主库。
  • 即时归档的同步机制可以保证备库的 REDO 日志不会比主库的 REDO 日志多,因此即时备库不需要 KEEP_PKG,收到 RLOG_PKG 直接加入到 Apply 任务系统,启动 REDO 日志重演。
  • 备库故障或主备库之间网络故障,导致发送 RLOG_PKG 失败后,主库马上修改即时归档为 Invalid 状态,并切换数据库为 Suspend 状态。
  • 即时归档修改为 Invalid 状态后,会强制断开对应此备库上存在影子会话的用户会话,避免只读操作继续分发到该备库,导致查询数据不一致。

即时归档流程图:

读写分离

事务一致性

读写分离集群通过 JDBC、DPI 等接口自动分发语句,一个事务包含的多个语句可能分别在备库和主库上执行,但执行结果与单独在一个数据库实例上完全一致,满足读提交事务隔离级特性。

  • 数据准备和说明,如下所示:
//数据准备,创建表 T
CREATE TABLE T(C1 INT);
//事务开始
SELECT * FROM T;          --首先在备库上执行
INSERT INTO T VALUES(1);  --写操作转移到主库上执行
SELECT * FROM T;          --事务未提交,还在主库上执行
COMMIT;                   --事务提交
SELECT * FROM T;          --事务已提交,重新转移到备库上执行
//代码准备。代码1
UPDATE T SET C1 = 2;
COMMIT;
//代码2
RS = SELECT C1 FROM T;
FETCH C1 FROM RS INTO VAR_X;
INSERT INTO TX VALUES(VAR_X);
COMMIT;

根据读写分离特性,代码 1 的 UPDATE 在主库执行;代码 2 的 SELECT 语句在备库执行,INSERT 语句转到主库执行,并且代码 2 的 INSERT 语句的插入值,是从之前执行的 SELECT 结果集中获取。

根据即时归档流程,结合代码 2 执行 SELECT 语句时机和代码 1 的不同状态进行详细地说明读写分离集群是如何实现提交事务隔离级别的。

  • 第一种情况,代码 2 执行 SELECT 时,代码 1 的 COMMIT 还未执行。

代码 2 的 SELECT 语句,无论是在主库还是备库执行,查询结果都是代码 1 更新 T 表之前的值,var_x = 1。

  • 第二种情况,代码 2 执行 SELECT 时,代码 1 的 COMMIT 已经执行完成。

代码 2 的 SELECT 语句,无论是在主库还是备库执行,查询结果都是代码 1 更新 T 表后的值,var_x = 2。

  • 第三种情况,代码 2 执行 SELECT 时,代码 1 正在执行 COMMIT。

代码 2 的 SELECT 查询结果,与两个语句在系统内部的执行顺序有关,var_x 的值可能是 1 或者 2。但由于代码 1 的 COMMIT 并没有明确响应用户,var_x 的最终值取决于数据库管理系统的实现策略,无论返回 1 还是 2,都符合提交事务隔离级。

注意

为了保证主备库一致性,下列类型语句不会在备库执行,在主库内执行。

  1. 设置会话、事务为串行化隔离级语句。
  2. 表对象上锁语句 (LOCK TABLE XX IN EXCLUSIVE MODE)。
  3. 查询上锁语句 (SELECT FOR UPDATE)。
  4. 备份相关系统函数。
  5. 自治事务操作。
  6. 包操作。
  7. 动态视图查询。
  8. 设置自增列操作语句 (SET IDENTITY_INSERT TABLE ON)。
  9. 临时表查询。
  10. 访问@@IDENTITY、@@ERROR 等全局变量。
  11. SF_GET_PARA_STRING_VALUE、SF_GET_PARA_DOUBLE_VALUE 等函数。

性能调整

  • 根据读写分离语句分发流程可以发现,当一个应用系统中只读事务占绝大多数情况下,可能出现备库高负载、高压力,主库反而比较空闲的情况。

为了实现负载均衡,更好地利用主备库的硬件资源,JDBC 等数据库接口提供了配置项,允许将一定比例的只读事务分发到主库执行。因此,用户应该根据主备库的负载情况,灵活调整接口的分发比例 rw_Percent 配置项,以获得最佳的数据库性能。

  • 备库数量是影响读写分离集群性能的一个重要因素,备库越多则每个备库需要承担的任务越少,有助于提升系统整体并发效率。

但是在事务一致模式下,主库要等所有备库重演 REDO 日志完成后,才能响应用户,随着备库的增加,即时归档时间会变长,最终降低非只读事务的响应速度。因此,部署多少备库,也需要综合考虑硬件资源、系统性能等各种因素。

  • 配置为高性能模式,则是提升读写分离集群的另一个有效手段。

如果应用系统对查询结果实时性要求并不太高,并且事务中修改数据的操作也不依赖同一个事务中的查询结果。那么,通过修改 dmarch.ini 中的 ARCH_WAIT_APPLY 配置项为 0,将读写分离集群配置为高性能模式,可以大幅提高系统整体性能。

注意

以下代码逻辑,不适合使用高性能模式。

//事务1
INSERT INTO T VALUES(1);                    --写操作在主库上执行
COMMIT;                                     --事务提交
//事务2
SELECT TOP 1 C1 INTO VAR1 FROM T;           --事务 1 已提交,SELECT 操作重新转移到备库上执行。高性能模式下备库可能还没有重做日志,查不出事务 1 中插入的数据
UPDATE T SET C1 = VAR1 + 1 WHERE C1 = VAR1; --更新不到数据

根据读写分离特性合理地规划应用的事务逻辑,也可以获得更佳的性能,建议如下:

  • 尽可能将事务规划为只读事务和纯修改事务,避免无效的备库试错。
  • 读操作尽量放在写操作之前,用备库可读的特点来分摊系统压力。

实时归档的读写分离

  • 实时主备也可以配置接口的读写分离属性进行访问,实现读写分离功能特性。
  • 实时读写分离同样也支持事务一致模式和高性能模式,由配置文件 dmarch.ini 中的ARCH_WAIT_APPLY 配置项来确定,1 表示事务一致模式,0 表示高性能模式,实时读写分离下,默认值为 0,即采用高性能模式。
  • 和即时归档不同的是,实时归档先发送日志到备库,然后再写入本地联机日志,和即时归档相比,实时归档的读写分离可以有效避免备库自动接管后老主库的分裂,在对读写分离集群的可用性要求比较高的情况下,可以采用这种配置方式。
注意

实时读写分离的事务一致模式仅在数据守护配置为自动切换模式下才会生效

参考文献

更多 SQL 语言使用说明,请参考《DM_SQL 语言使用手册》,手册位于数据库安装路径 /dmdbms/doc 文件夹下。如有其他问题,请在社区内咨询。

微信扫码
分享文档
扫一扫
联系客服