5大架构:细数数据平台的组成与扩展

简介:

导读:One size does not fit all! 数据处理平台已不集中于传统关系型数据库,各种其他平台层出不穷,也各有其适用范围。


从哪些角度去理解各种数据处理平台的设计思想及发展演进呢?下面我们从几个角度讨论一下:


一、单机存储引擎设计(数据的位置)


从某种意义上说,当我们处理数据的时候,实际上是在管理数据的位置,管理数据在CPU的位置,数据相对其他数据的位置。CPU特别适合处理顺序性操作数据指令,这样他可以进行数据预取。但是随机读取操作使得预取功能几乎失效,好多预取到缓存、前端总线的数据都是无效的。


传统意义上说,磁盘的存取性能要弱于内存,但是要分随机存取及顺序存取不同的场景下讨论。在流式顺序处理场景,磁盘及SSD的读取速度已经超过内存随机读取速度。


我们如何尽量实现数据的顺序存取呢?让我们设计一个很简单的数据库开始,存取一个文件。


1、数据存储和更新


追加写可以让我们尽量保持顺序存储文件。但是当数据要进行更新的时候,有两种选择,一种是在数据原地进行更新操作,这样我们就有了随机IO操作。另一种是把更新都放到文件末尾,然后需要读取更新数据的时候进行替换。


2、数据读取


一下子读取整个文件,也是很耗费时间的事情,例如数据库中的全表扫描。当我们读取文件中某一个字段时候,我们需要索引。索引的方式有多种,我们可以用一种简单的固定数值大小的有序数组来做索引,数组里存的是当前数据在文件中的存储偏移量。还有其他索引技术,如hash索引,位图索引等。


索引相当于在数据之上又加了一层树状结构,可以迅速的读取数据。但是打破了我们前面讲的数据的追加写,这些数据都是根据索引随机写入的。在数据库上建立索引的时候都会遇到这个问题,在传统的机械式磁盘上,这个问题会造成1000倍的性能差异。


有三种方法可以解决上述问题:


1)把索引放到内存中,可以随机存储和读取,把数据顺序存储到硬盘上。MongoDB,Cassandra都是采取这种方式。这种方式有一个弊端是存储的数据量受限于内存的大小,数据量一大,索引也增大,数据就饱和了。


2)第二种方式是把大的索引结构,拆成很多小的索引来存储。在内存中批量进来的数据,当积累到一个预定的量,就排序然后顺序写到磁盘上,本身就是一个小的索引,数据存储完,最后加一块小的全局索引数据即可。这样读取数据的时候,要遍历一些小的索引,会有随机读取。本质是用部分小的随机读换取了整体的数据顺序存储。我们通过在内存中保存一个元索引或者Bloom filter来实现处理那些小索引的低延迟。


日志结构的归并树(log structed merge tree, 简称LSM tree)是一种典型的实现,有三个特征:

a)一组小的、不变的索引集。

b)只能追加写 ,合并重复的文件。

c)少量的内存索引消耗换来读取的性能提升。这是一种写优化索引结构。


HBase、Cassandra、Bigtable都是通过这种比较小的内存开销来实现读取和存储的平衡


3)列式存储或者面向列的存储(暴力方式)。

纯列式存储和谷歌bigtable那种列式存储还是有所不同的,大家最好分开来看,虽然占用了同一个名字。列式存储很好理解,就是把数据按照列顺序存储到文件中,读取的时候只读需要的列。列式存储需要保持每一列数据都有相同的顺序,即行N在每一列都有相同的偏移。这很重要,因为同一查询中可能要返回多个列的数据,同时可能我们要对多列直接进行连接。每一列保持同样的顺序我们可以用非常简单的循环实现上述操作,且都是高效的CPU和缓存操作。


列式存储的缺点是更新数据的时候需要更新每一个列文件中的相应数据,一个常用的方法就是类似LSM那种批量内存写的方式。


当查询只是返回某几列数据,列式存储可以大规模减少磁盘IO。除此之外,列式存储的数据往往属于同一类型,可以进行高效的压缩,一些低延迟,高压缩率的扫描宽度、位填充算法都试用。即使对于未压缩的数据流,同时可以进行针对其编码格式的预取。


