数据库架构 - 如何设计结构化数据存储

转自:https://mp.weixin.qq.com/s/op8OGgJbBNwHd7A0eNLXeA ,有省略。

如何设计结构化数据存储

前言 

传统的数据系统就是所谓的『大数据』技术,这是一个被创造出来的名词,代表着新的技术门槛。近几年得益于产业的发展、业务的创新、数据的爆发式增长以及开源技术的广泛应用,经历多年的磨炼以及在广大开发者的共建下,大数据的核心组件和技术架构日趋成熟。特别是随着云的发展,让『大数据』技术的使用门槛进一步降低,越来越多的业务创新会由数据来驱动完成。

『大数据』技术会逐步向轻量化和智能化方向发展,最终也会成为一个研发工程师的必备技能之一,而这个过程必须是由云计算技术来驱动以及在云平台之上才能完成。应用系统和数据系统也会逐渐融合,数据系统不再隐藏在应用系统之后,而是也会贯穿在整个业务交互逻辑。传统的应用系统,重点在于交互。而现代的应用系统,在与你交互的同时,会慢慢地熟悉你。数据系统的发展驱动了业务系统的发展,从业务化到规模化,再到智能化。

  • 业务化:完成最基本的业务交互逻辑。
  • 规模化:分布式和大数据技术的应用,满足业务规模增长的需求以及数据的积累。
  • 智能化:人工智能技术的应用,挖掘数据的价值,驱动业务的创新。

向规模化和智能化的发展,仍然存在一定的技术门槛。成熟的开源技术的应用能让一个大数据系统的搭建变得简单,同时大数据架构也变得很普遍,例如广为人知的Lambda架构,一定程度上降低了技术的入门门槛。但是对数据系统的后续维护,例如对大数据组件的规模化应用、运维管控和成本优化,需要掌握大数据、分布式技术及复杂环境下定位问题的能力,仍然具备很高的技术门槛。

数据系统的核心组件包含数据管道、分布式存储和分布式计算,数据系统架构的搭建会是使用这些组件的组合拼装。每个组件各司其职,组件与组件之间进行上下游的数据交换,而不同模块的选择和组合是架构师面临的最大的挑战。

数据系统架

上图是一个比较典型的技术架构,包含应用系统和数据系统。这个架构与具体业务无关联,主要用于体现一个数据应用系统中会包含的几大核心组件,以及组件间的数据流关系。应用系统主要实现了应用的主要业务逻辑,处理业务数据或应用元数据等。数据系统主要对业务数据及其他数据进行汇总和处理,对接BI、推荐或风控等系统。整个系统架构中,会包含以下比较常见的几大核心组件:

  • 关系数据库:用于主业务数据存储,提供事务型数据处理,是应用系统的核心数据存储。
  • 高速缓存:对复杂或操作代价昂贵的结果进行缓存,加速访问。
  • 搜索引擎:提供复杂条件查询和全文检索。
  • 队列:用于将数据处理流程异步化,衔接上下游对数据进行实时交换。异构数据存储之间进行上下游对接的核心组件,例如数据库系统与缓存系统或搜索系统间的数据对接。也用于数据的实时提取,在线存储到离线存储的实时归档。
  • 非结构化大数据存储:用于海量图片或视频等非结构化数据的存储,同时支持在线查询或离线计算的数据访问需求。
  • 结构化大数据存储:在线数据库也可作为结构化数据存储,但这里提到的结构化数据存储模块,更偏在线到离线的衔接,特征是能支持高吞吐数据写入以及大规模数据存储,存储和查询性能可线性扩展。可存储面向在线查询的非关系型数据,或者是用于关系数据库的历史数据归档,满足大规模和线性扩展的需求,也可存储面向离线分析的实时写入数据。
  • 批量计算:对非结构化数据和结构化数据进行数据分析,批量计算中又分为交互式分析和离线计算两类,离线计算需要满足对大规模数据集进行复杂分析的能力,交互式分析需要满足对中等规模数据集实时分析的能力。
  • 流计算:对非结构化数据和结构化数据进行流式数据分析,低延迟产出实时视图。

对于数据存储组件我们再进一步分析,当前各类数据存储组件的设计是为满足不同场景下数据存储的需求,提供不同的数据模型抽象,以及面向在线和离线的不同的优化偏向。我们来看下下面这张详细对比表:

 

派生数据体系 

在数据系统架构中,我们可以看到会存在多套存储组件。对于这些存储组件中的数据,有些是来自应用的直写,有些是来自其他存储组件的数据复制。例如业务关系数据库的数据通常是来自业务,而高速缓存和搜索引擎的数据,通常是来自业务数据库的数据同步与复制。不同用途的存储组件有不同类型的上下游数据链路,我们可以大概将其归类为主存储和辅存储两类,这两类存储有不同的设计目标,主要特征为:

  • 主存储:数据产生自业务或者是计算,通常为数据首先落地的存储。ACID等事务特性可能是强需求,提供在线应用所需的低延迟业务数据查询。
  • 辅存储:数据主要来自主存储的数据同步与复制,辅存储是主存储的某个视图,通常面向数据查询、检索和分析做优化。

