银行跨数据中心数据库双活架构设计五大难点

本文根据社区交流内容整理,主要要来自孔再华、冯帅、韩成亮、liuhe等专家和会员的无私分享,可以为大家的相关工作提供思路和实践参考。

难点一:数据库双活,如何解决几十公里延时带来的性能问题?

分享一:

几十公里的延时主要表现在两方面,一个是存储双写延迟,一个是节点通信延迟。

从存储延时来说首先要做到本地读。这个在GPFS文件系统里是可以做到的。其次是增大缓存,减少同步写的次数。对于数据库里的大对象,最好使用inline的方式放在常规表空间里,或者存放在开启了文件缓存的表空间里。对于数据库日志,一定要设置足够的日志缓冲池,避免因为缓冲池不够发生的同步写。

在通信的延迟上,我们需要做到的是尽量减少通信。所以要想办法解决热点数据问题。同时能够本地访问和缓冲的都要想办法实现。例如推荐采用客户端偏好链接。基于current member来组织表和数据等等。(孔再华)

有个问题,由于CF节点只有一个,对于写来说,必然存在两个站点的DB2 MEMBER都同时需要通过RDMA访问CF节点GBP,本地来说,问题不存在,跨站点RDMA访问的话,这个通信耗时和性能是否需要重点关注?(邓毓)

你说的非常正确,跨站点的member和CF通信需求是双活环境调优的关键。所以这个就是重点关注的对象,要减少这种交互。数据库提供了mon_get_cf等相关表函数能够抓取CF的功能和耗时,进而分析是什么操作最慢,能不能减少或者调整。(孔再华)

分享二:

我从Oracle数据库层RAC说一下吧,个人比较喜欢用ASM,用ASM可以解决一部分性能问题,之所以说一部分是因为ASM也只能解决"读"的问题;

由于距离产生的延迟,那么最好的办法就是不缩短距离,这个好像是废话,但是对于Oracle ASM的 redundancy来说其实是可以做到的,比如创建Oracle ASM的磁盘组的时候选择的是Normal redundancy的方式,那么磁盘组就会至少有2个failure group ,而我们可以把2个failure group里的物理盘手工的划分到不同的物理位置,一般双活都有2个机房,那么一个failure group里放一个机房的磁盘,另外一个fialure group里放置另外一个机房的磁盘,这样双活也就实现了,但是随即而来的问题就是物理距离的增加和光信号的衰减和传输的性能降低,Oracle ASM考虑到提升一部分功能,在参数里提供了asm_preferred_read_failure_groups这个参数,也就是说当做物理读的时候每一个机房里的节点(RAC节点)都可以配置自己优先读的“机房” ,这样可以保证“读”不受“距离”的影响,但是“写” 是必须要在双节点都完成的,所以对于ASM来说对于“写”也没有特别好的办法解决距离产生的延迟。 当然这个时候如果RAC的节点的使用和划分以及应用层的布置是都慎重考虑的,否则有可能会出现本来业务应该登陆节点1 而因为配置问题缺被随机分到了节点2,那这个时候反而适得其反。(liuhefromoracle)

分享三:

数据双活和网络延迟的性能问题是一个很难平衡的问题。常见的方案是采用专线连接,更快的服务器,优化的网络基础设施和应用,而且几十公里的距离只能算同城,对于数据双活而言并不是很大的问题,当然也可以选择较近的距离作为数据中心位置。(韩成亮)

分享四:

数据写到主服务器,commit时复制到从服务器。复制完毕commit完成。

只有commit有性能问题,是批量操作性质,可以把通信开销降到最低。

但是如果有锁,锁的传递需要时间。

复制时如果从服务器失效,操作应该依然成功,要在主服务器记录从服务器遗漏事务。待从服务器复活,回复遗漏事务。

如果写几千条记录到主服务器,这期间没有复制开销。在commit时复制,产生一个批量传输,开销是很小的。

但是如果主机从机都在录入数据,他们之间是否有重复记录是不易检测的。一个办法是commit时检测,重复数据导致commit失败。如果在恢复遗漏事务时发生重复记录啦,唯一的办法是抛弃重复记录。

所以主从系统需要阶段性一致性检查,如果有不一致数据,以时间戳最新的为准。(匿名用户)

难点二:如何解决热点数据在双活环境的问题?

分享一:

热点数据是指当前业务频繁访问的数据。如果是单节点数据库,这些数据集中在一起可以提高缓冲池命中率。但是在集群环境恰恰相反!不同数据库成员节点访问同样的热点数据会产生竞争问题。

所以在集群环境,需要考虑热点数据的分布。大的pagesize会存放更多的row,会有更大的概率产生竞争。所以在集群环境,尽量使用小的pagesize, 例如4K。

而对于热点表,我们可用通过在使用分区表等数据库技术来从物理上打散当前的热点数据。例如我们在计费系统的双活环境里面,针对热点的日志表,传统分区表一般使用时间列来组合数据,而我们是用了current member这个变量和序列号组合,做了个隐藏列,实现本地节点插入数据落在自己单独的分区里,同时本地分区也是被轮询使用,彻底打散热点数据。部分定义如下:

"SERIALIZED_REQUEST" BLOB(1048576) INLINE LENGTH 1000 LOGGED NOT COMPACT ,

"CURMEM" SMALLINT IMPLICITLY HIDDEN WITH DEFAULT CURRENT NODE ,