列式存储尤其适用于大表扫描,求均值、最大最小值、分组等聚合查询场景。


列式存储天然的保持了一列中数据的顺序性,方便两列数据进行关联,而heap-file index结构关联时候,一份数据可以按顺序读取,则另一份数据就会有随机读取了。


典型优势总结:

  • 列式压缩,低IO

  • 列中每行数据保持顺序,可以按照行id进行关联合并

  • 压缩后的数据依然可以进行预取

  • 数据延迟序列化


上面讨论的数据顺序存取的几种方案,在很多数据处理平台的最优技术方案中大都有参考。


通过heap-file结构把索引存储在内存,是很多NoSQL数据库及一些关系型数据库的首选,例如Riak,CouchBase和MongoDB,模型简单并且运行良好。


要处理更大量的数据,LSM技术应用更为广泛,提供了同时满足高效存储和读取效率的基于磁盘的存取结构。HBase、Cassandra、RocksDB, LevelDB,甚至MongoDB最新版也支持这种技术。


列式存储在MPP数据库里面应用广泛,例如RedShift、Vertica及hadoop上的Parquet等。这种结构适合需要大表扫描的数据处理问题,数据聚合类操作(最大最小值)更是他的主战场。


Kafka 通过追加式的文件或者预定义的offset集来存储消息队列。你来消费消息,或者重新消费消息都是很高效的顺序IO操作。这和其他的消息中间件架构上有所不同,JMS和AMQP都需要上面提到过的额外的索引来管理选择器和session信息。他们最终性能表现像一个数据库而非文件。


为满足读和写不同业务场景的优化,以上这些技术多少都有某些方面的折中,或者把问题简化,或者需要硬件支持,作为一种拓展的方法。


二、分布式集群存储设计(并行化)


把数据放到分布式集群中运算,有两点最为重要:分区(partition)和副本(replication)。


分区又被称为sharding,在随机访问和暴力扫描任务下都表现不错。


通过hash函数把数据分布到多个机器上,很像单机上使用的hashtable,只不过这儿每一个数据桶都被放到了不同的机器上。


这样可以通过hash函数直接去存储数据的机器上把数据取出来,这种模式有很强的扩展性,也是唯一可以根据客户端请求数线性扩展的模式。请求会被独立分发到某一机器上单独处理。


我们通过分区可以实现批量任务的并行化,例如聚合函数或者更复杂的聚类或者其他机器学习算法,我们通过广播的方式在所有机器上使任务同时执行。我们还可以运行分治策略来使得高计算的任务在一个更短的时间内解决。


这种批处理系统在处理大型的计算问题时有不错的效果,但只能提供有限并发,,因为执行任务时会非常消耗集群的资源。


所以分区方式在两个极端情况非常简单:

  • 直接hash访问

  • 广播,然后分而治之。在这两种情况之间还有中间地带,那就是在NoSQL数据库中常用的二级索引技术。


二级索引是指不是构建在主键上的索引,意味着数据不会因为索引的值而进行分区。不能直接通过hash函数去路由到数据本身。我们必须把请求广播到所有节点上,这样会限制了并发性,每一个请求都会卷入所有的节点。


因此好多基于key-value的数据库拒绝引入二级索引,虽然它很有价值,例如Hbase和Voldemort。 也有些数据库系统包含它了,因为它有用,例如Cassandra、MongoDB、Riak等。重要的是我们要理解好他的效益及他对并发性所造成的影响。


解决上述并发性瓶颈的一个途径是数据副本,例如异步从数据库和Cassandra、MongoDB中的数据副本。


实际上副本数据可以是透明的(只是数据恢复时候使用)、只读的(增加读的并发性),可读写的(增加分区容错性)。这些选择都会对系统的一致性造成影响,这是CAP理论中的一个研究课题(也许CAP理论不像你想象中的那么简单)。


这些对一致性的折中,给我们带来一个值得思考的问题?一致性到底有什么用?