为何会有主存储和辅存储的存在?能不能统一存储统一读写,满足所有场景的需求呢?目前看还没有,存储引擎的实现技术有多种,选择行存还是列存,选择B+tree还是LSM-tree,存储的是不可变数据、频繁更新数据还是时间分区数据,是为高速随机查询还是高吞吐扫描设计等等。数据库产品目前也是分两类,TP和AP,虽然在往HTAP方向走,但实现方式仍然是底层存储分为行存和列存。

再来看主辅存储在实际架构中的例子,例如关系数据库中主表和二级索引表也可以看做是主与辅的关系,索引表数据会随着主表数据而变化,强一致同步并且为某些特定条件组合查询而优化。关系数据库与高速缓存和搜索引擎也是主与辅的关系,采用满足最终一致的数据同步方式,提供高速查询和检索。在线数据库与数仓也是主与辅的关系,在线数据库内数据集中复制到数仓来提供高效的BI分析。

这种主与辅的存储组件相辅相成的架构设计,我们称之为『派生数据体系』。在这个体系下,最大的技术挑战是数据如何在主与辅之间进行同步与复制。

 

上图我们可以看到几个常见的数据复制方式:

  • 应用层多写:这是实现最简单、依赖最少的一种实现方式,通常采取的方式是在应用代码中先向主存储写数据,后向辅存储写数据。这种方式不是很严谨,通常用在对数据可靠性要求不是很高的场景。因为存在的问题有很多,一是很难保证主与辅之间的数据一致性,无法处理数据写入失效问题;二是数据写入的消耗堆积在应用层,加重应用层的代码复杂度和计算负担,不是一种解耦很好的架构;三是扩展性较差,数据同步逻辑固化在代码中,比较难灵活添加辅存储。 
  • 异步队列复制:这是目前被应用比较广的架构,应用层将派生数据的写入通过队列来异步化和解耦。这种架构下可将主存储和辅存储的数据写入都异步化,也可仅将辅存储的数据写入异步化。第一种方式必须接受主存储可异步写入,否则只能采取第二种方式。而如果采用第二种方式的话,也会遇到和上一种『应用层多写』方案类似的问题,应用层也是多写,只不过是写主存储与队列,队列来解决多个辅存储的写入和扩展性问题。

  • CDC(Change Data Capture)技术:这种架构下数据写入主存储后会由主存储再向辅存储进行同步,对应用层是最友好的,只需要与主存储打交道。主存储到辅存储的数据同步,则可以再利用异步队列复制技术来做。不过这种方案对主存储的能力有很高的要求,必须要求主存储能支持CDC技术。一个典型的例子就是MySQL+Elasticsearch的组合架构,Elasticsearch的数据通过MySQL的binlog来同步,binlog就是MySQL的CDC技术。

『派生数据体系』是一个比较重要的技术架构设计理念,其中CDC技术是更好的驱动数据流动的关键手段。具备CDC技术的存储组件,才能更好的支撑数据派生体系,从而能让整个数据系统架构更加灵活,降低了数据一致性设计的复杂度,从而来面向高速迭代设计。可惜的是大多数存储组件不具备CDC技术,例如HBase。而阿里云Tablestore具备非常成熟的CDC技术,CDC技术的应用也推动了架构的创新。

一个好的产品,在产品内部会采用派生数据架构来不断扩充产品的能力,能将派生的过程透明化,内部解决数据同步、一致性及资源配比问题。而现实中大多数技术架构采用产品组合的派生架构,需要自己去管理数据同步与复制等问题,例如常见的MySQL+Elasticsearch,或HBase+Solr等。这种组合通常被忽视的最大问题是,在解决CDC技术来实时复制数据后,如何解决数据一致性问题?如何追踪数据同步延迟?如何保证辅存储与主存储具备相同的数据写入能力? 

存储组件的选型

