暂无图片
暂无图片
5
暂无图片
暂无图片
暂无图片

一个OceanBase集群,两个证券行业场景,多个核心特性

原创 多明戈教你玩狼人杀 2024-11-29
890

场景与需求

如果炒过股的朋友,可能会了解,我们日常的委托交易并不是实时完成结算交收,都是在日终完成集中清算的。这种方式可以减少交易成本和操作复杂性,提高资金使用效率,同时也降低了风险。而在清算阶段,用户账户上的持仓和金额都有可能出现数据变化,从而带来不准确性。因此各家券商采用了不同的方式来处理,有的是清算阶段用户无法查询,有的是采取其他方式,只提供清算之前的数据,直到清算完成才将最终清算后的正确数据提供给用户查询。而越来越多的券商,在采用后者。

而涉及到用户查询的问题,也不仅仅是日终清算,盘中的查询同样是极其高频发生的事情,对实时性和正确性有要求的情况下,如何保证查询数据的正确性、实时性,同时还能够不对交易产生影响,同样也是很多券商一直在不断努力优化的。将交易和查询的延迟做到最低,同时尽可能将读写分离开。

因此我们来提炼一下两个场景的核心需求:

1. 清算查询。在清算时,提供给用户查询清算前的数据,并告知当前清算中,数据会有变化。清算后,用户即可查到清算后的数据。

2. 读写分离。在盘中交易时,用户所有的交易和查询,互相之间尽可能隔离,数据库的负载彼此不影响,同时还要保证查询的数据有足够的新鲜度。

当然,这里还有一个隐藏的需求,高可用。无论是两第三中心还是多地多活,都需要提供跨地域跨机房的高可用。想要同时满足这些核心需求,对数据库的诸多特性,都有着很高的要求。

原有方案

之前在跨国券商的时候,同一个核心交易系统供应商,同样的的需求场景。我们采用的是Oracle11g的RAC架构。生产集群RAC是4节点的集群,同城机房和异地机房都是2节点RAC集群。而为了支持清算时提供给客户数据查询,还专门做了一个资源分配较少的2节点RAC,同样做了1主2备,用于配合生产RAC专门做清算用。大概架构如下(网关、防火墙之类的没有画):

1. 生产机房的RAC,一共两个库,交易库的主库和清算库的备库(ADG双箭头)。生产库用于客户的委托交易,清算库备库作为灾备。清算库备库除了灾备,还承担着从清算库取清算结果数据的作用。物理层面,四个节点,其中2个节点用于交易,2个节点用于查询,通过物理机器的隔离,来实现读写分离。

2. 同城灾备的RAC,以ADG的方式同步,保留了交易库和清算库灾备。

3. 异地灾备的RAC,也是两个库,清算库的主库和交易库的备库。清算库主要负责从交易库获取数据,然后与中登清算完成日终清算,以及交易库的备库用于提供灾备,以及清算库的取交易数据的作用。

而交易库和清算库之间,通过dblink来获取数据,具体示例如下,箭头指向是数据流向,不是dblink的指向:

1. 日终清算前,利用ADG秒级别的数据同步,通过dblink清算库从交易库备库直接取数,不需要走跨城网络,而是同一个机房不同的ASM磁盘组之间。

2. 日终清算后,同样利用ADG秒级别的数据同步,通过dblink交易库库从清算库备库直接取数,不需要走跨城网络,ASM磁盘组之间数据流向。

这个方案的优缺点都很明显。先说优点:

1. 交易清算分离。这样确保了客户在交易清算期间,仍然还能够查询自己的持仓和账户信息,数据是清算之前的。清算之后能够以极快的方式将清算后数据写入交易库。
2. 读写分离。交易RAC的4个节点,2个用于交易2个用于查询,互相之间的计算资源没有干扰。
3. 高可用。既有RAC实例级别的高可用,又有基于ADG的两地三中心高可用。而RAC和ADG的稳定性可靠性,大家都很了解。
4. 数据隔离。交易库和清算库使用的是不同的Oracle实例,彼此之间的权限不受影响,预分配好的内存资源同样互不干扰。

再说说缺点:

