目前网上没有这方面的介绍,主要是中兴公司基于MYSQL的包装.
中信银行(研发 PGXC)
终于要说到中信银行了,课程中我们已经多次讲过的 GoldenDB 就是中信银行与中兴通讯联合研发的产品,而目前 GoldenDB 主要用户也是中信银行。中信银行的核心业务系统在 2020 年 5 月正式上线切换到 GoldenDB。这之前,基于 GoldenDB 的信用卡新核心系统已经在 2019 年 10 月投产运行。这两个重要系统的运行,使中信银行无可争议地成为分布式数据库应用最为深入的一家银行。核心业务系统是银行业务的心脏,它的稳定运行无疑为其他银行树立了标杆,客观上也加快分布式数据库的普及速度。
GoldenDB 和 CBase 有大致相同的发展路径,从产品研发到试点应用,只不过中信银行的步子更快些。当然,这并不是说交行研发人员的能力不行,因为这个速度上的差别确实有架构上的因素。GoldenDB 是 PGXC 风格的分布式数据库,遇到的技术挑战更小;当然 NewSQL 架构上的优势,也让我们对 CBase 的未来充满期待。
你有没有注意到,还有一个很有意思的地方,同样是核心系统改造,为什么中信银行就使用了分布式数据库呢?
答案还是在于项目目标不同。中信的目标就是完成 AS400 小机下移,将应用程序翻写到开放平台,但是对应用架构本身并没有改造诉求。所以,数据库层面的平滑过渡就有很大的优势,编码逻辑改动小,测试成本低,最重要的是不会因为技术原因变动业务流程,这样就大大降低了项目的实施难度。
目前另外家地球级别的银行也开始使用GOLDENDB 代替AS400小型机.术语也叫主机下移项目. 所以我们还是简单地讲讲GOLDENDB
分布式数据库系统
分布式数据系统中的每台计算机可单独放在一个地方,每台计算机中都可能有数据的一份完整拷贝副本,或者部分拷贝副本,并具有自己局部的数据库。位于不同地点的许多计算机通过网络互相连接,共同组成一个完整的、全局的,逻辑上集中、物理上分布的大型数据库。
系统总体架构
从图上看基本上和中间件MYCAT没啥区别,唯一区别是在右下角这块,应该是管理节点.还有个GTM的管理思路.
1.OMM:统一运维平台
2.Manager:各种管理组件
3.GTM:全局事务管理节点
4.Proxy:计算节点
5.Cluster:数据节点集群
各个节点无需共享任何资源,都是独立自治的通用计算机节点,之间通过高速互联的网络通信,从而完成对应用数据请求的快速处理和响应。
物理部署
从部署来说有4个管理机器,一组GTM主从,另外一组就是节点管理
G1 G2 是数据节点, 是MYSQL主从模式
两地三中心部署
从这个多机房来看,数据节点利用MYSQL复制功能进行异地机房异步复制.
管理节点利用自身进行复制.
事务理论基础对比
单机数据库 |
分布式数据库 |
原子性:多条记录的多次操作要么一起成功,要么一起失败。 |
原子性:多个数据分片上的多次操作要么一起成功,要么一起失败。 |
隔离性:不同连接(处理线程或进程)不会相互访问到未提交事务的数据。 |
隔离性:多个计算节点上的不同连接不会相互访问到在多个数据分片内未提交事务的数据。 |
持久性:事务提交前必须先将日志落盘,机器重启后不丢失数据。 |
持久性:事务提交前必须将日志在分片主、从节点都得到复制,主节点故障时从节点上仍能找回数据。 |
理论上分布式隔离还是比较难以理解
防止另外个事务读取未提交的数据?
以转账交易为例:
交易前2个账户资金余额各100,事务T1从账户1转账50到账户2;
在事务T1提交期间,由于DB1和DB2提交时间有空隙,若此时事务T2读取2个账户的余额,会发现余额之和是50+100=150。
因事务之间的隔离性问题产生数据读不一致。存在事务T1对账户1上扣钱成功,给账户2加钱失败的情况。因事务内部的原子性问题产生数据写不一致性。
核心思想:引入全局事务管理器(GTM),记录当前所有未提交的全局事务标识(GTID)及其状态,把全局事务标识(GTID)加到每条数据记录中,作为分布式环境下表的全局锁,通过全局锁控制对数据的并发访问
以转账
事务开始时申请GTID,事务结束时释放GTID,记录在GTM中的所有事务均为未提交事务,称为活跃事务.创建表时自动增加GTID隐藏列,更新数据时同时更新GTID,采用优化的二阶段提交方式,实现分布式事务处理
原子性解决方案
以转账交易为例:
A、B账户原来各自拥有100元;A给B转账50元。
A、B属于不同节点,各自执行对应更新事务;
A执行成功,B执行失败。
B失败后,进入单机事务异常回滚流程;
A成功后,进入已提交事务回滚流程。
原子性实现方案:
事务所有的修改,生成的binlog都包含GTID信息;
过滤binlog,找到GTID对应的事务块日志;
解析事务块日志,生成对应的逆向SQL;
将逆向SQL发往所有节点执行。
解决故障类型1:部分DB节点提交失败,Proxy主动回滚相关事务
解决故障类型2:Proxy自身故障,由其它Proxy回滚相关事务
其实这个通过BINLOG进行回滚成功的,应该说是比较可以的.虽然回滚相对比较麻烦,而且性能不咋地. 不过正常生产环境中只有少概率会发生另外个数据节点提交失败情况, 应该是极少数! 这种设计使得短事务提交速度非常快,相比较其他分布式数据来说. 尤其是在GTM打卡模式,成功就OK,失败就FAILE,然后向成功的发生ROLLBACK命令.
一致性读过程
l查询数据时,通过检查数据行GTID系统列对应的全局状态,来判断该数据行是否正在被其他全局事务修改。
l如果GTID在全局活跃事务列表中,则表明该数据正在被修改,不能返回给应用。
l原语句:selecta,bfrom t1 where b >’yyyy’;
l实际下发语句:selecta,b,gtid from t1 where b>’yyyy’
处理过程:
①请求活跃事务列表
②改写语句
③路由查询请求
④检查记录行状态
⑤合并返回查询结果集
这点有点多余,步骤过于麻烦! 每个查询都要获得个GTID,然后去数据节点查询对应的行的GTID,然后在返回DBPROXY对比是否是活跃GTID.
这里小仙看得半懂,
可能有两种方式
1 一个查询 直接下放到数据节点,
2 返回结果集到DBPROXY
3 DBPROXY 获取活跃事务ID
4 对比返回的结果集中的GTID是否在活跃事务ID里
5 不在就把数据返回给客户端, 在的话就返回错误!
按图理解:
1 获取全局GITDS 这个是活跃GTID列表,还是查询也算是事务
2 从数据节点返回结果集,
3 在DBPROXY 获取当前活跃全局事务ID
4 然后再对比.
这样的设计性能估计也不咋地.
原因是
1 查多写少的情况下,每次查询都要对比GTID
2 没有利用MYSQL MVCC功能. 假如读过去的数据咋办? 看样子都是当前读.
怀疑一致性的代码逻辑性能不高
猜测 一个查询语句过来 DBPROXY 从全局事务列表获取个GTID 给这个查询.
改写,再路由到具体数据节点上. 返回结果集的GTID, 然后进行对比.
假设 查询为QGTID ,事务的DGTID
if QGTID>DGTID then 则报错 反之还要回MYSQL查MVCC的数据!
一致性写过程
分布式事务更新/删除时,通过selectfor update 锁定解决写写冲突。
原语句:updatet1 set a=’xxx’ where b >’yyyy’;
实际下发
1、select pkey, gtid from t1 where b>’yyyy’ for update
2、update t1 set a=’xxx’, gtid=current_gid where pkey in (pkeys)
处理过程:
①请求活跃事务列表(同时创建GTID)
②改写语句
③路由锁记录请求
④检查记录行状态
⑤路由更新请求
⑥释放GTID
⑦合并返回处理结果
数据分片策略
支持多样化的分片策略:
1.支持按哈希拆分数据集
2.支持按范围拆分数据集
3.支持按列表拆分数据集
4.支持单节点/多节点复制
多级分片功能:
1.支持多达5层分区
2.支持多个分区键使用不同分片策略
复制策略
类似MYCAT的全局表
Range范围策略
Hash策略
·Hash策略,提供了一种将数据均匀分散到整个数据节点集群中的方式,将IO的压力分散到整个集群上,减少热点数据的形成机会。
·采用一致性哈希算法
分片策略 基本比较易懂 符合ORACLE风格
唯一确定是涉及了存储参数. 这里的GROUP1 是逻辑的还是物理的. 跟存储挂钩对运维不太友好,将来添加数据节点时,需要修改表ALTER TABLE....
多级分片策略
·多级分片策略是一项非常实用的分布策略,可根据业务要求,精细化的控制数据在集群中的分布形态,进而减少计算复杂度,提升数据访问操作性能。
一眼嫖过去 好像ORACLE的双层分区,细看好像不是那么回事
看图是这样理解的,
1 先按地区分 纽约在G1(数据节点1) 伦敦在G2
2 如果是东京 北京的数据 进入按账号类型 对私里面按客户号HASH 到G3 G4
4 如果是东京,北京 对公的数据 按客户类型 G5
5 最后否则按客户HASH 到G6
这样的多级分片是否有利于提高性能要看将来情况哦! 感觉很烧脑!