实现一致性的代价非常昂贵。在数据库中是用串行化来保证ACID的。他的基本保证是所有操作都是顺序排列的。这样实现起来的代价非常昂贵,所以好多关系型数据库也不把他当成默认选项。


所以说要想在包含分布式写操作的系统上实现强一致性,如同坠入深渊。(补充说明,Consistency, 在ACID和CAP中同时出现,但是意义不一样,我这儿说的是在CAP中的定义:所有的节点在同一时间看到的是同样的数据)


解决一致性问题的方案也很简单,避免他。假如不能避免它把他隔离到尽可能少的写入和尽可能少的机器上。


避免一致性问题其实很简单,尤其是你的数据是一串不再改变的事实描述。web日志就是一个很好的例子,不用担心一致性问题,因为日志存下来后就是不变的事实描述。


当然有些业务场景是必须要保证数据一致性的,例如银行转账时候。有些业务场景感觉上是必须保持一致性的,但实际上不是,例如标记一个交易是否有潜在的欺诈,我们可以先把它更新到一个新的字段里面,另外再用一条单独的记录数据去关联最开始的那个交易。


所以对一个数据平台来说有效的方式是去避免或者孤立需要一致性的请求,一种孤立的方法是采取单一写入者的策略,Datamic就是典型的例子。另一种物理隔离的方法就是去区分请求中可变和不可变的字段,分别查询。


Bloom/CALM把这种理念走的更远,默认的配置选项就是无序执行的策略,只有在必要的时候才启用顺序执行读写语句。


前面是我们必须考虑的一些点,现在思考如何把这些设计组装在一起做成一个数据处理平台?





三、架构


1、命令查询职责分离架构(CQRS)


最常用的架构就是用传统关系型数据库存取数据,上层承接各种应用。这种架构会遇到一些瓶颈,比如当数据吞吐量大到一定程度,就会遇到消息传递、负载均衡、扩容、并发性能降低等问题。为保持ACID特性,扩容问题尤其严峻。


一种解决方案是CQRS(Command Query Responsibility Segregation),命令查询职责分离)架构,该模式从业务上分离修改 (Command,增,删,改,会对系统状态进行修改)和查询(Query,查,不会对系统状态进行修改)的行为。从而使得逻辑更加清晰,便于对不同部分进行针对性的优化。


还有一种简单的方式是把读和写的请求进行分离,写数据侧进行写优化处理,类似于日志文件结构。读数据侧进行读优化处理。比较代表性的实现如Oracle的GoldenGate和MongoDB的Replica Sets .



还有一些数据库,采用增加一层引擎的方式来实现上述思想。Druid就是一个很典型的例子,他是一个开源的、分布式的、实时的、列式存储的分析引擎。列式存储特别适合需要加载大的数据块,且数据块分到多个文件中的场景。Druid把一些近线实时数据放到写优化的存储中,然后随着时间的推移逐步把这些数据迁移到读优化的存储中。当Druid接收到请求,会同时把请求转发给读、写优化的存储,然后把返回的查询结果根据时间标记进行排序反馈给用户。像Druid这 种类似的系统,通过一层抽象实现了CQRS的优点。




2、操作/分析桥(Operational/Analytic Bridge)架构


另一种相似的处理方式是操作/分析桥(Operational/Analytic Bridge),读和写优化视图被事件流所区分,数据流的状态是被永久保存的,所以异步视图可以通过后来的更新被重组或增强。


这样前端模块可以提供同步的读和写,这样可以简单高效的读取刚被写入的数据,或者保持复杂的ACID事物管理。


后端模块利用异步性、状态不变性、去扩展离线处理进程,具体方式可以采用副本、异化、或者完全使用不同的存储引擎。信息桥,连接前端与后端,允许上层应用使用访问数据处理平台的数据。


这种模试比较适合中级数量的部署,尤其是至少包含部分的、不可

避免的动态视图请求。



3、批处理架构(Hadoop)


如果我们的数据是一次写入,多次读,不在改变的场景,上面可以部署各种复杂的分析型应用。采取批处理模式的hadoop无疑是这种平台最广用和出色的代表了。


