{
    "componentChunkName": "component---src-templates-blog-blog-detail-tsx",
    "path": "/blog/tidb-in-essence-securities",
    "result": {"pageContext":{"blog":{"id":"Blogs_459","title":"TiDB 在安信证券资产中心与极速交易场景的实践","tags":["TiDB"],"category":{"name":"案例实践"},"summary":"本文将分享 TiDB 在安信证券的资产中心与极速交易场景的实践经验。","body":">本文根据安信证券资深数据库架构师李轲在 DevCon 2022 上的分享整理，主要讲述了 TiDB 在安信证券的资产中心与极速交易场景的实践经验。主要包括三部分内容：第一是国产化信创改造总体情况，第二是 TiDB 在安信证券的一些实践情况，第三是实践过程中我们遇到一些问题的反馈和建议。\n\n> 安信证券股份有限公司（以下简称“安信证券”）成立于 2006 年 8 月，并先后于 2006 年 9 月、12 月以市场化方式收购了原广东证券、中国科技证券和中关村证券的证券类资产。安信证券总部设于深圳，全国设立 50 家分公司，320 家营业部和 370 个营业网点。安信证券现为全牌照综合类券商，多项业务排名进入全国前列，连续 10 年获得 A 类 A 级以上行业分类评级，其中 2011 年至 2013 年达到行业最高的 A 类 AA 级。2020、2021 年安信证券连续获评 A 类 AA 级。\n\n今天分享的议题主要是 TiDB，所以就给大家介绍一下 TiDB 这个产品，TiDB 是原生分布式数据库架构设计，是由 PD 以及 TiDB 和 TiKV 组件组成。PD 层主要是作为数据调度、事务调度以及 TiKV 的元数据的存储。TiDB 层是无状态的 SQL 计算引擎，因为它是无状态的，所以对于后期的扩展需求有良好的支持。第三层的 TiKV 负责具体的数据落地存储，TiKV 节点之间通过 Raft 协议进行数据同步，所以 TiDB 整体架构是以 TiDB 作为 SQL 计算引擎，TiKV 作为落地存储的存算分离架构。\n\n安信证券的国产化改造的架构选型，服务器采用了 Taishan 服务器，底座我们是选用了鲲鹏 920 CPU 搭载运行的是麒麟 V10 操作系统，在上面运行分布式数据库 TiDB，整体架构是基于 ARM 体系。在硬盘的选择上，因为 TiDB 对读写性能要求比较高，所以在 TiKV 和 PD 节点选择了额外的 NVMe 盘作为存储，TiDB 节点使用了传统的 SSD。\n\n![1.jpg](https://img1.www.pingcap.com/prod/1_0a98e9f0d5.jpg)\n\n**下面来介绍 TiDB 实践具体的应用案例**。第一个是安信客户资产中心系统，这个系统是一个能够覆盖全账户类型、全产品、全交易行为（1500 多种不同交易行为）、所有交易状态（20 多种交易状态）的数据共享中心，业务范围主要是满足客户的查询账户资产以及了解投资收益的各种场景需求，用数据帮助客户完成自我驱动的财富管理，覆盖了公司 700万+ 的全用户数据，服务查询性能平均响应时间在 50 毫秒以内。这个系统的改造诉求主要是高可用、稳定、落地持久存储这些方面的需求。\n\n![2.jpg](https://img1.www.pingcap.com/prod/2_1f0d1ffeb4.jpg)\n\n整个项目的改造历程分为四个阶段，第一阶段是在 2021 年一季度我们做了可行性分析和验证，包括一些 TiDB 集群性能的初步验证，还有一些数据的同步延时。在去年一年我们做了总体的技术方案设计，包括初步的开发设计、并行验证、初步的系统上线、业务的初步连通性验证和具体实施。在 2022 年一季度，我们做了下游系统的改造，包括一些业务代码以及系统对接等方面的开发。在 2022 年底我们已经完成了全部流量切换和备中心搭建。\n\n可以看到这套系统的改造前后，主要是针对日间变化数据这套原来基于 Lamda 技术架构做了改造，现在换成基于 TiDB 技术架构，下图表示具体的数据链路改造的变化。\n\n![3.jpg](https://img1.www.pingcap.com/prod/3_683be95209.jpg)\n\n左侧初始架构是从 OGG 到 kafka 再到 Spark Streaming 的流式处理，最后到 redis 进行落地存储的消息流处理模式架构, 右侧则是改造后的由四个组件现在简化成由 AR 数据导入导出的同步工具，再最终落地到 TiDB 进行数据存储。\n\n**改造的目的主要是出于五个方向考虑**，总体也可以分为运维角度和业务两个角度。\n\n第一，**降低运维难度**。原架构的数据链路比较长，设计上是从原来的柜台 DB 到 OGG 然后再到一系列的大数据组件，最后落地到 redis。随着组件的增多，出问题的概率会比较大一点，并且对运维人员技术栈的储备要求较高，后续的运维难度也比较大。大数据开源组件的特性在使用中有可能造成在一些业务场景数据的丢失，会影响到客户的使用体验。现在升级改造之后，数据链路换为柜台 DB 到 AR 数据同步工具，然后再落入到 TiDB ，极大地简化了一个数据流转链路，也简化了技术架构，相较之前运维也较简便。TiDB 是一个关系型数据库，对 DBA 来说运维技术的过渡转换也是十分方便的，加上 TiDB 的强一致性也可以保障写入数据的高可靠。\n\n第二，**性能容量提升**。原有架构以 redis 作为最终数据落地存储，设计初始更多的是基于高可用的出发点进行设计，用了哨兵模型进行部署。而证券行业特点使流量负载和流量峰值很难预测，原有的架构设计在一些业务峰值的数据承载以及性能上会有一定的瓶颈，特别是在数据峰值比较大的时候，如果需要扩展，对架构的改动较大，风险也相应提高。原有架构在线水平横向扩展能力上不足，缺少对逐渐增加的业务流量承载能力。TiDB 可以支持在线水平弹性扩展，最主要的特点就是弹性扩展对业务是无感知的，如果说缺少计算方面的能力，那么直接扩展 TiDB 节点即可，如果数据量增多，可以直接扩展 TiKV ，并且扩展只需增加节点数，不需要对原有架构进行改动。\n\n第三，**缩短应急处理周期**。之前的架构因为大数据组件比较多，特别是 kafka 的消费以及重试机制，如果出现问题的话，因为其流式架构设计，出现故障的时候第一我们要定位，第二在时间点的处理方式上我们可能会基于更早的时间点去进行消息重放，需要有一定的时间去进行消息处理，从而进一步拉长应急处理周期，降低故障处理速度，我们发现在一些应急处理场景并没有达到预期。改造后，在出现故障的时候可以通过 AR 导数工具快速将指定时间的数据恢复到下游 TiDB，能在很短的时间内将业务恢复，提高系统的运维连续性和可用性。\n\n前三点主要是从运维角度出发的，后两点更多是从业务和开发角度去进行改造。\n\n也就是第四点，**简化数据流转复杂度**。之前是使用 redis 作为最终的数据落地存储，这块第一我们在一开始设计的时候没有打算做长期的存储保留，而源数据端柜台 DB 是传统型关系数据库，例如 DB2、Oracle 以及 MySQL，从柜台数据同步到 redis 会经过一些数据转换，从结构化数据转换到 KV 结构数据，对于下游的开发、设计也会增加了复杂度。现在转为 TiDB 后，同样都是关系型数据库架构，从柜台 DB 到 TiDB 的数据结构对于开发团队来说没有什么太大的区别，直接进行开发使用，简化数据流转复杂度，提高开发的灵活度。\n\n第五点，**支持历史查询以及复杂分析**。随着业务发展不断增加的需求，例如报表分析等。原来的架构无法满足我们将来的一些复杂分析以及客户的特定需求，业务痛点基于原有架构很难去解决。改造成 TiDB 之后，首先单集群能够支持 200TB 以上的数据量，可以进行历史数据的长期存储， TiFlash  分析引擎可以很好地支持复杂分析，OLTP 和 OLAP 事务分离，也可以跟我们的大数据栈进行无缝衔接，支持后续业务发展。\n\n![4.jpg](https://img1.www.pingcap.com/prod/4_ce0564636b.jpg)\n\n接下来我们来看实时资产项目的部署架构，2022 年南方主中心生产上线，每台机器上部署了两个 TiKV，是一个 3*2 的架构，PD 和 TiDB 采用混合部署，也是 3*(1PD*2TiDB) 的架构设计，在 TiDB  Server上层做了 HAProxy ，负责流量的接入以及负载均衡的调度。2022 年底已完成部署深圳备中心。TiDB 数据主要是通过 binlog 方式将主中心的数据进行同步。\n\n![5.jpg](https://img1.www.pingcap.com/prod/5_c6525c3c31.jpg)\n\n以上就是客户资产中心系统的改造总体情况，**接下来介绍 ATP 极速交易系统**。\n\nATP 极速交易系统作为安信证券首批的交易系统改造是比较慎重的。对这个项目的系统改造要求也比较特殊，这套系统改造是一个全面的国产化改造，要支持国产化服务器、操作系统甚至是路由器，包括一些前端应用全部都是国产化的设计。作为交易系统所以改造的最终诉求就是适配性好、业务改造简单，而源端的数据库原来使用的是 MySQL，TiDB 对 MySQL 的兼容性好，可以降低原有开发团队的适配难度，只要把数据直接导入再进行相应的适配开发。交易系统的定级也需要满足证券行业的两地三中心的技术要求。\n\nATP 的整体项目进度还处在上线及试用阶段，预计要在 24 年中才会根据改造进度和业务需求进行大规模的客户迁移和流量接管。\n\n![6.jpg](https://img1.www.pingcap.com/prod/6_5070f08610.jpg)\n\nATP 极速交易业务架构是采用三中心部署。项目比较有特点的地方就是它是一个自底向上全国产化方案，一般的项目改造可能只是针对服务器以及数据库进行替换。而 ATP 系统是从底层网络的交换机到服务器以及 CPU，还有操作系统和数据库全部采用产品。在上层应用，也采用华锐的 ATP 国产化版本，包括机构交易平台和分布式高性能计算平台。\n\n这套系统主中心的应用组件采用主备高可用部署方式，组件间实时同步保持强一致性，只要有单点故障的出现，可以实现自动切换，满足 RPO=0，RTO<10 秒的要求。也能支持系统的水平扩展，作为一个极速交易系统，核心诉求就是快，进行国产化改造之后，需要保证交易时延也要与原来的系统一致。所以在低时延这块，也能做到微秒级的全链路时延。\n\n![7.jpg](https://img1.www.pingcap.com/prod/7_c8688ab8e2.jpg)\n\n接下来看具体的部署架构。以南方主中心，深圳科技园备中心，上海金桥灾备中心形成一个两地三中心，一主两备的级联部署。备中心和灾备中心的配置类数据是通过 TiDB 本身数据库的 binglog，以异步同步的方式进行数据同步。考虑到时延和性能， 各机房会处理自己的交易类数据，然后直接落盘到本地库，这样可以保证交易数据快速地入库以及对外提供服务。\n\n![8.jpg](https://img1.www.pingcap.com/prod/8_e1a8295685.jpg)\n\n在网络环境上采用了华为的交换机，接入交换机是采用双机的组网，配置 V-STP 模式对外提供服务，同时配置了双活网关，对于业务网络来说，把交换机链路单独划分出一个 VLAN，专门用来业务网络使用。交换机三层与核心交换机进行互联，通过静态以及动态路由实现两地三中心业务的互通。\n\n**TiDB 的整体使用收益，我们从两个业务场景看**。第一个是资产中心，资产中心受益的地方，就是极大地精简了数据流转链路，把原来多个大数据组件的一套架构，改造成 TiDB 一个国产化数据库，承载的功能不变。数据处理流转比较简单，从传统的柜台关系型数据库到 TiDB 是关系型到关系型，对于开发使用也比较友好。TiDB 提供数据的强一致性保证，支持后续的高并发联合查询、水平扩展、复杂分析、开发需求等等。对于极速交易来说，TiDB 首先满足全栈国产化和全功能兼容的要求，从原来的 MySQL 切换到 TiDB，功能上和兼容性来说是都是不错的。其次，TiDB 支持两地三中心的高可用部署，也满足高可用需求。\n\n![9.jpg](https://img1.www.pingcap.com/prod/9_9ffd5e8fb8.jpg)\n\n**最后分享一下 TiDB 在安信证券实践过程中遇到的一些问题，以及具体是我们怎么做的，希望这些能给大家一些启发**。\n\n首先第一点，就是数据读写热点。TiDB 的底层存储 TiKV 的数据是以 region 为单位进行存储，在 region 上按照 key 值有序追加，如果不做特殊处理的话，数据会一路往后面追加，在高并发场景下比较容易产生读写的热点。因为数据比较集中，读事务与写事务都会集中在一块资源上，会产生读写热点。对于这个问题，我们的建议是在进行表结构设计时，尽量使用 Auto Random 方式的自增主键，把数据打散，分散存储，可以减少热点冲突的现象。\n\n第二点就是 TiDB 内部组件资源争用的现象。这个场景比较特殊，因为我们的业务场景是有很多的 DDL。在大量 DDL 场景操作下，TiDB 的 region cache 可能会因为某些内在机制没有及时清理，后续的 SQL 查询语句进来的时候，可能会找到实际上已经不存在，但是它认为没有被清理的region。当SQL语句发现数据不存在时，就去寻找下一个可能存在的region，这种情况导致 SQL 执行时间就被不断拉长，使SQL 执行效率下降进而影响到集群的其他语句，最终表现形式就是业务处理性能下降。我们的处理方式是将 DDL 的应用与其中的一个 TiDB server 进行绑定，也就是将 DDL 场景以及语句进行聚合，尽量争取是在一个 TiDB server 进行处理，然后其他的业务 通过 HAProxy 进行负载均衡，把其他的一些读事务分发到其他的 TiDB server 进行处理，减少 DDL 事务与读事务之间的影响，从而保障读性能。\n\n第三就是锁冲突。大部分企业都是从传统的 Oracle、MySQL 以及 DB2 等数据库进行改造。而TiDB 的锁处理机制与传统数据库不一样，其同时存在乐观事务和悲观事务。对于开发团队来说，一些 SQL 的执行在原来数据库上的执行结果与现有的 TiDB 的执行结果可能会出现差异。建议在改造迁移的时候，比如说从 MySQL 等数据库迁移，在开发的时候要重视开发规范，比如严格使用事务显式声明，像 begin 加上需要执行的SQL语句，加上 commit 的方式，特别是对于 DML 语句，尽可能保证这个事务机制与原来的传统关系型数据库（像 MySQL）一致，减少开发的复杂度，保证数据的准确性。\n\n写在最后，自主创新之路确实会出现许多大大小小的问题，这也需要我们一起去协作解决和攻克这些阻碍。\n\n道阻且长，行则将至。行而不缀，未来可期。","date":"2023-02-07","author":"李轲 蔡茂捷 徐凯","fillInMethod":"writeDirectly","customUrl":"tidb-in-essence-securities","file":null,"relatedBlogs":[{"relatedBlog":{"body":"本文根据 PingCAP DevCon 2021 上来自微众银行资深数据库架构师黄蔚的分享整理而成，主要阐述 TiDB 在微众银行的应用实践，包括微众银行选择 TiDB 的背景和 TiDB 的部署架构，以及 **TiDB 在贷款核心批量场景的应用**，最后分享了**基于 TiDB 优化方案的最佳实践和未来规划。**\n\n## TiDB 的产品优势\n\n从 2018 年底微众银行开始接触 TiDB 的团队，到 2019 年上线，TiDB 在数据库的选型之中展现了很多独有的优势。\n\nTiDB 兼容 MySQL 协议，同时也兼容 MySQL 的生态工具，比如备份、恢复、监控等等，不管是应用本身还是运维或是开发人员，从 MySQL 迁移到 TiDB，其成本和门槛都较低。对于 TiDB 原生的计算、存储分离的架构，用户将不必担心容量或者单机性能的瓶颈，某种程度可以把 TiDB 当作一个很大的 MySQL 来使用。同时 TiDB 的数据多副本强一致的特性对金融场景来说十分重要，TiDB 还天然支持多 IDC 的部署架构，可以支持应用做到同城多活的部署架构。此外，TiDB 开源社区的运营也非常活跃，比如在 AskTUG 平台可以看到很多用户的典型问题的处理方法，包含大量的宝贵经验可以借鉴，可以进一步降低用户使用 TiDB 的门槛。\n\n现在使用 TiDB 的用户越来越多，不管是互联网头部厂商或者金融行业用户都在大量使用，这也是 TiDB 产品越来越成熟的体现，也给更多用户使用 TiDB 带来了更强的信心。\n\n## TiDB 在微众银行的部署架构\n\nTiDB 的特性是否能够满足金融机构高可用的架构需求？\n\n这是 TiDB 在微众银行的部署架构，如图所示，首先 TiKV 选择三副本，分别部署在同城的三个数据中心，这样可以实现 IDC 级别的高可用，同时在每个 IDC 部署了一套 TiDB Server，通过绑定到负载均衡器提供 VIP 服务，这样使得应用可以做到多活接入的模式。这套架构也经受过 IDC 级别的真实故障的演练验证，将其中一个 IDC 的网络全部断掉，观察到集群可以快速恢复，我们认为 **TiDB 能够符合金融场景高可用的要求。**\n\n![devcon-2021-wzyh-1.jpg](https://img1.www.pingcap.com/prod/devcon_2021_wzyh_1_3a834efd9c.jpg)\n\n## 核心批量核算场景\n\n**贷款核心批量核算**是金融行业比较经典且非常重要的场景，我们将其接入到了 TiDB。下图是之前微众银行贷款核心批量应用场景的架构，左边这部分有很多业务单元，相当于把用户的数据做了单元化拆分，每一个单元化数据可能不一样，但架构和部署模型是一样的，底层用的是单实例数据库，同时批量是在每一个单实例数据库上面运行，最终把批量结果 ETL 到大数据平台给下游使用，那么这个架构有哪些瓶颈或者优化点呢？\n\n![devcon-2021-wzyh-2.jpg](https://img1.www.pingcap.com/prod/devcon_2021_wzyh_2_bfa907ed98.jpg)\n\n它是一个**纯批量**的应用，意味着有大量的批量的写入、更新以及运算，而且数据量都特别大，亿级或者十亿级别以上，随着业务快速开展，借据数、用户数和流水数据也在持续增涨，如果使用单机数据库来承载，首先受限于单机数据库的性能上限，跑批耗时会越来越长，而且之前单机数据库负载已经很高，IO、CPU 已经达到 70% ~ 80%，如果想提升跑批效率，应用通过增加并发的方式是有风险的，因为数据库负载太高可能造成主备复制延迟或者遇到故障无法进行快速主备切换，所以效率很难提升；其次单机数据库对这种亿级或者十亿级的表加字段或者数据管理难度非常大，虽然微众银行日常会用 online DDL 工具比如 pt-online-schema-change 来做表变更操作，但也会有小概率锁表风险。另外基于资源利用率考虑，批量系统和联机系统复用了同一套单机数据库，所以如果批量任务造成高负载，很可能会影响联机交易。基于这些背景问题，微众银行借助 TiDB 做了架构优化的升级。\n\n升级改造后的架构如下图所示，可以看到微众银行把各个业务单元的数据通过 DM 工具把数据实时同步和汇总到 TiDB，然后批量 APP 直接基于 TiDB 做批量计算，再把结果传到大数据平台，相当于借助了 TiDB 的水平扩展性来达到批量效率的水平扩展。之前是传统的 MySQL 主备架构，会要求 APP 服务器 要跟 MySQL 的主节点是部署在同一个 IDC，而如果是跨机房访问，网络延时会比较大进而影响批量耗时，所以其他 IDC 的 APP服务器 就处于 standby 的状态，会有一定的资源浪费，而 TiDB 架构的所有 TiKV 节点可以同时读写，所以**可以多个 IDC 同时启动批量任务，最大化资源利用率。**\n\n![devcon-2021-wzyh-3.jpg](https://img1.www.pingcap.com/prod/devcon_2021_wzyh_3_c668ee3b3c.jpg)\n\n## 价值收益\n\nTiDB 在微众银行贷款核心业务场景中的使用，总结有三个主要的价值收益：\n\n**1.批量效率的提高**。下图左边是微众银行其中一个贷款业务的账单日的批量耗时对比，可以看到在单实例架构下面，批量大概是跑三个多小时，而微众银行通过借助 TiDB 进行架构的升级优化后，耗时减少到了 50 分钟左右，有绝对效率上的提升。\n\n![devcon-2021-wzyh-4.jpg](https://img1.www.pingcap.com/prod/devcon_2021_wzyh_4_1ba5ebdea0.jpg)\n\n**2.线性水平扩展**。微众银行的需求不仅仅是效率提升，而且要求其做到水平扩展，也就是弹性伸缩。因为随着业务发展，借据量包括用户量在持续增长，如果存在热点或者其他瓶颈，以后想继续提升将十分困难，下图右边是展示其批量耗时的对比情况，在初始的一个资源情况下大概跑 25 分钟，如果数据量翻倍，耗时增加到 50 分钟，如果想把这个耗时降下来再把资源也翻倍，可以发现耗时又降回到 26 分钟左右，可见已经具备线性扩展能力。所以除了效率上的提升，线性扩展能力的一大好处就是随着业务持续的发展，借据数、借据量都在快速增长，这套架构将无需担心业务快速增长可能出现的技术瓶颈，业务可以更加聚焦于产品本身，这是 TiDB 带来的一个实实在在的业务价值。\n\n![devcon-2021-wzyh-5.jpg](https://img1.www.pingcap.com/prod/devcon_2021_wzyh_5_c687b48c87.jpg)\n\n**3.批量系统与联机交易系统分离**。前面提到跟联机系统是因为资源的考虑做了一个复用，现在拆分之后实际上跟联机就已经完全剥离了，并且没有像单机数据库的主备复制延迟，可以最大化资源利用率来提升批量效率。\n\n## 基于 TiDB 的优化\n\n以上这些收益可以看到比较明显的效果，那么微众银行做了哪些优化或者遇到了哪些问题呢？\n\n1. **SQL 模式优化**。TiDB 因为本身分布式架构其单条请求时延会相对比 MySQL 更高，所以需要去把一些跟数据库频繁交互的请求进行打包，尽量减少交互，比如把多个 select 改成 in 的方式，把 insert 多条改成 insert 单条多 values 的方式，把多个 update 改成 replace 多条 values 的方式。此外，因为把多个单元化的数据全部汇总到一个 TiDB 集群，那么它的单表数据量一定非常非常大，如果跑了一个比较低效的 SQL，很容易把这个集群搞垮，比如存在着 OOM 的风险，所以需要特别注意 SQL 的审核和调优。再比如早期版本会出现执行计划不准确的问题，在 4.0 版本支持 SQL 执行计划绑定，可以对一些高频的 SQL 进行绑定，使其运行更加稳定。因为微众银行接入 TiDB 比较早期，所以主要使用的是乐观锁模式，应用也做了很多适配，目前适配乐观锁模式的代码已经固化为一个通用模块，新系统接入时直接拿来用就可以了。\n\n2. **热点与应用并发优化**。使用 TiDB 比较多的用户可能会对热点这个问题比较熟悉，前面提到弹性伸缩，而要做弹性伸缩，数据必须足够离散，所以微众银行在前期接入 TiDB 的时候也发现像在 MySQL 上的 Auto Increment 特性，可能会存在热点问题，还比如像用户的卡号、借据号也可能是一些连续的数字，所以微众银行针对这两块做了一些调整或优化，比如把它改成 Auto Random，然后把一些卡号，根据它的数据分布规律，通过算法提前把这些数据的分布区间算出来，再通过 Split Region 打散功能进行预打散，这样大批量瞬时写入时就可以充分利用每一个节点的性能；另外也对低频修改、高频访问的小表进行了应用内的缓存处理，缓解热点读问题。除了数据需要足够离散，应用同样也要做分布式改造优化，因为应用是分布式的，所以需要一个 App Master 节点来做数据分片的工作，然后把分片任务均匀分摊到每一个 App 上做运算，运行期间还需要监测每个分片任务的状态和进度；最终通过数据和应用的协同优化，达到整体具备的水平扩展能力。\n\n3. **数据同步与数据校验优化**。这就是前面提到微众银行通过 DM 工具把各个业务单元的数据汇总起来，早期使用的 DM 1.0 版本不具备高可用特性，这在金融场景下是比较致命的。而在 DM 2.0 版本上包括高可用性，兼容灰度 DDL，易用性等等几个特性都已稳定上线。此外是数据校验部分，因为是核心批量场景，数据同步必须做到数据不丢、不错，所以应用也内嵌了数据 checksum 的逻辑，比如在 MySQL 入库时先对数据进行分片，然后把各个分片的 checksum 值写到表里面，再通过 DM 同步到下游 TiDB，最后应用在跑批期间从 TiDB 把各个分片加载出来，然后再跑一遍对应分片的 checksum，再对上下游的 checksum 值进行比对，通过这样的校验机制以确保数据的一致性。\n\n4. **故障演练与兜底预案优化**。这个系统之前是基于 MySQL 的批量系统，迁到 TiDB 后有一些故障场景表现可能会出现非预期的现象，所以微众银行做了大量故障演练，第一是模拟各个 TiDB 组件节点异常，确保应用可以兼容，同时当出现批量中断后，应用也支持断点续跑；第二是整批次重跑，由于可能会遇到程序 bug 或者非预期问题导致整个批次需要重跑，为了快速恢复重跑现场，应用开发了快速备份和 rename 闪回的功能; 第三是针对极端场景的演练，比如假设 TiDB 库出现了整体不可用，微众银行结合 Dumpling 和 Lightning 进行了整集群的快速备份和恢复，难点包括 DM 同步的还原点快速确认、大表人工预打散等等，最后验证的结果符合正确性和时效性的要求。因为这个架构涉及到较多数据流转，所以针对故障场景做了大量的演练以及对应预案 SOP 的编写。\n\n## 未来规划\n\n微众银行从 2018 年开始调研及 POC，2019 年上线了第一个 TiDB 的应用，当前 TiDB 在微众银行的应用领域已覆盖了贷款、同业、科技管理、基础科技等等，当前还有多个核心业务场景在做 POC 测试。针对未来的规划有五个方面：\n\n1. **TiDB 的云原生 + 容器化**。可以带来比如自动化运维能力的提升、资源调配的能力等等。\n2. **基于 Redis + TiKV 的持久化方案**。主要是替换 Redis + MySQL 的兜底方案，借助 TiKV 天然的高可用特性来做持久化的方案。\n3. **基于 SAS 盘低成本应用**。微众银行在行内有很多归档场景，数据量特别大，因为受监管要求需要保留很长时间，针对这种存储容量要求高但低频访问的场景，TiDB 基于 SAS 盘低成本的方向也会做一些试点。\n4. **国产化 ARM 平台的 TiDB 应用**。去年微众银行已经有业务上了 TiDB ARM，未来随着国产化的趋势，这块将会被继续加大投入力度。\n5. **TiFlash 的评估与应用**。TiFlash 提供的是 HTAP 的能力，尤其像实时风控以及轻量 AP 查询的场景会带来很大帮助，这也是微众银行未来的重点规划方向。\n\n> 视频：TiDB 在微众银行核心批量场景的实践  \n\n![微众银行TiDB应用实践.mp4](https://img1.www.pingcap.com/prod/Ti_DB_a131219c09.mp4)\n","author":"黄蔚","category":4,"customUrl":"devcon-2021-webank","fillInMethod":"writeDirectly","id":306,"summary":"本文根据 PingCAP DevCon 2021 上来自微众银行资深数据库架构师黄蔚的分享整理而成，主要阐述 TiDB 在微众银行的应用实践，包括微众银行选择 TiDB 的背景和 TiDB 的部署架构，以及 TiDB 在贷款核心批量场景的应用，最后分享了基于 TiDB 优化方案的最佳实践和未来规划。","tags":["DevCon","核心批量核算"],"title":"TiDB 在微众银行核心批量场景的实践"}},{"relatedBlog":{"body":"> **作者介绍**  \n**陈培新**，参与国信证券基础平台研发工作（DevOps、微服务治理、Serverless）\n\n\n国信证券是一家全国性大型综合类证券公司，在 118 个城市和地区共设有 57 家分公司、185 家营业部，根据中证协发布的数据，近年来国信证券的总资产、净资产、净资本、营业收入、净利润等核心指标排名行业前列。\n\n国信证券从 2020 年 6 月开始接触 TiDB，从技术预研到第一个业务上线大约花了半年时间。第一个上线的业务是金太阳帐单，后面陆续在数据中台、服务观测等系统中应用。从只在东莞主机房的 TiDB 部署到 2021 年 9 月实现 TiDB 多机房的部署，并启动国产海光 x86 服务器的试点工作，国信证券在开源 NewSQL 数据库的探索和应用层面，积累了丰富的实践经验。目前，**国信证券共有 7 个 TiDB 集群，节点数量 109 个，最大表 100 亿，支撑了托管、经纪和自营等业务**。\n\n## 从 0 到 1，国信金太阳引入 TiDB\n\n身处互联网企业，大家可能跟富途牛牛接触的比较多。国信金太阳跟富途牛牛类似，它提供证券交易、理财和咨询相关的服务。我们使用证券软件最主要的功能就是交易，用户在做交易的时候，关注更多的是收益率以及什么时候去买卖股票，用户可以根据证券软件提供的功能对所有的交易做分析。国信金太阳的用户数大概有一千万左右，国信有一个大数据平台，存储了所有用户历年的交易数据，账单存量数据有一百多亿，清仓股票数据量大概是十亿，整个帐单和清仓股票增量数据大概是二十亿每年。\n\n下图是国信金太阳的数据服务架构。金太阳 App 直接连金太阳后端，后端架构基于国信自研的 gRPC 微服务框架构建。跟大多数券商系统一样，金太阳后端对接柜台系统，里面有交易、帐户、清算等各种后台应用。所有数据最后会推送到数据中心，数据中心每天或每周都会做跑批。跑批完之后，会将相关的数据推送到前端的数据库中，用户通过 App 端的查询服务来直接查询这个数据库，从而获取相关的帐单以及清仓股票的数据。\n\n![1.png](https://img1.www.pingcap.com/prod/1_9b780638af.png)\n\n<center>图：国信金太阳数据服务架构</center>\n\n整个账单经历了三个版本，账单 1.0 我们可以称它为**刀耕火种**的时代。在 1.0 版本的时候，只支持一年账单的查询，使用的是单库单表 SQL Server。具体是怎么实现的？首先，数据中心每天会将数据同步到一张临时表中，然后进行数据转换的服务，这个临时表的数据会加到正式表里面，正式表里面保存的是一年的数据量。在单库单表的情况下，通过一个中间程序将所有一年的数据都压缩到某一列里面去，里面是一个 JSON 字符串，存的是一年 365 天的数据。那如果新一天有新数据来了怎么办？这边会起一个临时任务，将新的一天推过来的数据压入到这个 JSON 里面去，再倒推 365 天，把以前最早那天的数据清除，最后再写到正式表里面去。可以看到，这其实是一个非常原始的实现。为什么要使用 JSON 这种格式？因为我们的数据用户量大概有一千多万，如果是每天存一行的话，用单库单表肯定是 hold 不住的。所以一开始，我们用了一个非常取巧的方式，将 360 多行给它并了一行，这样的话整个表的数据量将近有一千多万，查询效率还可以。\n\n![2.png](https://img1.www.pingcap.com/prod/2_d194e09786.png)\n\n<center>图：账单 1.0 单库单表实现方式</center>\n\n这种方式面临的问题是：业务上，用户是希望查询更长时间的数据，比如五年，使用单表的话，这一项其实是难以满足的。技术上，数据查询以及后续的更新压力大，难以扩展，有时候会出现数据更新出错，第二天用户来查询的时候，查到的数据就不准确了。\n\n为了应对这些业务和技术难点，国信在账单 2.0 版本使用 sharding-jdbc 来做分库分表。在引入这个技术的时候，我们也听说了 TiDB，考虑到**证券业务对稳定性要求较高**，当时对 TiDB 稳定性还有一定的担忧，所以选择了 sharding-jdbc。做了分库分表之后，可以支持 5 年帐单的查询，使用了 16 台 MySQL，总共分了 512 张表。数据中心与分库分表是如何进行同步的？数据中心还是和以前每天一样，先把数据写到临时表，转换服务会配置分库分表的规则，从临时表里面取数据，最后写到正式表里面。数据中心有个  ETL 工具，它不支持扩展，所以就没有直接写入到正式表。\n\n![3.png](https://img1.www.pingcap.com/prod/3_a5cebf7d86.png)\n\n<center>图：账单 2.0 分库分表实现方式</center>\n\n大概跑了两年时间，我们发现了新问题，分库分表虽然可以满足业务需求，但后续在扩展性方面有很大的约束，这些约束包括：第一，字段扩展困难，我们分了 512 张表，如果要有新业务上来，需要新增一个字段，这个时候 DBA 就会很痛苦，需要到每个分表新增字段。第二，扩容极其麻烦，数据一开始预估不准确的话，后面分库分表的规则就一定要变，从一开始 512 张表要变到再乘以 2，变到一千多张表，DBA 迁移的工作非常繁杂，而且很容易出错。第三，同步还需要中间表，所以数据同步的时间也还是一样的慢，并且制约系统上线时间。第四，分表的定时创建跟清理也比较繁琐，每天会将一些日表删掉，比如五年前的表，然后还要去创建第二天的表，在开发的时候，始终是要使用这个定时器来做清理和创建。第五，运维方面，也要运维多个数据库。\n\n到了账单 3.0 的时候，公司的开发和运维方提出了需求，分库分表虽然可以搞定，但是太麻烦了。借这个机会，我们把 TiDB 引入到国信证券里面来，使用 NewSQL 数据库来支持 5 年账单查询。数据中心就直接将数据每天直接推到正式表里面，查询服务方面就是直接去查询 TiDB，在 TiDB 之上加了缓存，**每天同步入库的效率较以前提升了大概 70% 左右**。当前 TiDB 已经在国信三地机房里面做了部署，同时在东莞机房最近也在做国产海光 x86 服务器的试点。\n\n![4.png](https://img1.www.pingcap.com/prod/4_75ffe3786a.png)\n\n<center>图：账单 3.0 TiDB 分布式数据库实现方式</center>\n\n接下来谈谈一年多来 TiDB 相关的使用心得。从开发角度来看，首先是大数据量删除，一开始没有经验，还是按照以前老的套路，比如要删除指定某一天的数据，直接就是 DELETE SQL WHERE = “某一天”，当时是周六，运维告警显示 TiDB 有很多台机器逐个地挂掉，后来找排查发现 DELETE SQL 太大了，后续把事务大小调到 10 G，扩展 TiDB 机器内存到 64 G，这部分是满足系统层面的扩展。另外一方面是在应用程序侧做改造，需要去做分批的删除，可考虑使用 Range 分区表，删除数据直接 truncate 或 drop 分区即可。\n\n第二个经验是对新上 TiDB 的业务，尽量要使用 AUTO-RANDOM 作为主键，对那种持续插入、大量插入，很大情况下可以避免插入的热点。对于多机房数据同步，TiDB 是需要主键或者唯一索引，无主键或者唯一索引会造成同步 OOM。在表已有大量数据的时候，如果要加这个主键，整个过程也会比较麻烦。\n\n## 三地高可用容灾架构的实现\n\n一开始只在国信东莞主机房作为试点去做 TiDB 的部署，后续运维要求 TiDB 要做容灾部署相关的工作，应用要实现三地的高可用多活。之前每个机房的应用是访问自己本地的 TiDB ，每个季度会做灾备演练，验证东莞整个主机房故障之后，异地上海与同城福田灾备的可用性。\n\nPingCAP 的老师一开始给了三个方案。第一个方案是最简单直白的，在**三个机房都部署一套单独的 TiDB 集群**。东莞机房做读写，用 TiCDC 或者 binlog 将对应的数据同步到其他两个机房的灾备集群。这个方案的优点是比较简单，做灾备演练的时候，如果东莞主机房挂了，其他两个机房的应用基本上不用做什么操作，还是可以继续使用。这个方案存在问题是副本数比较大，需要有 9 个副本，同步的时延可能也会大一点。\n\n第二个方案是比较经典的**两地三中心**，这个方案对于网络的要求比较高，而且如果东莞机房挂了，福田机房要做一下手动恢复。第三个是**同城双中心**，把东莞跟福田当成一个集群，将数据同步到上海灾备集群，也就是两个集群。但这个方案在做灾备演练的时候做恢复也会比较复杂。\n\n![5.png](https://img1.www.pingcap.com/prod/5_60cdfd6a5d.png)\n\n<center>图：多机房方案对比</center>\n\n经过三个方案的对比，最后国信还是采用了最简单的 binlog 同步方案，每个机房部署一个 TiDB 集群，这也是根据业务特点来实现的。国信的业务基本上使用查询，不会存在多个机房同时写入，所以最后采用了这个最简单的方法。在多机房部署实现的过程中做了一些迁移导入的工作：一开始只有东莞机房，因为对于 TiDB 的使用不熟悉，有一些业务表是没有加主键或者没有唯一索引。福田机房搭建新的 TiDB 集群之后，我们发现在做两地集群同步的时候，同步器就直接 OOM 了，是因为没有加主键或唯一索引导致的。当时有一张最大的表已经到 60 多亿了，如果直接在表上加主键或者唯一索引的话其实是不可能的。\n\n那我们是怎么做到的呢？首先使用 Dumpling 将这个表导出到 CSV 文件，这个 CSV 文件的命名是带有表的名称的，在导出完成之后在原来的数据库上面去创建新表，里面加上主键或者唯一索引，再把导出的这两个 CSV 文件重命名跟新表一样，然后通过 Lightning 把数据导入到这个新的表里面，最后把旧表和新表给重命名，把这张新的表命名为正式表，正式表重命名为备份表，这样做的话可以尽量的减少对业务的影响，在导入导出的过程中，用户基本上是无感的。\n\n![6.png](https://img1.www.pingcap.com/prod/6_d33080e331.png)\n\n<center>图：无主键表处理</center>\n\n## 服务可观察的探索\n\n最后谈谈在金太阳**服务可观察方面**的探索。应用在使用了微服务架构之后，部署的节点会非常多，而且调用链整个过程也非常复杂，这个时候想定位一个问题就会很复杂，根据业界当前比较流行的 “服务可观察” 概念我们做了一个应用来辅助开发的问题定位。这个 “服务可观察应用” 主要是包含三个部分，一个是日志，第二个是指标，最后一个是跟踪链。我们针对日志部分做了增强，把系统的请求和响应日志通过 ETL 工具转换到 TiDB 里面，然后做了可视化相关的工作。\n\n![7.png](https://img1.www.pingcap.com/prod/7_719828aeae.png)\n\n<center>图：金太阳服务的可观测性</center>\n\n**可视化**部分是开发一直提的需求，采集了日志一般都是在 ELK 的 Kibana 里面看，都是一些文本，这是非常不直观的。我们做的优化是对于每个微服务的请求跟响应日志我们都导入到 TiDB 里面，用 “服务可观察” 应用去做展示。如果客户有什么问题，输入客户的手机号就可以很直观地看出这个客户在某个时间段做了什么操作，从而可以很快定位问题，同时我们也将内容和响应进行可视化，看起来更加方便。 \n\n当时在做 TiDB 入库也遇到一些问题，因为这个业务特点跟账单不一样，账单基本上都是每天晚上做插入，白天用户做查询操作。并且该业务在开市期间（上午九点到下午三点多）会做持续大量的插入，查询操作会比较小，有问题的时候才上去做查询。这是一个运维相关系统，所以没有用很好的磁盘，系统上线后就发现整个 TiDB 变得非常卡，一开始以为是插入的程序或者查询程序有问题，我们做了很多优化，发现还是不行，最后升级完磁盘之后发现整个性能获得了直接的提升。我们得到的经验就是上 TiDB 的话，一定要选择好的磁盘，这样才能确保处理效率。","author":"陈培新","category":4,"customUrl":"tidb-in-guosen-securities","fillInMethod":"writeDirectly","id":335,"summary":"本文讲述了 TiDB 在国信证券海量数据高并发场景中的实践。国信证券从 2020 年 6 月开始接触 TiDB，从技术预研到第一个业务上线大约花了半年时间。第一个上线的业务是金太阳帐单，后面陆续在数据中台、服务观测等系统中应用。","tags":["用户实践","高并发","服务可观察"],"title":"TiDB 在国信证券海量数据高并发场景中的实践"}}]}}},
    "staticQueryHashes": ["1327623483","1820662718","3081853212","3430003955","3649515864","4265596160","63159454"]}