0
点赞
收藏
分享

微信扫一扫

分布式数据库选型测试(三)——模拟实战

非凡兔 2022-05-11 阅读 81


原生的分布式数据库体验

分布式数据库产品都尽力给用户一种接近单实例数据库的使用体验,如原生的 SQL 和事务。在分布式数据库中间件的功能发展历史中可以看出这方面的进展。早期的 DRDS 产品里,对 SQL 有很多限制。比如说分片字段不支持多个字段组合、SQL不能跨分片(分表或分库)做表连接或者性能不好、SQL 语法有些限制(如不支持复杂的子查询、统计分析等等)。后来 SQL 支持跨分片查询,并且支持一些执行计划算子下推优化。只是设计上隐藏了一个问题,各个分片都是独立查询数据并返回到中间件节点内部聚合计算再返回。各个分片的数据严格来说并不是同一个快照(即同一个事务版本SCN之前的合法数据,合法指的是遵循某种事务隔离级别,如 READ COMMITTED 或 REPEATABLE READ )。再往后发展成熟的 DRDS 产品声称支持分布式 MVCC,能提供一致性快照读。然而效果如何没有好的办法检验。事务方面一开始也是不支持分布式事务,后来支持分布式事务但是需要特殊的开启语法或者引入分布式事务中间件,以及事务是最终一致性方案(如 TCC)。到最后成熟的产品把分布式事务中间件跟分库分表中间件融合在一起,自动判断是否有分布式事务并支持强一致。理论上分布式事务要满足 ACID,必须使用两阶段提交协议。有些产品在中间件层接管事务(如GTM),使用一阶段提交协议和自己实现多版本,提供 ACID 的效果。在底层数据库层面,各个参与者(数据库)都是本地事务直接提交。产品并不希望用户绕过GTM 访问数据(那样可能读到业务层面尚未提交的事务数据)。如果有参与者故障,业务事务需要回滚,GTM 利用自己的 Undo 构造逆向SQL 去回滚底层事务已经提交的实例里的数据。节点故障引起的麻烦并不只是部分参与者实例的事务要回滚,还有故障实例的主备实例之间的一致性和同步状态。传统的商业数据库(ORACLE、DB2、SQLServer)都有 Redo 和 Undo 设计,在实例故障后拉起时,有相应的崩溃恢复逻辑(即重做故障点附近的全部事务日志,然后再回滚未提交的事务日志)。这些数据库在稳定状态下其事务日志和数据是保持一致性状态。这符合 Writing Aheaad Logging 机制的设计目的,关键点是日志要及时落盘。然而 MySQL 数据库插件式引擎设计改变了这个设计。在 MySQL 有两套事务日志系统,一是 Server 层 Binlog,二是 Innodb 的 Redolog。MySQL 试图使用本地两阶段提交协议去保证这两套日志系统对一个业务事务的变更是一致的。不过 Binlog 只记录已提交的事务日志,不记录未提交的事务(没有 Undo 逻辑)。Innodb的 Redolog 才记录了全部的事务日志(包括未提交的事务及其 Undo 日志)。在 Binlog 和 Redolog 的持久化上,二者并不一致且有多种落盘策略。让实际情况变得更复杂的是 MySQL 主备复制同步的是 Binlog。主备在事务日志持久化上也可能不一样。所以 MySQL 在宕机恢复后有一定概率出现丢数据或者主备数据不一致、复制中断。GTID 和半同步技术也不能彻底解决所有的复制中断问题。基于 MySQL 数据库构建的分布式数据库,在节点故障时想把故障处理做到对用户完全透明,这个挑战还是非常大的。产品并不希望用户了解这些细节。包括 SQL 和事务的内部执行细节。用户如果是开发,往往也乐意如此,只要能用就行。这种透明往往只能做到对开发透明,对运维就不一定了。当分布式数据库到一定规模或者压力上去后,深入的性能调优、故障处理都不可避免的要接触到内部细节。即一个多组件集成的自动化的分布式数据库解决方案。

‍‍

生产环境特点

用户可以不了解分布式数据库产品细节,但一定了解数据库上线后的生产环境特点。后期POC测试案例设计要尽可能跟生产环境特点接近。

生产环境往往有下面这些特点:

  • 表都有一定数据量,特别是核心表。这些表有可能要做变更(加字段、加索引等、备份导出)。大表加字段或索引比较耗时,有一定操作风险。
  • 跑批业务,有大量数据写入或更新。
  • 卸数业务,有大量数据导出。
  • 业务不可中断,随时都有读写访问。数据库运行中有一定负载有高低峰期,不同时间段变更风险会有些不一样。
  • 数据不能丢,准确的说法是业务相关表数据的业务逻辑始终是保持一致的。
  • 数据库集群有一定规模。运行半年一年后可能面临数据库扩容需求,三年后还可能临机器更新换代问题。
  • x86 服务器可能随时有故障。如果是国产服务器或系统,风险会更高一些。


POC 测试建议POC.测试接近生产特点,模拟生产并不难。只需要考虑下面几点即可。

  • 不在空表或小表上做功能测试。表的数据量不少于5000万。
  • 不在空闲的表或实例上做功能测试。表或实例要有一定的并发读写请求,要把数据库CPU压到约30%左右。
  • 测试自始自终运行业务数据一致性校验。这里面会对相关业务表做业务逻辑检查。功能和性能测试过程中和结束后都抽查校验日志。
  • 不孤立的做高可用测试,而是在每个功能测试和性能测试过程中随机加入节点故障事件。观察业务恢复情况,业务数据一致性,运维处理工作等。故障时丢数据和主备不一致是小概率事件,一次故障测试可能无法发现问题。
  • 不孤立的做功能测试,而是在测试中加入业务负载和随机故障,观察业务数据一致性、业务恢复和运维恢复过程。
  • 不孤立的做性能测试,在性能测试过程中和故障前后校验业务数据一致性,随机加入节点故障测试。


其他参考

  • ​​分布式数据库选型测试(一)——测试需求​​
  • ​​分布式数据库选型测试(二)——测试环境​​
  • ​​分布式数据库选型——数据水平拆分方案​​​​
  • ​​说说数据库事务和开发(下)—— 分布式事务​​



举报

相关推荐

0 条评论