Hadoop平台提供快速的读写访问,廉价的存储,批处理流程,高吞吐信息流,和其他抽取、分析、处理数据的工具。


批处理平台可以主拉取或者推进来多种数据源的数据,存储进HDFS,后续可以处理成多种优化的数据格式。数据可以压缩,清洗结构化,聚合,处理为一种读优化的格式例如Parquet,或者直接加载到数据服务层或者数据集市。通过这些过程,数据可以被查询或者处理。


这种结构在大批量的、数据不再改变的场景表现良好,一般可以到100TB以上,这种结构的进化是缓慢的,数据处理速度一般也是以小时为单位的




4、lambda架构


有时候我们并不想等待小时后才得到结果,这是该架构的一个缺陷。一种解决方法就是加一个流处理层,就是常说的lambda架构。


lambda架构在批处理的架构上增加了一个流处理层,如同在一个拥挤城镇新建一条高架桥。流处理层可以用主流的Storm或者Samza实现。lambda架构的本质是可以快速的返回一个近似的结果,精确的结果在后续返回。


所以流处理旁路提供一个流处理窗口期内最好的结果,可以先被上层应用所使用,后续批处理流程计算出精确结果在覆盖掉前面的近似结果。这种架构是对精准度和反馈时间做了一个聪明的平衡,作为后续发展,Spark平台同时提供了批处理和流处理模块(虽然流处理实际上市用微型批处理来实现的)。这种架构也可以满足 100TB以上数据的处理。


这种架构的另一种代表叫kappa架构,但是本文作者没看中那种架构,觉得叫kappa属于吃饱了撑的。




5、流式处理架构


不像是批处理架构,把数据存储到HDFS上,然后在上面执行各种跑批任务。流处理架构把数据存储到可扩展的消息或者日志队列,例如kafka,这样数据就可以被实时的处理成三级视图、索引, 被数据服务层或者数据集市供上层应用使用。


这和去掉批处理层的lambda架构很相似,在消息层可以存储处理海量的数据,有足够强大的流处理引擎可以hold住这些数据处理进程。


流处理结构可以用来解决“应用集成”问题,这是个头疼复杂的问题,IT传统大佬:Oracle,Tibco,Informatica都曾经试图想解决,一些部分结果是有用的,但不是真的解决,始终在寻找一套真正可用的解决方案。


流式处理平台提供了一种解决该问题的可能性,他继承了O/A桥平台的优点:多样化的异步存储形式和重新计算视图的能力,把一致性请求给隔离。系统保存的数据是日志的话,很天然的拥有不变性。Kafka可以保存高容量和吞吐量的历史记录,意味着可以重新计算数据状态,而不是持续的设置检查点。


类似流处理架构的工具还有Goldengate,用来向大型数据仓库同步数据,不过他在数据副本层缺乏高吞吐量支持,在数据模型管理层过于复杂。




四、小结:


我们开始于数据的位置,用来读写数据的顺序地址,从而说明了我们用到组件对该问题的折衷。我们讨论了对一些组件的拓展,通过分区和副本构建分布式的数据处理平台。最后我们阐述了观点:尽量在数据处理平台中把一致性的请求隔离。


数据处理平台自身也是一个动态调整变化的平台,依据业务需求,会把写优化转为读优化,把强一致性依赖转为开放的流式、异步、不变的状态。


有些东西我们必须留在思想中,顺序的结构化模式是一种,时序、分布式、异步是另一种。


我们要坚信:经过认真的解决,这些问题都是可控的。


附(知识补充):


简单介绍一下heap-file结构(和链表结构很相似):

  • 支持追加数据(append)

  • 支持大规模顺序扫描

  • 不支持随机访问




下面是Heap file自有的一些特性:

  • 数据保存在二级存储体(disk)中:Heapfile主要被设计用来高效存储大数据量,数据量的大小只受存储体容量限制;

  • Heapfile可以跨越多个磁盘空间或机器:heapfile可以用大地址结构去标识多个磁盘,甚至于多个网络;

  • 数据被组织成页;

  • 页可以部分为空(并不要求每个page必须装满);