架构师在做架构设计时,最大的挑战是如何对计算组件和存储组件进行选型和组合,同类的计算引擎的差异化相对不大,通常会优先选择成熟和生态健全的计算引擎,例如批量计算引擎Spark和流计算引擎Flink。而对于存储组件的选型是一件非常有挑战的事,存储组件包含数据库(又分为SQL和NoSQL两类,NoSQL下又根据各类数据模型细分为多类)、对象存储、文件存储和高速缓存等不同类别。带来存储选型复杂度的主要原因是架构师需要综合考虑数据分层、成本优化以及面向在线和离线的查询优化偏向等各种因素,且当前的技术发展还是多样化的发展趋势,不存在一个存储产品能满足所有场景下的数据写入、存储、查询和分析等需求。有一些经验可以分享给大家:

  • 数据模型和查询语言仍然是不同数据库最显著的区别,关系模型和文档模型是相对抽象的模型,而类似时序模型、图模型和键值模型等其他非关系模型是相对具象的抽象,如果场景能匹配到具象模型,那选择范围能缩小点。
  • 存储组件通常会划分到不同的数据分层,选择面向规模、成本、查询和分析性能等不同维度的优化偏向,选型时需要考虑清楚对这部分数据存储所要求的核心指标。
  • 区分主存储还是辅存储,对数据复制关系要有明确的梳理。(主存储和辅存储是什么在下一节介绍)
  • 建立灵活的数据交换通道,满足快速的数据搬迁和存储组件间的切换能力,构建快速迭代能力比应对未知需求的扩展性更重要。

另外关于数据存储架构,我认为最终的趋势是:

  • 数据一定需要分层
  • 数据最终的归属地一定是OSS
  • 会由一个统一的分析引擎来统一分析的入口,并提供统一的查询语言

结构化大数据存储

定位

结构化大数据存储在数据系统中是一个非常关键的组件,它起的一个很大的作用是连接『在线』和『离线』。作为数据中台中的结构化数据汇总存储,用于在线数据库中数据的汇总来对接离线数据分析,也用于离线数据分析的结果集存储来直接支持在线查询或者是数据派生。根据这样的定位,我们总结下对结构化大数据存储的几个关键需求。

关键需求

  • 大规模数据存储:结构化大数据存储的定位是集中式的存储,作为在线数据库的汇总(大宽表模式),或者是离线计算的输入和输出,必须要能支撑PB级规模数据存储。
  • 高吞吐写入能力:数据从在线存储到离线存储的转换,通常是通过ETL工具,T+1式的同步或者是实时同步。结构化大数据存储需要能支撑多个在线数据库内数据的导入,也要能承受大数据计算引擎的海量结果数据集导出。所以必须能支撑高吞吐的数据写入,通常会采用一个为写入而优化的存储引擎。
  • 丰富的数据查询能力:结构化大数据存储作为派生数据体系下的辅存储,需要为支撑高效在线查询做优化。常见的查询优化包括高速缓存、高并发低延迟的随机查询、复杂的任意字段条件组合查询以及数据检索。这些查询优化的技术手段就是缓存和索引,其中索引的支持是多元化的,面向不同的查询场景提供不同类型的索引。例如面向固定组合查询的基于B+tree的二级索引,面向地理位置查询的基于R-tree或BKD-tree的空间索引或者是面向多条件组合查询和全文检索的倒排索引。
  • 存储和计算成本分离:存储计算分离是目前一个比较热的架构实现,对于一般应用来说比较难体会到这个架构的优势。在云上的大数据系统下,存储计算分离才能完全发挥优势。存储计算分离在分布式架构中,最大的优势是能提供更灵活的存储和计算资源管理手段,大大提高了存储和计算的扩展性。对成本管理来说,只有基于存储计算分离架构实现的产品,才能做到存储和计算成本的分离。
  • 存储和计算成本的分离的优势,在大数据系统下会更加明显。举一个简单的例子,结构化大数据存储的存储量会随着数据的积累越来越大,但是数据写入量是相对平稳的。所以存储需要不断的扩大,但是为了支撑数据写入或临时的数据分析而所需的计算资源,则相对来说比较固定,是按需的。
  • 数据派生能力:一个完整的数据系统架构下,需要有多个存储组件并存。并且根据对查询和分析能力的不同要求,需要在数据派生体系下对辅存储进行动态扩展。所以对于结构化大数据存储来说,也需要有能扩展辅存储的派生能力,来扩展数据处理能力。而判断一个存储组件是否具备更好的数据派生能力,就看是否具备成熟的CDC技术。
  • 计算生态:数据的价值需要靠计算来挖掘,目前计算主要划为批量计算和流计算。对于结构化大数据存储的要求,一是需要能够对接主流的计算引擎,例如Spark、Flink等,作为输入或者是输出;二是需要有数据派生的能力,将自身数据转换为面向分析的列存格式存储至数据湖系统;三是自身提供交互式分析能力,更快挖掘数据价值。满足第一个条件是最基本要求,满足第二和第三个条件才是加分项。

开源产品

目前开源界比较知名的结构化大数据存储是HBase,Cassandra和Tablestore,Cassandra是WideColumn模型NoSQL类别下排名Top-1的产品,在国外应用比较广泛,在国内的话相比Cassandra会更流行一点,Tablestore是阿里云自研的结构化大数据存储产品。

posted @ 2019-09-04 09:27  Helios_Fz  阅读(2710)  评论(0编辑  收藏  举报