云计算
近日,腾讯云发布了分布式数据库解决方案(dcdb),其最明显的特性之一就是提供了高于开源分布式事务xa的性能。大型业务系统有着用户多、并发高的特点,在这方面,集中式数据库(单机数据库)的性能很难支持,因此主流的互联网公司往往采用分布式(架构)数据库,物理上利用更多的低端设备,逻辑上对大表水平拆分支撑业务的需要。
虽然分布式数据库能解决性能难题,但事务一致性(consistency)的问题,却很难在分布式数据库上得到解决。
分布式事务老大难题,数据一致难以实现
众所周知,一个事务所做的更新,分布式数据库系统内部多个独立的数据节点完成(每个节点的本地事务是这个全局事务的一个事务分支),在这样一个全局事务提交期间,有可能某些事务分支无法成功提交。
针对这一问题,虽然业内早已存在理论解决方案——二阶段提交协议(简称2pc),并延伸出分布式事务(简称xa)的解决方案。但业内却少有工程化实现且大规模应用的案例。而腾讯云分布式数据库dcdb,却已在内部业务中应用多年。
(图:二阶段提交算法)
目前dcdb已应用在腾讯内部90%%u4ee5上的交易、计费业务,并且三一重工(树根互联)、汇通天下(g7)、阅文集团(起点/创世中文网等)、微众银行、和泰人寿、威富通等都在该产品。
腾讯云首发分布式数据库xa,支持mysql 5.7
腾讯云分布式数据库dcdb,是基于腾讯金融级数据库(公司内部代号tdsql)云化改造而来的兼容mysql协议的分布式数据库。现如今,腾讯云dcdb已经正式在mysql 5.7(percona分支)协议上支持分布式事务xa,并已在腾讯云公有云、金融云发布供开发者使用。开发者可以通过申请dcdb实例,并在初始化后,连接实例运行如下sql进行初始化:
mysql> xa init;
query ok, 0 rows affected (0.03 sec)
注意:初始化xa前,请开启强同步复制能力,另外该sql会创建xa.gtid_log_t,用户在后续使用中万勿对其进行任何操作。。
为更好的支持分布式事务,dcdb还新增了sql命令:
1) select gtid(),获取当前分布式事务的gtid(事务的全局唯一性标识),如果该事务不是分布式事务则返回空;
gtid的格式:
‘网关id’-‘网关随机值’-‘序列号’-‘时间戳’-‘分区号’,例如 c46535fe-b6-dd-595db6b8-25
2) select gtid_state(“gtid”),获取“gtid”的状态,可能的结果有:
a) “commit”,标识该事务已经或者最终会被提交
b) “abort”,标识该事务最终会被回滚
c) 空,由于事务的状态会在一个小时之后清楚,因此有以下两种可能:
1) 一个小时之后查询,标识事务状态已经清除
2) 一个小时以内查询,标识事务最终会被回滚
3) 运维命令:
xa recover:向后端set发送xa recover命令,并进行汇总
xa lockwait:显示当前分布式事务的等待关系(可以使用dot命令将输出转化为等待关系图)
xa show:当前网关上正在运行的分布式事务
以python为例,可以对转账业务进行如下编码:
db =
pymysql.connect(host=testhost, port=testport, user=testuser, password=testpassword,
database=testdatabase)
cursor = db.cursor()
try:
cursor.execute(begin)
#为一个账户bob的余额减1
query = update
t_user_balance set balance = balance – 1
where user=\\\’bob\\\’ and balance>1)
affected =
cursor.execute(query)
if affected == 0: #余额不足,回滚事务
cursor.execute(rollback)
return
#为一个账户john的余额加1
query = update
t_user_balance set balance = balance 1
where user=\\\’john\\\’)
cursor.execute(query)
# 为了安全起见,建议在这里执行‘select gtid()’获取当前事务的id值,便于后续跟踪事务的执行情况
#提交事务
cursor.execute(commit)
except pymysql.err.mysqlerror as
e:
# 发生故障,回滚事务
cursor.execute(rollback)
分布式事务的好处在于会大大降低应用开发难度,因为在某些不支持xa的数据库中,需要业务系统通过特殊并且巧妙的设计,而非利用数据库来解决事务中数据不一致等问题。这种对应用开发者的技术水平要求很高,越是复杂的业务系统,越会增加开发成本和技术门槛,这是业内大多数开发者面对分布式数据库时,只能望而却步的主要原因。
腾讯云dcdb xa关键实现方案
1、dcdb架构介绍
腾讯云dcdb整个集群架构简图如下图,mysql采用主从节点配置(也叫作主备)一套主从节点叫做set,在每一个set外配置网关(tproxy),形成一个物理分片(shard)。
dcdb后端是mysql(或其分支版本)数据库,目前腾讯云公有云发布支持xa的版本是基于mysql 5.7.17(percona分支)。
2、网关(tproxy)与xa
网关是用于接收请求并与后端mysql建立连接的网络模块。网关可以用两种模式工作,一种称为noshard,此模式下网关不处理/不解析sql语句,透明转发请求和应答。另一种模式称为shard(分布式,即支持自动水平分表)模式下,tproxy会解析sql并转发到不同的数据分片。
在实现xa之前,网关不允许在一个事务中向多个set发送dml语句。因为未实现二阶段提交(2pc)时,事务采用一阶段提交,如果分布式中某一个set提交失败了或回滚了,那么这个分布式事务就处于不一致的状态。
(网关的工作方式)
二阶段提交中需要的事务管理器(tm)。为了解决容灾、简化架构,腾讯云dcdb将tm实现在tproxy中,而dcdb的网关是一个无状态的模块,通过这一架构,dcdb xa可以支持:
1、分布式事务对业务透明,兼容单机事务语法(start transaction/commit/rollback/savepoint)。
2、每个网关都可以独立接受和处理事务请求,且无需与其他网关进行协调节点故障不丢失事务。
3、允许显式事务中多条语句分别发给多个分片。
4、网关无需持久状态,无需容灾,可以随时经由调度集群退出或加入集群,且性能可以扩展。
5、支持autocommit下单条语句写访问多个分片等。
dcdb网关还允许以流式处理方式运行group by、order by,流式处理让这类操作变得非常方式非常高效;网关还支持两个shard使用shardkey(分表键)做等值连接,以及使用shardkey的子查询。
未来,腾讯云还计划支持分布式join、sparksql、二级分区等高级功能,兼容更多mysql高级语法。
3、强同步与xa
由于腾讯云dcdb默认采用强同步复制,即主从节点数据完全一致,因此xa事务也遵循强同步的逻辑,即需等待从机确认数据同步后,才给业务以应答(commit)。基于强同步,在以下两种异常情况下,dcdb xa可轻松应对
1、主节点故障时,已确认事务数据不会丢失:主节点故障那么拥有最新数据和binlog的从机就被选为主节点,这其中的数据也包括所有已经向用户确认完成提交的事务的数据。
2、原主节点恢复后重新加入集群,未确认事务自动闪回:原主节点恢复重新接入集群,它将作为从机运行,此时他可能存留多余的已提交事务(此时事务并未得到强同步同步确认,即原备机并没有相关数据),那么这些事务会被闪回。虽然这些事务可能已经在原主节点的mysql内部完成提交,但由于强同步机制,他并不会向客户端返回commit语句,这意味着仍被视为一个未完成的事务。因此,这些事务的闪回了也并没有破坏数据库的acid属性。这里值得说的是,闪回flashback是基于binlog生成做逆操作,它与数据库回滚并不同rollback,闪回可以做ddl操作。
腾讯云dcdb的强同步为腾讯金融级数据库自研的一项能力,性能比官方半同步大幅提高,几乎等于异步复制性能,腾讯云dcdb在腾讯内部应用多年,未发生过一起因为主从切换、故障带来的数据误差。而且
云服务器是怎么收取费用的在电脑中如何删除残留的dll文件连接mysql报1045错误怎么办如何申请邮箱免费注册邮箱到期域名如何才能注册成功百度云服务器微端更新怎么设置腾讯云服务器建站教程1对象存储哪个好