页面可以被分割在某个存储体的不同的物理区域,也可以分布在不同的存储体上,甚至是不同的网络节点中。我们可以简单假设每一个page都有一个唯一的地址标识符PageAddress,并且操作系统可以根据PageAddress为我们定位该Page。


一般情况下,使用page在其所在文件中的偏移量就可以表示了。



原文发布时间为:2015-09-13

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“BigDataDigest”微信公众号

相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
相关文章
|
9月前
|
存储 SQL 监控
数据中台架构解析:湖仓一体的实战设计
在数据量激增的数字化时代,企业面临数据分散、使用效率低等问题。数据中台作为统一管理与应用数据的核心平台,结合湖仓一体架构,打通数据壁垒,实现高效流转与分析。本文详解湖仓一体的设计与落地实践,助力企业构建统一、灵活的数据底座,驱动业务决策与创新。
|
11月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
10月前
|
存储 SQL 分布式计算
19章构建企业级大数据平台:从架构设计到数据治理的完整链路
开源社区: 贡献者路径:从提交Issue到成为Committer 会议演讲:通过DataWorks Summit提升影响力 标准制定: 白皮书撰写:通过DAMA数据治理框架认证 专利布局:通过架构设计专利构建技术壁垒
|
7月前
|
存储 分布式计算 资源调度
【赵渝强老师】阿里云大数据MaxCompute的体系架构
阿里云MaxCompute是快速、全托管的EB级数据仓库解决方案,适用于离线计算场景。它由计算与存储层、逻辑层、接入层和客户端四部分组成,支持多种计算任务的统一调度与管理。
595 1
|
9月前
|
消息中间件 分布式计算 大数据
“一上来就搞大数据架构?等等,你真想清楚了吗?”
“一上来就搞大数据架构?等等,你真想清楚了吗?”
165 1
|
8月前
|
SQL 存储 监控
流处理 or 批处理?大数据架构还需要流批一体吗?
简介:流处理与批处理曾是实时监控与深度分析的两大支柱,但二者在数据、代码与资源上的割裂,导致维护成本高、效率低。随着业务对数据实时性与深度分析的双重需求提升,传统架构难以为继,流批一体应运而生。它旨在通过逻辑、存储与资源的统一,实现一套系统、一套代码同时支持实时与离线处理,提升效率与一致性,成为未来大数据架构的发展方向。
|
10月前
|
架构师 Oracle 大数据
从大数据时代变迁到数据架构师的精通之路
无论从事何种职业,自学能力都显得尤为重要。为了不断提升自己,我们可以尝试建立一套个性化的知识目录或索引,通过它来发现自身的不足,并有针对性地进行学习。对于数据架构师而言,他们需要掌握的知识领域广泛而深入,不仅包括硬件、网络、安全等基础技术,还要了解应用层面,并熟练掌握至少一门编程语言。同时,深入理解数据库技术、具备大数据实操经验以及精通数据仓库建模和ELT技术也是必不可少的。只有这样,数据架构师才能具备足够的深度和广度,应对复杂的业务和技术挑战。 构建个人知识体系是数据架构师在学习和工作中的一项重要任务。通过系统化、不断深化的知识积累,数据架构师能够有效应对快速变化的商业环境和技术革新,进一
|
9月前
|
消息中间件 缓存 负载均衡
构建高效可扩展的后端架构:从设计到实现
本文探讨了如何构建高效、可扩展的后端架构,涵盖需求分析、系统设计、实现与优化全过程。内容包括微服务、数据库设计、缓存与消息队列等关键技术,并涉及API设计、自动化测试、CI/CD及性能优化策略,助力打造高性能、易维护的后端系统。
|
12月前
|
SQL 分布式数据库 Apache
网易游戏 x Apache Doris:湖仓一体架构演进之路
网易游戏 Apache Doris 集群超 20 个 ,总节点数百个,已对接内部 200+ 项目,日均查询量超过 1500 万,总存储数据量 PB 级别。
1029 3
网易游戏 x Apache Doris:湖仓一体架构演进之路
|
12月前
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。