jillme
作者jillme2020-12-15 15:10
CIO, 某大型银行

某单位海量数据存储、应用实践

字数 6388阅读 6699评论 3赞 3

一、 项目建设背景

随着大数据、云计算、移动互联迅速发展,快速交付与灵活扩展的强烈需求增长,传统竖井式的 IT 基础架构设施面临着新的挑战。一方面快速增长的互联网业务需要灵活的、可自由伸缩、不限于规格容量的存储的 IT 软硬件资源提供坚实基础保障,另一方面高效的业务响应同传统的 IT 基础设施发展矛盾也日益突出。例不可预估的互联网业务客户量、持续增长的日交易量、重要时期的高峰的运行压力、大量并发 IO 读写,系统响应缓慢,关键指标时效性不足,而这些性能痛点最先反映在数据存储 IO 上。

因此如何全面规划和整合当前 IT 基础架构中的数据存储体系,构建灵活、高效、先进的高可用存储架构,实现可满足生产系统的高并发、低延时的性能需求,是金融机构 IDCIT 信息化建设的迫切要求。

二、 高性能高并发的数据存储建设痛点

随着信息大数据时代的来临,对信息收集的需求越来越高,在原来客户交易信息留存的基础上,增加了客户的行为及客户的属性等信息。 对于一个大型的应用系统,海量数据的存储和访问成为了系统设计的瓶颈问题。

我机构原先系统采用的是 oracle 的 RAC 作为数据存储,随着业务量和数据量的增大,对于系统的稳定性和扩展性造成了极大的问题。现在采用 postgres 集群 +redis 内存数据库 +Druid 实时分析数据库 +hbase 列式数据库 +hdfs+kafka 消息队列;辅以 Minio 分布式文件存储实现的,目前使用效果良好,但在整合建设的初期,是存在许多技术痛点的。

1、 是否坚持所有数据一致性原则

传统的项目,几乎清一色的使用传统的关系型数据库 (RDBMS) 。从早期的 mysql 、 sqlserver 到后期的 informix 、 db2 、 oracle 再到 oracle rac. 。关系型数据库是强事物一致性 (ACID) ,使用比较早,技术相对成熟。

ACID 它的核心是“约束”,而这个“约束”由数据库的使用者告诉数据库,使用者要求数据一定是符合这样或者那样的约束条件。当数据发生修改时,数据库会检查数据是否还符合约束条件,如果约束条件不再被满足,那么修改操作不会发生。关系数据库最常见的两类约束是“唯一性约束”和“完整性约束”,表格中定义的主键和唯一键都保证了指定的数据项绝不会出现重复,表格之间定义的参照完整性也保证了同一个属性在不同表格中的一致性。

当数据库系统从批量处理进化到在线实时系统后,事务就可以并发地在数据库上进行操作,在给使用者带来便利的同时也给数据库系统开发人员带来了诸多困难。严肃的数据库系统都会有一套复杂的并发控制机制来保证事务并行执行时数据的正确性。而事务隔离性最大的烦恼来自并发控制对性能的影响,最严格的隔离性保证了所有的事务虽然是并发执行,但是最终执行的结果跟事务一个个串行着做是一样的,可串行化保证了一定不会因为并发进行的事务导致数据出错,但是这也会导致事务有更多等待或者失败。

在进入大数据时代后,超高的并发访问量以及海量的数据,注定使用 ACID 的原则将使得系统需要一个性能极高的计算器进行运算。无疑这给系统带来了巨大开销浪费。

原本单位使用的是 ORACLE 的 RAC ,但是在越来越多的数据存储和更多的访问并发,单点 IO 吞吐量的制约效果,越来越明显。

当关系型数据库越来越成为瓶颈时,为解决单点瓶颈,适当采取牺牲 CAP 属性中的 C ,也不失为一个可选的策略。

早期的系统调研中,有的场景对于实时性一致性要求高,但是每次操作的数据量不大。而在其他的常见中,每次操作的数据量较大,但是对于数据的实时一致性没有过高的要求。

