一、DRDS 扩展性原理
并发和存储容量扩展性
扩展性本质在于分而治之,DRDS 通过水平拆分(分库分表)和垂直拆分,将数据分散到多个 RDS for MySQL 以获取数据读写并发和存储容量的分散, 同时 DRDS 层本身是无状态的,如同业务应用,简单扩展节点数量应对并发 SQL 负载。
水平拆分(分库分表)
数据放置按照一定的规则进行计算和路由,从而达到分散到多个 RDS for MySQL 目的,实际上 DRDS 具备相当丰富的算法来应对各种场景的负载。
垂直拆分
垂直拆分是具备业务语义的,比如和交易紧相关的表组成一个交易库,和用户紧相关的表组成一个用户库,和商品紧相关的表组成一个商品库,分别放置在不同或相同的 RDS for MySQL 实例上,也可以针对特别大的库进行水平拆分。
DRDS 垂直拆分能力将不同 RDS for MySQL 实例下的业务库汇聚到一个连接下,业务可以通过一个连接,操作不同库的数据,也可以横跨多个 RDS 实例数据库进行联合查询及事务写入操作。
计算扩展性
无论是水平拆分,还是垂直拆分,DRDS 常常碰到需要对远超单机容量数据进行复杂计算的需求,这些 SQL 包括多表 join、多层嵌套子查询、grouping、sorting、aggregation 等组合。针对这类在线数据库上复杂 SQL 的处理, DRDS 额外扩展了单机并行处理器(SMP,Symmetric Multi-Processing) 和多机并行处理器(DAG),前者完全集成在 DRDS 内核中 , 后者 , DRDS 构建了一个计算集群 ,运行时动态获取执行计划进行分布式计算,通过增加节点提升计算能力。
目前多机并行数据处理的 DRDS 实例以分析型只读实例产品形态提供给业务使用。
二、DRDS 分布式事务
分布式事务通常使用二阶段提交来保证事务的原子性(Atomicity)和一致性(Consistency)。
二阶段事务将事务提交分成准备(PREPARE)和提交(COMMIT)两个阶段:
PREPARE 阶段中,数据节点准备好所有事务提交所需的资源(例如加锁、写日志等);
COMMIT 阶段中,各个数据节点才真正提交事务。
当用户提交一个分布式事务时,DRDS 服务器作为事务管理器的角色,首先等待所有数据节点(MySQL 服务器) PREPARE 成功,之后再向各个数据节点发送 COMMIT 请求。
三、基于 MySQL 5.7 的分布式事务
如果您的 MySQL 版本 ≥ 5.7,并且 DRDS 版本 ≥ 5.3.4 时,将会自动开启 XA 分布式事务,使用体验和单机 MySQL 数据库一致,无需特殊指令开启。
如果不满足上述要求,请您移步 基于 MySQL 5.6 的分布式事务文档。
基本原理
分布式事务的原理请参考文档 DRDS 分布式事务基本原理。
对于 MySQL 5.7 及更高版本,DRDS 默认基于 XA 事务协议进行分布式事务。
如何使用?
DRDS 分布式事务使用体验和单机 MySQL 数据库完全一致,例如:
SET AUTOCOMMIT=0 开启一个事务;
COMMIT 提交当前事务;
ROLLBACK 回滚当前事务。
如果事务中的 SQL 仅涉及单个分片,DRDS 会将其作为单机事务直接下发给 MySQL;如果事务中的 SQL 语句修改了多个分片的数据,DRDS 会自动地将当前事务升级为分布式事务。
常见问题
Q: 使用 DRDS 分布式事务需要在控制台开启吗?
A: 不需要显式开启,只要版本达到要求,即可以直接像单机 MySQL 那样使用事务。
Q: DRDS 分布式事务对版本是否有要求?
A: DRDS 新版分布式事务要求 MySQL 版本 ≥ 5.7、DRDS 版本 ≥ 5.3.4。如果您的 MySQL 或 DRDS 版本不满足上述要求,建议您升级到新版,或查看基于 MySQL 5.6 的分布式事务文档。
四、基于 MySQL 5.6 的分布式事务
基本原理
分布式事务的原理请参考文档 DRDS 分布式事务基本原理。
对于 MySQL 5.6 版本,由于 MySQL XA 协议实现尚不成熟,DRDS 自主实现了 2PC 事务策略用于分布式事务。MySQL 5.7 及更高版本中,推荐您使用 XA 事务策略。
如何使用
如果某个事务可能涉及多个数据分库,则需要将当前事务声明为分布式事务。如果事务仅涉及单个数据分库,则无需开启分布式事务,直接像 MySQL 单机事务那样即可,无需额外操作。
分布式事务开启方式如下:
在事务开启后,执行 SET drds_transaction_policy = ‘…’ 即可。
MySQL 命令行客户端使用示例(以 2PC 事务为例)
SET AUTOCOMMIT=0;
SET drds_transaction_policy = '2PC'; -- 建议 MySQL 5.6 用户使用
.... -- 业务 SQL
COMMIT; -- 或 ROLLBACK
Java JDBC 代码示例(以 2PC 事务为例)
conn.setAutoCommit(false);
try (Statement stmt = conn.createStatement()) {
stmt.execute("SET drds_transaction_policy = '2PC'");
}
// ... 运行业务 SQL ...
conn.commit(); // 或 rollback()
常见问题
如何在 Spring 框架中使用 DRDS 分布式事务?
如果使用 Spring 的 @Transactional 注解开启事务,可以通过扩展事务管理器来开启 DRDS 分布式事务。
代码示例:
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class DrdsTransactionManager extends DataSourceTransactionManager {
public DrdsTransactionManager(DataSource dataSource) {
super(dataSource);
}
@Override
protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition) throws SQLException {
try (Statement stmt = con.createStatement()) {
stmt.executeUpdate("SET drds_transaction_policy = '2PC'"); // 以 2PC 为例
}
}
}
之后,在 Spring 配置中将上述类实例化,例如:
<bean id="drdsTransactionManager" class="my.app.DrdsTransactionManager">
<property name="dataSource" ref="yourDataSource" />
</bean>
对于需要开启 DRDS 分布式事务的类,加上注解 @Transactional(“drdsTransactionManager”) 即可。
五、DRDS 平滑扩容
当逻辑库对应的底层存储已经达到物理瓶颈,需要进行水平扩展,比如磁盘余量接近30%,那么可以通过平滑扩容来改善。
平滑扩容是一种在线水平扩容方式,既把原有的分库平滑迁移到新添加的 RDS 实例上,通过增加 RDS 实例的数量来提升总体数据存储容量,从而降低单个 RDS 实例的处理压力。
具体操作步骤请参考平滑扩容文档。
六、DRDS 读写分离
在主实例的读请求较多、读压力比较大的时候,可以通过 DRDS 读写分离功能对读流量进行分流,减轻 RDS 主实例的读压力。