1. 使用成本。整个方案需要用三个Oracle RAC,无论是软件授权费用还是硬件成本,都偏高。
2. 扩展性。Oracle RAC虽然能够动态增加节点,但是操作风险一直是比较高的一个水平。
3. 存在隐藏瓶颈。虽然说在计算资源上实现了存算分离,但是ASM存储的带宽是有上限的,交易时间里的存和算实际都依赖同一个ASM服务。
4. 资源浪费。同城灾备的RAC仅仅作为灾备存在,并没有利用起来。

如果用OceanBase替换

首先就是,OceanBase已经具备了Oracle语法语义的兼容性,因此这部分我们不再做过多讨论。主要是针对两个行业场景+高可用这个必备的需求,来做一个替换方案。作为曾经的产品经理,我还是先从需求出发,再到替换。

第一个场景,清算时仍然可以查询清算前的结果。

使用Oracle11g的方案时实例级别的隔离。当然,如果在Oracle12c以上,完全可以使用PDB来做隔离。那么在OceanBase当中,自然就对应了多租户。我们来分配如下两个租户:

租户A,用于交易和查询。高频操作,对系统的延迟要求非常敏感,在整个资源分配当中,优先级最高。

租户B,用于日终清算。操作频率不高,和租户A的负载时间完全错开,资源分配的优先级不高。

这两个租户就可以在地位上完全等同于交易库和清算库,彻底实现资源隔离和权限隔离。而两个租户之间的数据交换,过去使用的办法是Oracle的DBlink,在OceanBase中也有同样的对象类型可供使用,以用户名和密码鉴权的方式,和之前的使用方式基本一致。

第二个场景,读写分离。

既然说到读写分离,我们就先得引入OceanBase的几个组件和功能,其中的第一个,叫做ODP。

OceanBase Database Proxy(简称 ODP)是 OceanBase 数据库专用的代理服务器。OceanBase 数据库的用户数据以多副本的形式存放在各个 OBServer 节点上,ODP 接收用户发出的 SQL 请求,并将 SQL 请求转发至最佳目标 OBServer,最后将执行结果返回给用户。

从官网文档的描述来看,ODP重要的作用之一,就是将用的SQL请求转发到最佳目标的节点上,这也是我们要实现读写分离的第一个必备组件,为的是做到请求层面的读写分开。

其次,OceanBase目前能够支持的是弱一致性读,我们要利用这个特性,让用户查询的SQL不需要去读到最新的数据,搭配多副本来使用,让写入的数据副本和读取的数据副本区分开来,做到存储层面的读写分开。配置好参数obproxy_read_consistencyproxy_route_policy 两个参数,让用户的查询SQL更优先走备副本。

做到这一步,实际上配合OceanBase的多副本,读写分离就已经可以实现,但是要说的是,因为是副本之间,之间数据同步必然会有一个时间差。查询的数据往往也会有延迟,按照官网描述是有毫秒级别的延迟,按照日常业务普通客户反馈的需求来看,还是可以接受的。当然如果是机构客户或者高频交易客户,需要极低的延迟,完全可以单独配资源采用强一致读。


以及,监管要求的异地容灾。

首先我要说的是,作为一个日常工作都要去查询监管要求的人,这几年一个直观感受就是,监管对于系统可用性的要求也在不断增强,从早年的两地三中心,也在朝着多地多活过渡,而多地多活,恰恰也是云原生分布式的OceanBase天然擅长的场景。通过创建多个Zone,来覆盖多个物理位置不同的数据中心,是一个很成熟的策略。我们做一个最简版的两地多活三中心规划:

  • Zone 1,主生产中心,主要对接沪深交易所,提供委托交易和客户查询,同时可以为中登清算的数据中心做灾备。
  • Zone 2,同城数据中心,作为Region A的同城机房,可以承担起Region A同等的业务负载,实现双活。
  • Zone 3,异地灾备中信,主要对接中登清算系统,并为主中心提供灾备能力。


OceanBase替换方案