基于此,对于数据存储的选型,要区别对待。对于前后数据需要一致性的,依旧采用关系型数据库,用数据库事务来保证数据的 ACID 一致性要求。对于并发访问量高,但是数据的时效性和对比关联性不是很强的场景,我们采用分布式数据存储来应对。

经过多次选型调研,最终选择了 postgres 数据库作为关系型数据库的载体,用于 ACID 的场景。使用 NOSQL 的数据存储作为高并发访问的场景的数据存储。

2、 非关系型数据库选型

市面常见的 NOSQL 包括 redis,duri , hbase,mongdb,hive 等。对于不同应用场景的选择是不同的。

MongoDB 表结构灵活可变,字段类型可以随时修改。记录以 Json 格式后存储,不需要定义表结构。但是多表查询、复杂事务等高级操作效率低下。所以其适合于写少读多的场景。

HBase 列式存储特性带来了海量数据规模的支持和极强的扩展能力,但是由于查询都必须要依赖 rowKey ,这就使得很多复杂查询难以进行。例如,如果你的查询条件涉及多个列项,或者你无法获取要查询数据的 key ,那么查询效率将会非常低下。

Druid 是基于 MPP 架构的 OLAP ,其预聚合算是 Druid 的一个非常大的亮点,通过预聚合可以减少数据的存储以及避免查询时很多不必要的计算。适用于大量数据的下的实时聚合查询场景。

Redis 牺牲了常规数据库中的数据表、复杂查询等功能,特别适合那些对读写性能要求极高,查询条件也同样简单的应用场景。

HIVE 数据仓库,基于 HDFS 的结构,支持主流的 SQL 但是查询的速度较慢,适合于大批量场景的数据加工,存储的场景。

下面有个对比的表格:

支持情况RedisDuridHbaseMonodbHive
数据规模
批量查询性能
批量写入性能
支持表级关联不支持不支持不支持
聚合查询不支持不支持
亚秒级查询
亚秒级写入

3、 数据灾备方式的选择

数据是科技公司最大的资产,每个公司都在数据灾备上面作为了大量的应用防止出现意外时候,数据丢失及访问异常。为最大程度的降低风险。早期考虑 dump 每天的数据快照,在异地数据库进行恢复,但是这样存在 dump 期间的数据丢失情况。一旦出现数据服务器 down 机的情况,备库是无法承接使用的。

现在 postgres 集群本地采用一主两从的流复制方式,保证主从节点之间数据一致性。同时在一台从节点上使用级联复制为异步 IDC 提供数据同步服务。

Hdfs 采用跨 idc 机架的方式, redis 、 durid 、 mongodb 采用集群模式、保证数据灾备时候,能够快速切换到备机使用,且数据不会丢失。

三、 建设实践

1、 关系型数据库应用

关系型中数据库切分存储

由于去 IOM 的要求及未来国产化、开源化的大趋势。我们最终选择了 postgres 作为关系型数据库的载体。

单库 postgres 性能无法满足高并发访问的要求,采用了分库分表的数据逻辑切分。由于是强职能管理型的系统特性。客户关联的数据信息使用基于所在辖区水平分库切分,而管理公共信息、统计报表信息、数据概览信息、以垂直切分的方式切分。对于常用的表,在各个数据库中冗余存储。以此减少 OLAP 操作时网络传输的耗时,同时便于利用数据库本身的特性。

这样切分,虽然不同的数据库中数据相较于一致性 hash 分库原则会不一致,不同辖区对应的数据库中数据量可能不一样多,牺牲了一部分的存储。但是较系统的性能,还是值得的。

同时对于数据库当日产生的操作信息及交易流水,按照一致性 HBASE 的原理,将流水信息存储在以流水号切分的数据库节点中存储。

关系型中数据库 HA

在众多的 PostgreSQL HA 方案中,流复制 HA 方案是性能,可靠性,部署成本等方面都比较好的,也是目前被普遍采用的方案。而用于管理流复制集群的工具中, Pacemaker+Corosync 又是比较成熟可靠的。同时为了兼顾异地灾备,以一个从节点进行级联复制,将数据异地灾备到其他 IDC 机房节点。

