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

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介:

导读: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把这种理念走的更远,默认的配置选项就是无序执行的策略,只有在必要的时候才启用顺序执行读写语句。


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



0?wx_fmt=png


三、架构


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


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


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


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


0?wx_fmt=png


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


0?wx_fmt=png


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


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


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


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


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

避免的动态视图请求。


0?wx_fmt=png

3、批处理架构(Hadoop)


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


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


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


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


0?wx_fmt=png


4、lambda架构


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


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


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


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


0?wx_fmt=png


5、流式处理架构


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


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


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


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


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


0?wx_fmt=png


四、小结:


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


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


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


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


附(知识补充):


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

  • 支持追加数据(append)

  • 支持大规模顺序扫描

  • 不支持随机访问


0?wx_fmt=png
0?wx_fmt=png

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

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

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

  • 数据被组织成页;

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


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


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



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

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

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
相关文章
|
6天前
|
存储 缓存 API
探索后端技术:构建高效、可扩展的系统架构
在当今数字化时代,后端技术是构建任何成功应用程序的关键。它不仅涉及数据存储和处理,还包括确保系统的高效性、可靠性和可扩展性。本文将深入探讨后端开发的核心概念,包括数据库设计、服务器端编程、API 开发以及云服务等。我们将从基础开始,逐步深入到更高级的主题,如微服务架构和容器化技术。通过实际案例分析,本文旨在为读者提供一个全面的后端开发指南,帮助大家构建出既高效又具有高度可扩展性的系统架构。
|
9天前
|
存储 SQL 缓存
快手:从 Clickhouse 到 Apache Doris,实现湖仓分离向湖仓一体架构升级
快手 OLAP 系统为内外多个场景提供数据服务,每天承载近 10 亿的查询请求。原有湖仓分离架构,由离线数据湖和实时数仓组成,面临存储冗余、资源抢占、治理复杂、查询调优难等问题。通过引入 Apache Doris 湖仓一体能力,替换了 Clickhouse ,升级为湖仓一体架构,并结合 Doris 的物化视图改写能力和自动物化服务,实现高性能的数据查询以及灵活的数据治理。
快手:从 Clickhouse 到 Apache Doris,实现湖仓分离向湖仓一体架构升级
|
6天前
|
Kubernetes Cloud Native 持续交付
探索云原生架构:打造弹性可扩展的应用
【9月更文挑战第29天】在云计算的浪潮中,云原生架构成为企业追求高效、灵活和可靠服务的关键。本文将深入解析云原生的概念,探讨如何利用容器化、微服务和持续集成/持续部署(CI/CD)等技术构建现代化应用。我们将通过一个简易的代码示例,展示如何在Kubernetes集群上部署一个基于Node.js的应用,从而揭示云原生技术的强大能力和潜在价值。
19 6
|
23天前
|
Cloud Native Devops 持续交付
探索云原生架构:构建高效、灵活和可扩展的系统
本文将深入探讨云原生架构的核心概念、主要技术以及其带来的优势。我们将从云原生的定义开始,了解其设计理念和技术原则;接着分析容器化、微服务等关键技术在云原生中的应用;最后总结云原生架构如何助力企业实现数字化转型,提升业务敏捷性和创新能力。通过这篇文章,读者可以全面了解云原生架构的价值和应用前景。
|
23天前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
29 3
|
1月前
|
设计模式 存储 人工智能
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
77 3
|
2月前
|
存储 API 持续交付
探索微服务架构:构建灵活、可扩展的后端系统
【8月更文挑战第25天】 本文将引导您理解微服务架构的核心概念,探讨其对现代后端系统设计的影响。我们将从基础讲起,逐步深入到微服务的高级应用,旨在启发读者思考如何利用微服务原则优化后端开发实践。
42 4
|
2月前
|
消息中间件 负载均衡 持续交付
构建可扩展的微服务架构:从设计到实现
在微服务架构的世界里,设计和实现可扩展性是至关重要的。然而,开发者往往面临着如何在系统复杂性和性能之间取得平衡的问题。本文通过深入探讨微服务架构的关键设计原则和实践,展示了如何从初期设计到最终实现,构建一个既高效又可扩展的系统架构。
|
2月前
|
存储 SQL 分布式计算
MaxCompute 近实时增全量处理一体化新架构和使用场景介绍
本文主要介绍基于 MaxCompute 的离线近实时一体化新架构如何来支持这些综合的业务场景,提供基于Delta Table的近实时增全量一体的数据存储和计算解决方案。
|
2月前
|
存储 监控 安全
大数据架构设计原则:构建高效、可扩展与安全的数据生态系统
【8月更文挑战第23天】大数据架构设计是一个复杂而系统的工程,需要综合考虑业务需求、技术选型、安全合规等多个方面。遵循上述设计原则,可以帮助企业构建出既高效又安全的大数据生态系统,为业务创新和决策支持提供强有力的支撑。随着技术的不断发展和业务需求的不断变化,持续优化和调整大数据架构也将成为一项持续的工作。
下一篇
无影云桌面