"IDKEY" SMALLINT IMPLICITLY HIDDEN GENERATED ALWAYS AS (MOD(ID,10) + MOD(CURMEM,4)*10) )

COMPRESS YES ADAPTIVE

INDEX IN "TBS_LOG_IDX_4K" PARTITION BY RANGE("IDKEY")

(PART "PART0" STARTING(0) IN "TBS_LOG_DAT" INDEX IN "TBS_LOG_IDX_4K" LONG IN "TBS_CLOB_DAT",

对于热点表的热点索引,建议使用分区索引,random索引等方式。也可以加入current member列作为索引的一部分,从而减少成员节点间的竞争。(孔再华)

分享二:

主要是通过部署负载均衡设备,当然热点数据的可以通过读写分离和缓存来实现,业务层面或者架构层面的调整其实是最简洁有效的。(冯帅)

难点三:在双活环境应该怎么设计数据库对象?

分享一:

其实作为双活环境不可避免的存在很多问题,比如说网络延迟,热点数据,数据耦合等,其实最主要是数据的一致性,作为双中心的环境,我们需要保证数据库的一致性,这个就要求我们在设计表或者其他对象的时候需要考虑这方面可能出现的问题,加强对于业务维护时间戳的维护,同时减少双数据中心的单个时间点的高数据交互,对业务逻辑进行拆分打散,避免大事务对复制延迟的影响,这就要求我们在设计表的时候需要进行更加细致的拆分,特别是对于热点数据,尽量使用缓存处理。(韩成亮)

难点四:本地数据库双活的异地容灾该怎么做?

分享一:

数据库双活环境做异地容灾就是选择如何复制数据。复制数据有两种方式,一种是通过存储复制,另一种是通过数据库复制技术。存储复制只需要复制单数据中心的数据,在异地搭建同架构的集群环境(可以使轻量级的,资源配置不要求一致)。我行就有系统通过SRDF存储异步复制技术将数据复制到异地。数据库复制技术更推荐使用。因为数据集复制技术能够规避存储复制坏块的风险。同时对网络带宽的压力也小很多(只复制变化的日志)。这个是更加推荐的方式。(孔再华)

分享二:

异地容灾主要看你需要实现什么样的级别。

常见的容灾方案有

1 基于存储层的容灾复制方案

2 基于逻辑卷的容灾复制方案

3 基于log的逻辑复制方式(ORACLE REDO、MYSQL binlog)

4 还有一些第三方的软件

5 自己开发的一些脚本或者工具

其实,总的来说,本地数据库双活的异地容灾,单活异地容灾最大的区别在于,你以哪个为主,同步的频率,同时,如果你的环境已经是双活,那么异地容灾说白了仅仅是一个冷备。

至于如何做,需要切合你的业务需求。(韩成亮)

难点五:有没有针对双活环境的数据库开发规范?

分享一:

在双活环境大部分开发规范是和单机数据库的开发规范一样的,但是有写针对这个环境特点的开发规范:

事务处理设计:

尽量避免热点数据和不必要的数据重复访问。例如计费系统的查重,入表,更新表等操作,可以改变为最后只插入一条最终的记录。

尽量将业务分表。例如计费里面将不同的业务计入不同的流水表里面。

合理设计索引。不要建立不必要的索引,适当使用聚合索引。

批处理:

由于CF通信和存储复制的延时,双活环境的单个事务会比单机版慢,所以批处理建议通过提高并发的方式来加快处理速度。

拆分批处理,将单次批拆成多个批一起跑。例如一天的归档拆成按照小时的归档。

作业拆分,使用跟多并发的方式处理单个批处理。

报表:

在双活环境里面运行实时报表需要慎重,防止GBP的DE空间被占满。尽量避免出现全表扫描的报表。合理安排利用索引,减少记录扫描数量。(孔再华)

分享二:

其实还有一些更加严格的安全规范,行为规范

1. 表结构变更必须通知DBA进行审核。

2. 禁止有super权限的应用程序账号存在。

3. 禁止有DDL、DCL权限的应用程序账号存在。

4. 重要项目的数据库方案选型和设计必须提前通知DBA参与。

5. 批量导入、导出数据必须通过DBA审核,并在执行过程中观察服务。

6. 批量更新数据,如UPDATE、DELETE操作,必须DBA进行审核,并在执行过程中观察服务。

7. 产品出现非数据库导致的故障时,如被攻击,必须及时通DBA,便于维护服务稳定。

8. 业务部门程序出现BUG等影响数据库服务的问题,必须及时通知DBA,便于维护服务稳定。

9. 业务部门推广活动或上线新功能,必须提前通知DBA进行服务和访问量评估,并留出必要时间以便DBA完成扩容。

10. 出现业务部门人为误操作导致数据丢失,需要恢复数据的,必须第一时间通知DBA,并提供准确时间点、 误操作语句等重要线索。

11. 提交线上建表改表需求,必须详细注明涉及到的所有SQL语句(包括INSERT、DELETE、UPDATE),便于DBA进⾏行审核和优化。

12. 对同一个表的多次alter操作必须合并为一次操作。

13. 不要在MySQL数据库中存放业务逻辑。

14. 禁止在线上做数据库压力测试。

15. 禁止从测试、开发环境直连数据库。(冯帅)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180810B07U7M00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励