系统基于 Pacemaker+Corosync 实现 PG 集群的 Master-Slave 模式,如图所示:

读写分离、高可用

使用 pacemaker 实现集群资源的管理,业务层通过 write-vip 实现数据向 Master 节点的写入,通过 read-vip 实现 Slave 节点数据的读取;主节点故障时, vip 会自动漂移,从节点升为主库,实现 PG 的高可用。

数据、状态同步

Master 与 Slave 节点基于流复制( Steaming Replication )通过 1.X ( eth1 )网段实现数据的同步;通过 2.X ( eth2 )网段, corosync 实现 Master 与 Slave 节点状态同步。

主从切换策略**

  1. 初始状态下, master 数据库和 write-vip 在节点 1 上运行, slave 数据库和 read-vip 在节点 2 上运行。
  2. 当 master 数据库或 master 数据库所在节点宕机时,节点 2 上的 slave 数据库提升为 master 数据库,同时 write-vip 飘移到节点 2 上。
  3. 当 slave 数据库所在节点 2 宕机时, slave 数据库停止运行, read-vip 飘移到 node1 。

2、 redis 内存数据库存放热点数据以及公共参数和映射参数

REDIS 数据存储内容

由于客户信息进行了切分。为了快速的找到一个客户所在的信息。我们将客户及客户所在数据库的映射关系、客户交易流水的 hash 键值的映射关系作为热点数据存放于 REDIS 中。

同时系统中需要承载的公共参数也放入了 redis 中。

同时将客户交易信息中,交易金额超过 1 万元的大额数据交易信息以及每天日终提取出最近一季度活跃的客户信息,将这部分活跃的客户关键标志信息和大额交易标志信息,也存放在 redis 中,用于检索时候,直接在内存中进行检索,而非直接访问数据库,当 REDIS 中没有的时候再访问对应的数据库。

REDIS 的 HA

映射关系、公共参数采用集群模式部署 HA 。热点数据由于数据量较大,集群模式写入慢,采用了哨兵的模式部署 HA 。

其中哨兵 3 台节点 集群 6 台节点。

3、 Durid 检索聚合重点信息

有时候存在在全单位维度的数据 OLAP 的数据加工和抽样。如果在每个数据库中抽样结果聚合后,在通过程序二次筛选,一方面架构复杂,另外一方面开发成本较高。为此我们引入了 druid ,在其中存储了全机构的所有客户和客户的重点属性信息。

每次需要聚合查询的时候,从 druid 中根据客户重点信息检索出目标集合。如果目标集合的展示信息不够,在根据目标集合到对应的 PG 分库或者 HBASE 中查询出应的数据信息。

4、 Hbase 应用历史交易明细信息

明细信息存放于 hbase 中注意基于以下几个情况:

PG 分库分表存放:

( 1 )数据量较大, PG 数据库压力过大,数据库内存数据的频繁交换

( 2 )分库分表,数据库维护成本的增加,例如数据库表清理维护,数据同步策略,路由策略。

采用 druid 存储:

大量数据存入 druid , druid 集群压力大。

由于 HBASE 适合于读少写多的情况,而历史明细一般查询较少。所以放入 HBASE 进行保存。

于是采用了将索引与数据存储隔离的原则,只把可能参与条件检索的字段索引到 druid 中,这样整个 druid 集群压力减少到原来的 1/N ,全量的客户历史交易明细根据检索出的主键,作为 ROWKEY 在 hbase 内查询。

实际应用中,用客户号 + 日期 + 交易流水号作为 ROWKEY 。当发生交易时候,首先在交易数据库节点写入当天的流水信息。同时写入的操做通过 kafka 消息队列传到后线服务。后线服务实时写入 HBASE 中存放历史交易明细的表中

5、 MongoDb 应用用户的属性行为偏好信息

因为系统的定位原因,系统主要用户客户信息的检索,并对客户进行产品推荐以及其他金融服务。所以客户的属性信息是访问量最大的。但是其修改又很少。这种正适合于 MongoDB 的应用场景。