三个场景都完成了替换,接下来,我们要做的就是,把它们整合起来,形成一个完整的替换方案。首先把架构图贴出来,再讲解。


  • OBProxy层,以OBProxy作为接入,提供负载均衡、SQL路由功能。
  • Tenant A,原交易库,现在继续负责委托交易和查询。
  • Tenant B,原清算库,现在继续负责日终清算。两个租户之间依然通过DBLink来交换数据。
  • Zone 1,之前的主生产机房,现在的同城机房1,提供Tenant A的数据P1与P2的主副本(蓝色),P3与P4的备副本(白色),以及Tenant B的备副本数据。
  • Zone 2,之前的同城灾备机房,现在的同城机房2,提供Tenant A的数据P3与P4的主副本(蓝色),P1与P2的备副本(白色),以及Tenant B的备副本数据。
  • Zone 3,之前的异地灾备机房,地位保持原状,提供Tenant B数据P1和P2的主副本(蓝色),Tenant A数据P1-P4的备副本(白色)。


在盘中,用户的委托交易以及查询请求,通过OBProxy分发到Zone1或者Zone2最合适的OBServer中,直接操作主副本。所有的查询请求,仍然通过OBProxy分发到Zone1或者Zone2最合适的OBServer中,直接读取备副本。这里需要注意的是,因为直接读取备副本,因此会有少许数据延迟。

在盘后的清算开始前,Tenant B在Zone3直接读取Tenant A的备副本,因为此时已经是盘后,所以已经不存在数据延迟。

在清算期间,用户的查询依旧只是通过Tenant A在两个同城机房的数据查询,因为配置了弱一致读,所以优先去读备副本。此时实现了客户在清算期间查询自己清算前持仓的需求。

在清算完成后,Tenant A读取Tenant B在Zone1和Zone2的备副本,将清算后的数据同步过来。实际时间差取决于异地机房和同城机房之间的带宽。完成同步后,客户读到的就是清算后的数据。

高可用方面,无论Tenant A还是Tenant B,都实现了两地三中心三副本。其中任何一个机房发生宕机,都可以确保任意两个机房可以继续承担读写分离和清算中查询,但是无法确保性能。任意两个机房发生宕机,都可以保证数据是完整的,读写分离和清算期间查询无法完全保障,但是可以通过临时加节点扩容的方式继续实现。


与Oracle的案例相比,我们来总结一下这个架构的优劣。

优势:

1. 资源利用率高。三个机房实现了多地多活,没有出现之前同城机房纯粹冗余而出现了资源空置较高的情况。

2. 高可用。实现了多地多活,只要不是三个数据中心同时出现重大问题,都可以确保数据服务的可用性。

3. 灵活扩容。OceanBase集群的扩容灵活性是好于Oracle RAC的(我个人观点),如果出现资源瓶颈,可以更加灵活加OBServer。

4. 使用成本。硬件方面使用更多价格一般的硬件,以分布式集群的方式,替换更高配置的服务器。


劣势:

1. 学习门槛更高。Oracle RAC的架构,相对来说我觉得更加简单直接,而OceanBase涉及到多副本、多节点、多Zone、Proxy,实际需要理解并且充分设计是需要一定门槛的。

2. 数据延迟。因为Oracle的方案里,读写分离是依靠不同的计算节点实现,背后都是同一个ASM磁盘组,而OceanBase则是主副本和备副本,实际存在的几百毫秒的时间差,在高频交易或者行情剧烈波动的时候,有可能问题会被放大。

不得不说,没有哪个方案或者架构是完美的,都需要一些时间去不断壮大。我相信伴随着时间,学习门槛和数据延迟的问题,慢慢都会备逐步解决,只是当下,仍然需要我们花一些时间来学习和分析。


最后做一个小结,之所以想写这个内容,实际上也是我最近在看金融监管有关数据中心建设的新规,曾经的两地三中心,早晚有一天要彻底被多地多活所替代,新的监管要求,必然带来新的技术更迭,那么探索出一条新技术的道路,就显得十分重要。任何技术特性,最终都是给业务场景服务,脱离了这些,都是无根之水。这一点上,我觉得OceanBase的诸多特性,都是经过现实中不断摸索不断调研不断论证后开发的,很多地方让我感叹,如果是我产品经理,大概率想不到这么多。

这篇文章,肯定里面有诸多不当之处或者误解,所以我写完也做好了随时改正的准备,也希望大家不吝指出。我会不断调整优化,并且希望在未来付诸实现。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论