每天晚上通过 hive 数据仓库,加工出客户的属性信息。将其导入 MongoDB 用于白天的高并发访问的查询。

数据存储和 HA

MongoDB 有三种集群部署模式,分别为主从复制( Master-Slaver )、副本集( Replica Set )和分片( Sharding )模式。

Master-Slaver 因为不提供自动 HA 功能,所以建设中没有考虑使用。

Replica Set 将数据复制多份保存,不同服务器保存同一份数据,在出现故障时自动切换,实现故障转移。但遇到需要存储海量数据的情况时,副本集机制就束手无策了。副本集中的一台机器可能不足以存储数据,或者说集群不足以提供可接受的读写吞吐量。

所以最终选择了 Sharding 模式,它将数据分开存储,不同服务器保存不同的数据,所有服务器数据的总和即为整个数据集。

Mongodb(R) 表示路由节点 , 点 Mongodb(C) 表示配置节点, Mongodb(M) 表示主节点, Mongodb(S) 表示备节点, Mongodb(A) 表示仲裁节点 .

Mongodb(M) , Mongodb(S) , Mongodb(A) 组成一个分片服务器,整个的数据分布存储在不同的分片服务器中。其中 Mongodb(M) , Mongodb(S) 用于实际数据存储。 Mongodb(A) 负责仲裁选主,不存储数据。

Mongodb(R) 在集群中可作为路由使用,客户端由此接入,让整个集群看起来像是一个单一的数据库,提供客户端应用程序和分片集群之间的接口。

Mongodb(C) 是独立的一个 mongod 进程,保存集群和分片的元数据,在集群启动最开始时建立,保存各个分片包含数据的信息

6、 HIVE 数据仓库

在 hdfs 中构建 hive 数据仓库,用于上面 5 部分的数据加工源。

Hive 的数据源来源于本系统的数据和外系统的数据。本系统数据通过 KAFKA 写入 HIVE ,外系统数据通过文件的方式采集。

hive 的 HA

Hive 的高可用分为 Hive Metastore 的高可用和 HiveServer2 的高可用。

Hive Metastore HA 解决方案旨在处理 Metastore 服务失败。每当部署的 Metastore 服务关闭时, Metastore 服务在相当长的时间内都会保持不可用状态,直到恢复服务为止。为避免此类停机,在 HA 模式下必须部署 Metastore 高可用,而不是只有 HiveServer2 的高可用。

四、 实践应用架构

五、 建设后小感

其实数据建设不是一蹴而就的,很多时候都是在实践中边摸索边前进。本单位的数据应用建设也是经过了多个阶段,很有幸,自己都全程参与了。最早的时候 RAC 。到 RAC+ 集群离线,到集群离线 +PG 集群 最后发展到 NOSQL+ 集群流批 +PG 集群 + 内存缓存的模式。

建设到本期之后,数据的支持能达到在 10000+TPS 的时候访问 60 亿以上记录达到秒级响应。最长耗时不超过 2.5S 。在数据容量 300TB 以上,这样的并发条件下,取得这个成绩我个人还是蛮欣慰的。未来数据湖的出现,可能有一批新的技术等待我们应用。

数据建设应用未来路漫漫长远,希望有志同道合者一起讨论。


作者简介:
董生,拥有13年IT工作经验,有丰富的互联网金融从业经历和金融机构工作履历,从事过交易系统、数据治理及数据架构设计和基于产品设计,擅长互金产品、客户管理、资金清算及风控领域,曾在多家金融机构任职CIO和高级产品经理。目前就职于某银行。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

3

添加新评论3 条评论

amanyamany系统架构师, zes
2021-03-15 11:56
这么复杂的系统,集群规模多大?后续运维会不会很复杂?
else_xieelse_xie系统运维工程师, NZX
2021-02-26 08:42
分库分表,后续的运维很考验
lzx660927lzx660927高级工程师/顾问, 浏阳市中医医院
2020-12-15 16:33
写得好,作者在数据存储技术方面,知识面广、经验丰富,值得分享和学习,
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广