点击这里查看第一章:数据导论
点击这里查看第三章:Lambda架构:一种数据湖实现模式
第2章数据湖概念概览
数据湖概念的诞生,源自企业面临的一些挑战,如数据应该以何种方式处理和存储。最开始,企业对种类庞杂的应用程序的管理都经历了一个比较自然的演化周期。最开始的时候,每个应用程序会产生、存储大量数据,而这些数据并不能被其他应用程序使用,这种状况导致数据孤岛的产生。随后数据集市应运而生,应用程序产生的数据存储在一个集中式的数据仓库中,可根据需要导出相关数据传输给企业内需要该数据的部门或个人。然而数据集市只解决了部分问题。剩余问题,包括数据管理、数据所有权与访问控制等都亟须解决,因为企业寻求获得更高的使用有效数据的能力。为了解决前面提及的各种问题,企业有很强烈的诉求搭建自己的数据湖,数据湖不但能存储传统类型数据,也能存储任意其他类型数据,并且能在它们之上做进一步的处理与分析,产生最终输出供各类程序消费。在本章中,将介绍数据湖的一些主要方面,帮助读者理解为什么它对企业非常重要。
2.1 什么是数据湖
如果需要给数据湖下一个定义,可以定义为这样:数据湖是一个存储企业的各种各样原始数据的大型仓库,其中的数据可供存取、处理、分析及传输。
数据湖从企业的多个数据源获取原始数据,并且针对不同的目的,同一份原始数据还可能有多种满足特定内部模型格式的数据副本。因此,数据湖中被处理的数据可能是任意类型的信息,从结构化数据到完全非结构化数据。企业对数据湖寄予厚望,希望它能帮助用户快速获取有用信息,并能将这些信息用于数据分析和机器学习算法,以获得与企业运行相关的洞察力。
数据湖与企业的关系
数据湖能给企业带来多种能力,例如,能实现数据的集中式管理,在此之上,企业能挖掘出很多之前所不具备的能力。另外,数据湖结合先进的数据科学与机器学习技术,能帮助企业构建更多优化后的运营模型,也能为企业提供其他能力,如预测分析、推荐模型等,这些模型能刺激企业能力的后续增长。
企业数据中隐藏着多种能力,然而,在重要数据能够被具备商业数据洞察力的人使用之前,人们无法利用它们来改善企业的商业表现。
2.2 数据湖如何帮助企业
长期以来,企业一直试图找到一个统一的模型来表示企业中所有实体。这个任务有极大的挑战性,原因有很多,下面列举了其中的一部分:
- 一个实体在企业中可能有多种表示形式,因此可能不存在某个完备的模型来统一表示实体。
- 不同的企业应用程序可能会基于特定的商业目标来处理实体,这意味着处理实体时会采用或排斥某些企业流程。
- 不同应用程序可能会对每个实体采用不同的访问模式及存储结构。
这些问题已困扰企业多年,并阻碍了业务处理、服务定义及术语命名等事务的标准化。
从数据湖的角度来看,我们正在以另外一种方式来看待这个问题。使用数据湖,隐式实现了一个较好的统一数据模型,而不用担心对业务程序产生实质性影响。这些业务程序则是解决具体业务问题的“专家”。数据湖基于从实体所有者相关的所有系统中捕获的全量数据来尽可能“丰满”地表示实体。
因为在实体表示方面更优且更完备,数据湖确实给企业数据处理与管理带来了巨大的帮助,使得企业具备更多关于企业增长方面的洞察力,帮助企业达成其商业目标。值得一提的是,Martin Fowler写过一篇很有意思的文章,在这篇文章中,他对企业数据湖的一些关键方面做了简明扼要的阐述,可参考下面这个链接:https://martinfowler.com/bliki/DataLake.html。
数据湖的优点
企业会在其多个业务系统中产生海量数据,随着企业体量增大,企业也需要更智能地处理这些横跨多个系统的数据。
一种最基本的策略是采用一个单独的领域模型,它能精准地描述数据并能代表对总体业务最有价值的那部分数据。这些数据指的是前面提到的企业数据。
对企业数据进行了良好定义的企业当然也有一些管理数据的方法,因此企业数据定义的更改能保持一致性,企业内部也很清楚系统是如何共享这些信息的。
在这种案例中,系统被分为数据拥有者(data owner)及数据消费者(data consumer)。对于企业数据来说,需要有对应的拥有者,拥有者定义了数据如何被其他消费系统获取,消费系统扮演着消费者的角色。
一旦企业有了对数据和系统的明晰定义,就可以通过该机制利用大量的企业信息。该机制的一种常见实现策略是通过构建企业级数据湖来提供统一的企业数据模型,在该机制中,数据湖负责捕获数据、处理数据、分析数据,以及为消费者系统提供数据服务。数据湖能从以下方面帮助到企业:
- 实现数据治理(data governance)与数据世系。
- 通过应用机器学习与人工智能技术实现商业智能。
- 预测分析,如领域特定的推荐引擎。
- 信息追踪与一致性保障。
- 根据对历史的分析生成新的数据维度。
- 有一个集中式的能存储所有企业数据的数据中心,有利于实现一个针对数据传输优化的数据服务。
- 帮助组织或企业做出更多灵活的关于企业增长的决策。
在本节中,我们讨论数据湖应该具备哪些能力。本章后续部分将会讨论和评述数据湖是如何工作的,以及应该如何去理解其工作机制。
2.3 数据湖是如何工作的
为了准确理解数据湖能给企业带来哪些好处,理解数据湖的工作机制以及构建功能齐全的数据湖需要哪些组件就显得尤为重要了。在一头扎进数据湖架构细节之前,不妨先来了解数据湖背景中的数据生命周期。
在一个较高的层面来看,数据湖中数据生命周期如图2-1所示。
上述生命周期也可称为数据在数据湖中的多个不同阶段。每个阶段所需的数据和分析方法也有所不同。数据处理与分析既可按批量(batch)方式处理,也可以按近实时(near-real-time)方式处理。数据湖的实现需要同时支持这两种处理方式,因为不同的处理方式服务于不同的场景。处理方式(批处理或近实时处理)的选择也依赖数据处理或分析任务的计算量,因为很多复杂计算不可能在近实时处理模式中完成,而在一些案例中,则不能接受较长的处理周期。
同样,存储系统的选择还依赖于数据访问的要求。例如,如果希望存储数据时便于通过SQL查询访问数据,则选择的存储系统必须支持SQL接口。如果数据访问要求提供数据视图,则涉及将数据存储为对应的形式,即数据可以作为视图对外提供,并提供便捷的可管理性和可访问性。最近出现的一个日渐重要的趋势是通过服务(service)来提供数据,它涉及在轻量级服务层上对外公开数据。每个对外公开的服务必须准确地描述服务功能并对外提供数据。此模式还支持基于服务的数据集成,这样其他系统可以消费数据服务提供的数据。
图2-1 数据湖的生命周期
当数据从采集点流入数据湖时,它的元数据被捕获,并根据其生命周期中的数据敏感度从数据可追溯性、数据世系和数据安全等方面进行管理。
数据世系被定义为数据的生命周期,包括数据的起源以及数据是如何随时间移动的。它描述了数据在各种处理过程中发生了哪些变化,有助于提供数据分析流水线的可见性,并简化了错误溯源。
可追溯性是通过标识记录来验证数据项的历史、位置或应用的能力。
——*
2.4 数据湖与数据仓库的区别
很多时候,数据湖被认为与数据仓库是等同的。实际上数据湖与数据仓库代表着企业想达成的不同目标。表2-1中显示了两者的关键区别。
从表2-1来看,数据湖与数据仓库的差别很明显。然而,在企业中两者的作用是互补的,不应认为数据湖的出现是为了取代数据仓库,毕竟两者的作用是截然不同的。
2.5 数据湖的构建方法
不同的组织有不同的偏好,因此它们构建数据湖的方式也不一样。构建方法与业务、处理流程及现存系统等因素有关。
简单的数据湖实现几乎等价于定义一个中心数据源,所有的系统都可以使用这个中心数据源来满足所有的数据需求。虽然这种方法可能很简单,也很划算,但它可能不是一个非常实用的方法,原因如下:
- 只有当这些组织重新开始构建其信息系统时,这种方法才可行。
- 这种方法解决不了与现存系统相关的问题。
- 即使组织决定用这种方法构建数据湖,也缺乏明确的责任和关注点隔离(responsibility and separation of concerns)。
- 这样的系统通常尝试一次性完成所有的工作,但是最终会随着数据事务、分析和处理需求的增加而分崩离析。
更好的构建数据湖的策略是将企业及其信息系统作为一个整体来看待,对数据拥有关系进行分类,定义统一的企业模型。这种方法虽然可能存在流程相关的挑战,并且可能需要花费更多的精力来对系统元素进行定义,但是它仍然能够提供所需的灵活性、控制和清晰的数据定义以及企业中不同系统实体之间的关注点隔离。这样的数据湖也可以有独立的机制来捕获、处理、分析数据,并为消费者应用程序提供数据服务。
2.6 Lambda架构驱动的数据湖
正如我们在前面讨论的那样,有多种处理数据的方式,它们可以被大致地分为批处理和实时数据处理。虽然可能有这样的场景,只用其中一种处理方式就提供了所需的结果,但也有可能同时需要来自批处理和实时数据处理组件处理后产生的数据。这使我们遇到了将批处理结果与实时处理结果合并的问题。这个问题可由Lambda架构模式解决,细节将会在下一章中进行讨论。这里讨论的是最原始的由Lambda架构驱动的数据湖理念。
Lambda架构作为一种模式,提供了在大型数据集上执行高度可伸缩和高性能分布式计算的方法,并且最终为批处理和近实时处理提供了一致的数据。Lambda架构定义了能应对企业中各种数据负载的可水平扩展架构的实现方法与手段,并且具有较低的延迟预期。
图2-2显示了数据湖中的功能模块。
图2-2 数据湖中的功能模块
Lambda架构模式的实现方式是将整个架构划分为多个功能模块/层(layer)。每一层都将在本章的后续部分中进行简略介绍。
2.6.1 数据摄取层——摄取数据用于处理和存储
快速的数据摄取层(data ingestion layer)是Lambda架构模式中的关键层之一。这一层需要控制将数据快速传递到Lambda架构的工作模型中。该层的关键功能如下所列:
- 该层必须具有高度可扩展性,满足各种需求,能够根据不同的负载情况进行伸缩。
- 该层必须具有容错(fault tolerant)能力,提供系统可靠性和故障转移(fail-over)能力。
- 该层必须支持多线程及多事件处理。
- 该层必须能够快速地将所摄取数据的结构转换为目标数据格式,这是Lambda架构处理层所要求的。
- 该层必须确保所交付的所有数据都以最纯粹的形式供下一步处理。
2.6.2 批处理层——批量处理已提取数据
批处理层(batch layer)是Lambda架构中对已提取数据进行批量处理的层,以确保系统资源的最佳利用,同时也可将长时间运行的操作应用于数据,以确保输出数据的高质量。输出数据也称为模型数据(modeled data)。将原始数据转换为模型数据是批处理层的主要职责,其中,模型数据中蕴含了Lambda架构中服务层(serving layer)向外提供数据的数据模型。该层主要职责如下所列:
- 该层必须能在已摄取的原始数据之上执行数据清理、数据处理、数据建模算法。
- 该层必须提供重新执行(replay/rerun)某些操作的机制,以实现故障恢复。
- 该层必须支持在已摄取的原始数据之上执行机器学习算法或数据科学处理,以产生高质量的模型数据。
- 该层可能需要执行一些其他操作,以期通过移除重复数据、检测错误数据和提供数据世系视图来提高模型数据的整体质量。
2.6.3 快速处理层——近实时数据处理
快速处理层(speed layer)将对从数据摄取层接收的数据执行近实时处理。由于处理预期接近实时,因此这些数据的处理需要快速、高效,为高并发场景提供支持和相应的精心设计,并且最终产生满足一致性要求的输出结果。很多因素可以影响快速处理层的特性,这些将在本书的后面部分详细讨论。简单来说,该层应包含以下功能:
- 必须支持在特定数据流之上的快速操作。
- 必须能生成满足近实时处理需求的数据模型。所有需要长时间运行的处理必须被委托给批处理模式。
- 必须有快速访问能力和存储层的支持,这样就不会因为处理能力而导致事件的堆积。
- 必须与数据摄取层的批处理过程分离。
- 必须产生一个输出模型,该模型(从某种程度上来说)可以与批处理产生的数据集合并,进一步提供增强型的企业数据。
2.6.4 数据存储层——存储所有数据
在Lambda架构模式中,数据存储层(data storage layer)非常引人注目,因为该层定义了整个解决方案对传入事件/数据流的反应。由架构常识可知,一个系统的速度最多与处理链中最慢的子系统一样快,因此,如果存储层不够快,由近实时处理层执行的操作将会变得很慢,从而阻碍了该架构达到近实时的效果。
在Lambda的总体架构中,针对已摄取的数据有两种主动操作:批处理和近实时处理。批处理和近实时处理的数据需求差别很大。例如,在大多数情况下,批处理模式需要执行串行读和串行写操作,此时使用Hadoop存储层就足够了,但是如果我们考虑近实时处理,需要快速查找和快速写入,那么Hadoop存储层可能是不合适的(见表2-2)。为了支持近实时处理,需要数据层支持某些类型的索引数据存储。
表2-2 Hadoop存储层对批处理和近实时处理模式的适用情况
Lambda架构的典型功能如下所列:
- 同时支持串行读写及随机读写。
- 针对用户的使用情况,提供合适的层次性的解决方案。
- 支持以批量模式或近实时模式处理海量数据。
- 以灵活、可扩展的方式支持多种数据结构的存储。
2.6.5 服务层——数据交付与导出
Lambda架构也强调了为消费者程序提供数据传输服务的重要性。众所周知,数据可以以多种方式在系统间传递。其中最重要的一种方式是通过服务(service)传递。在数据湖背景中,这些服务被称为数据服务(data service),因为它们的主要功能是传输数据。
另外一种传输数据的方式是数据导出(export)。数据最终可导出为多种格式,如消息、文件、数据备份等,导出的数据供其他系统消费。
数据传输/服务主要关注的是如何将数据转换为预期的格式。这种格式可以强制约定为数据契约(data contract),数据服务在对外提供服务时遵循该约定。然而,在执行数据传输操作时,合并批量处理及近实时处理产生的数据非常重要,因为这两类数据中都可能包含与组织机构相关的关键信息。数据服务层必须保证数据与数据契约(与消费者程序约定)的一致性。
从较高的层次来看,数据服务层应满足下列特性:
- 支持多种机制为消费者程序提供数据服务。
- 每种支持数据服务的机制,必须与消费者程序的数据契约兼容。
- 支持批量处理及近实时处理数据视图的合并。
- 为消费者程序提供可扩展、快速响应的数据服务。
因为数据服务层的核心职责是向数据湖以外的消费者提供数据服务,出于增强数据表现的考虑,该层可能会选择性地进行数据合并。
以上是Lambda架构的主要功能模块,其他向Lambda架构灌入数据供其处理的功能模块,如数据获取层(data acquisition layer)、消息层(messaging layer)及数据摄取层(data ingestion layer)等将在本章后续小节中讨论。
2.6.6 数据获取层——从源系统获取数据
企业中数据格式多种多样,可大致分为结构化数据、半结构化数据和非结构化数据。
结构化数据的常见例子包括关系数据库、XML/JSON、系统间传递的消息等。企业也非常青睐半结构化数据,尤其是E-Mail、聊天记录、文档等。非结构化数据的典型例子包括图片、视频、原始文本、音频文件等。
对于这些类型的数据,部分数据可能无法对其定义模式(schema)。需要将数据转换为有意义的信息时,模式是非常重要的。为结构化数据定义模式的方法非常直接,但是无法为半结构化数据或非结构化数据定义模式。
数据获取层的一个关键作用是将数据转换为在数据湖中可进行后续处理的消息。因此数据获取层必须非常灵活,能适应多种数据模式。同时,它也必须支持快速的连接机制,无缝地推送所有转换过的数据消息到数据湖中去。
数据获取层在数据获取端由多路连接(multi-connector)组件构成,然后将数据推送到特定的目的地。在数据湖的例子中,目的地指的是消息层,如图2-3所示。
图2-3 数据获取组件
很多技术框架可以用于构建能支持多种源系统的低延迟的数据获取层。对于每种源系统类型,数据获取层的连接都需要根据所依赖的底层框架进行特殊配置。数据获取层会对已获取的数据做少量转换,其目的是最小化传输延迟。这里的数据转换指的是将已获取的数据转换为消息或事件,它们可以发送给消息层。
如果消息层无法到达(由于网络中断或消息层处于停机期间),则数据获取层还必须提供所需的安全性保障和故障恢复机制。
为了确保该层的安全性,它应该能够支持本地持久化的消息缓冲,这样,如果需要,并且当消息层再次可用时,消息可以从本地缓冲区中恢复。该模块还应该支持故障转移,如果其中一个数据获取进程失败,另一个进程将无缝接管,如图2-4所示。
图2-4 数据获取层组件设计
2.6.7 消息层——数据传输的保障
消息层其实就是数据湖架构里的消息中间件(Message Oriented Middleware,MOM),该层的主要作用是让数据湖各层组件之间解耦,同时保证消息传递的安全性。
为了确保消息能被正确传输到目的地,消息将会被持久化到某种存储设备中去。被选用的存储设备需要与消息处理需求匹配(结合消息大小及数量等因素)。更进一步来看,不论是读操作还是写操作,消息中间件都是按队列(queue)方式来处理的,队列天然适合处理串行存取,机械硬盘足以应付此类I/O操作。对于那些需要每秒处理百万级的消息的大型应用程序来说,SSD能提供更好的I/O性能。
消息层组件必须能对消息队列进行入队列和出队列操作,如图2-5所示。对于大多数消息处理框架来说,入队列和出队列操作对应的是消息发布与消息消费。每个消息处理框架都提供了一系列库函数,用于与消息队列的资源连接(如topic/queue)。
图2-5 消息队列
任意消息中间件都支持两类与队列通信的方式以及topic消息结构,如下所列:
- 队列通常用于点对点(point-to-point)通信,每个消息应该只被某个消费者消费一次。
- topic概念经常出现于发布/订阅机制中,在这里,一个消息被发布一次,但是被多个订阅者(消费者)消费。一条消息会被多次消费,但是每个消费者消费一次。在消息系统内部,topic基于队列来构建;消息引擎(message engine)对这些队列进行差异化管理,以实现一个发布/订阅机制。
队列与topic都可以根据需要配置为持久化或非持久化。出于保障数据发布安全的目的,强烈建议将队列配置为持久化,这样消息将不会丢失。
从较高的层次来看,消息中间件可以抽象为由消息代理(message broker)、消息存储、topic/queue等组件组成的框架或引擎。
图2-6中描述了消息中间件框架中的各种组件。请记住,图2-6给出的是一种较高层次的抽象,屏蔽了很多细节。这些组件稍后将在第7章中详细介绍。
图2-6 消息中间件框架
2.6.8 探索数据摄取层
数据摄取层负责消费消息层中的消息,对消息做适当的转换,从中提取所期望的信息,然后传输给Lambda层供其处理。数据摄取层的输出必须与期望的数据存储或处理格式一致。该层也必须保证消息以一致性的方式消费掉,即没有消息丢失并且每条消息至少被消费一次。
数据摄取层被期望能支持多个消费者/线程来并行消费消息。每个消费者必须是无状态的,并且能快速处理流式数据。从消息层导出的多个数据流中的数据会源源不断地涌入Lambda层。数据摄取层必须确保消息消费速度不低于消息生成速度,这样消息/事件处理就不会有延迟。较慢的处理速度会导致消息层中消息的堆积,会对系统处理消息/事件的近实时特性造成伤害。该层应支持快速消费策略,在必要时恢复因消息堆积而导致的系统故障。
因此,该层有一个隐含的要求,即这一层需要一直保持近实时性,具有最小延迟,这样消息层就不会堆积任何消息。为了保障近实时性,该层必须有能力持续地消费消息/事件,及对故障进行恢复。
消息消费者扮演了向Lambda层递送消息供其处理的关键角色,如图2-7所示,因此消息消费者的内部组件与数据获取层非常相似,差别在于消息消费者知道从消息层(源)获取的消息及发送至Lambda层(目的地)的消息的格式。消息的消费行为可能是以微批量(micro-batches)方式来处理,这样能实现资源的最优利用,使系统效率更高。
图2-7 消息消费者
消息消费者可能需要同时将输出流推送到Lambda层的批处理层及快速处理层。
2.6.9 探索Lambda层
前面提到过,Lambda层由两个模块组成:批处理层及近实时处理层(即快速处理层)。
1.批处理层
批处理是处理海量数据的最传统方法之一,处理任务通常是长时间执行的。随着近期的各种大数据技术的诞生,批处理越来越高效,极大地缩减了处理时间。
一般来说,批处理对要消费的数据及要产生的输出结果非常了解。较早的时候,批处理的处理颗粒度很大,可能会在一次执行中处理整个数据集,也会用到多线程技术,并且提供了特殊的机制用来处理失效场景,以及执行一些操作流程来维护生产环境中的批处理作业。
Hadoop,作为一种大数据技术,因为其能满足批处理的各种要求而成为首选框架,它支持构建高效可扩展的批处理任务,这是传统批处理技术所无法比拟的。Hadoop中有两大组件是执行批处理所需的,主要是并行处理及分布式存储组件。Hadoop批处理已经被证明性能远优于传统批处理,原因如下:
1)使用经过优化的MapReduce范式的处理流程,执行速度很快。
2)顺序存储(sequential storage)有利于快速地顺序读/写。
3)存储备份机制(replicated storage)保证了数据的高可用性。
4)批处理任务执行期优先处理由作业调度器(job scheduler)管理的离得较近的数据。
基于Hadoop的批处理,由于具备了上面所述的这些能力,相较于传统批处理技术有巨大的改进。这里的分布式数据存储及并行处理由底层的Hadoop框架处理,Mapper与Reducer任务更关注特定的数据处理。
MapReduce处理范式并不是什么新概念,相反,它从大型机时代就已经出现在各种应用中了。该范式基于数据划分与规则,最早源自传统的多线程模型。其主要机制是将批处理分割为多个子任务,然后对这些处理任务的结果进行合并,最终产生整体输出,如图2-8所示。这样的话,多个任务并行执行且相互独立,各自处理各自的数据块(partition)。这样处理确保数据至少被处理一次,子任务的处理结果会被合并,并且结果已经去重了。由于Hadoop框架的内置功能,批处理的执行已经被证明是高度优化过的了,这使得Hadoop能处理主流的批处理问题。有了Hadoop及MapReduce,从数据处理中推导出商业智能(business intelligence)成为可能,此外也可以集成更复杂的数据科学(data science)、机器学习(machine learning)方法,用于满足各种基于批处理的分析需求。然而这又会引发另外一个问题,我们如何满足实时数据处理的需求?
图2-8 MapReduce范式——批处理
有一种策略可以满足近实时数据处理的需求,那就是使用多种框架。设计这些框架就是为了解决近实时数据处理问题。Lambda架构提供了多种机制使得可以在快速处理层中使用这些框架。
早期人们尝试通过触发频繁的批处理操作来实现近实时处理,然而这种方式永远无法到达近实时处理的预期。
2.快速处理层
快速处理层在Lambda架构中扮演近实时处理层的角色,在这里,消息/数据被快速摄取和处理,然后保存到存储层。
快速处理层主要满足数据近实时可用的要求,架构需要确保数据处理、存储、读取能达到近实时的预期。
为了保证近实时性,数据处理层、存储层、服务层必须保持对等的处理速度,这样才不至于在某个环节卡住。
已经存在一些流式处理的技术,较早的如Flume,它可以与HDFS交互,部分解决了这个问题。然而,Flume处理的是日志类型的数据,这些日志没经过进一步处理就直接存储到HDFS里了。数据的最终处理是在批处理中进行的,因此它本质上不是近实时的。
读者不难理解,依赖Hadoop的批处理,很难达到近实时处理的预期,因此需要一些另外的框架用于实现近实时处理,这些框架构成了Lambda架构的快速处理层。
最开始,这些框架是孤立的,它们没有与Hadoop生态系统很好地集成;随着应用的普及及功能的完备,显然这些框架需要与Hadoop生态系统集成以达到简化数据操作与管理的目标。图2-9显示了准实时处理流水线(pipcline)。
![9.png]
(https://ucc.alicdn.com/pic/developer-ecology/66b380890d1f4f479df1cb6602f25d54.png)
图2-9 准实时处理流水线
这些框架的实现机制都与Hadoop类似,都遵循MapReduce范式。只不过它们在实现上针对近实时处理做了特殊优化。每个框架都有自己的流式数据处理及资源管理方式。它们中的大多数都构建在快速的内存消息传输功能之上,这是近实时处理中的一种有效的组件解耦方式,能将处理延迟时间降至最低。
实时处理通常依赖键/值(key/value)和索引类型的数据,因此需要一个强大的快速数据处理层,这样对键/值及索引类型数据的处理不至于对系统的实时性造成伤害。在这里,某些NoSQL技术扮演了重要的角色,在本章及后续章节中将会陆续介绍它们。
3.服务层
服务层在Lambda架构中扮演着向消费者提供数据的角色。服务层应支持各种数据传输协议。从消费者视角来看,这些协议可以分为数据推送和数据拉取两大类。
服务层必须能从数据湖的数据存储层消费数据,并且通过与消费者程序事先约定好的接口传输数据。
- 数据推送
任意向数据湖之外推送数据的机制被称为数据推送(data push)机制。有多种数据推送机制,下面列举了最常见的几种:
- 数据导出(data export):服务层必须提供数据导出所需的工具、控制及管理策略,为消费者应用程序导出与期望格式一致的数据。该层的部分功能与ETL类似,然而不同之处在于它主要是受消费者应用需求和使用方式驱动。在底层,可能是通过由服务层调度的批处理任务来对数据湖中的数据进行抽取、转换、加载等操作,最后将结果数据加载到目的地。服务层的此类功能可能使用了一些嵌入系统中的ETL工具来执行ETL处理。
- 数据发布(data publish):服务层也可以通过发布数据到消费者应用程序订阅的topic/queue的形式来向外推送数据。这种数据推送方式其实是点对点(point-to-point)的数据推送,遵循发布(publish)/订阅(subscribe)模型。因为这些向外推送的数据必须是可以发布的消息,因此消息越小越好,以便于提高系统性能。
- 数据拉取
任意支持数据消费者从数据湖向外拉取数据的机制被称为数据拉取(data pull)机制。下面我们来讨论几种最常见的数据拉取机制:
- 服务(service):数据传输最流行的机制之一是数据服务。这包括在数据湖上构建Web服务(REST / SOAP),这样可以通过服务将数据暴露给消费者应用程序。这对于通过HTTP传输的相对较少数据的消费行为来说,很容易满足其近实时要求。这也源于将数据作为服务的概念,在这里,所有数据在服务中已经准备好且为可用状态。服务请求和响应的定义必须简洁明了,以便于能保持足够的通用性以满足多个消费者的需求。这也隐式意味着必须对数据访问进行高度优化,以保证具有随机访问能力、秒级以内的响应时间及可对大数据集进行处理。这些服务更适用于只读数据服务,而不是可更新的数据服务。
- 数据视图(data view):数据湖也可能实现为基于数据视图的数据传输机制,各种应用程序可以连接到这些视图,然后拉取数据。这种服务数据的机制已经非常普遍,因为它结合了简单、易于维护和访问等优点。一旦数据通过数据视图对外公开,任何获得授权的消费者应用程序都可以通过标准驱动程序直接连接到这些数据视图,以及执行任何允许的数据处理。这些视图通常是物化视图(materialized view)以保障执行性能,并且隔离对性能有影响的查询,限定它们只能在特定的表上执行。然而,物化视图也需要进行刷新,可以以增量或彻底重建的方式进行,这个过程被称为刷新周期(refresh cycle)。如果要在一个刷新周期里彻底重建物化视图,则需要有对应的控制机制,以保障刷新周期中的操作对数据服务没有影响。传统的做法是使用同义词(synonym);在最近的一些技术中是通过数据集副本来实现同样的效果。
4.数据存储层
Lambda架构中的数据存储层必须提供灵活的访问机制,同时也应该对系统进行高度优化以满足批处理及近实时处理的需求。换句话说,存储层必须同时支持数据的顺序访问和随机访问。在典型的Lambda架构中,以下功能层级直接依赖数据存储层。
- 批处理层
从数据访问的角度来看,批处理过程需要对数据进行顺序访问,并且存储层应针对此类操作进行优化。Hadoop是一种按块(block)读取和写入数据的技术,每个块都包含了序列数据中的一部分。甚至Hadoop中的块级访问都是按顺序进行的,以确保任何批处理在磁盘上的操作速度都足够快,即使是在旋转式的机械磁盘(普通硬件)上。 - 快速处理层
快速处理层需要以近实时的方式对其收到的数据消息进行操作,因此它必须能随机访问存储系统快速检索所需的信息,以及将处理后的数据快速写入存储系统。 - 服务层
服务层执行多种操作,它们对磁盘的顺序和随机访问都有需要,这依赖数据传输本身的特性。例如,如果需要在大数据集上执行数据导出,服务层通常会触发一个批处理进程来导出所需数据,此时主要依赖顺序数据访问。如果数据传输以数据服务的形式进行,所需的磁盘访问必须支持随机数据访问,以确保数据服务的响应时间长度低于预期。图2-10给出了数据访问模式示意。
图2-10 数据访问模式
因此,从数据访问的角度来看,数据湖中的数据可分为两大类:非索引数据(non-indexed data)和-索引数据(indexed data)。
- 非索引数据:一般来说,原始数据进入数据湖中,会顺序、分块存储。这些数据块也构成了数据处理的单位。因为非索引数据是顺序存储的,因此它适用于批处理,并且输出数据也是顺序存储的。非索引数据是顺序数据,因此它对基于关键字的检索的支持非常有限(只有少量存储格式支持这种检索)。有些数据存储还支持某些级别的索引和分区(partitioning),以便能以最快速度定位到数据所在的位置。此类数据通常用于批处理,其目的是提高批处理的处理速度,将批处理进程迁移到数据附近,使得待处理数据的移动最小化,充分利用本地数据。这是Hadoop生态系统中MapReduce过程处理速度很快的关键原因之一。
- 索引数据:在维护数据湖中索引数据这个背景中,我们试图寻找能随机寻址和访问数据的解决方案。在支持随机数据的存储和访问模式方面,底层硬件扮演了一个至关重要的角色。正如前面内容曾经提到过的那样,SSD非常适合这种场景。但是SSD也有它本身的问题,如成本、故障频率、数据容量、耗电量等方面的问题,这些问题又常常迫使企业不得不考虑使用机械硬盘。在这种背景下,需要对期望达到的I/O速率进行权衡。同时,实施者也可以考虑分级存储,例如,将高I/O数据或事务数据索引存储在SSD中,其他数据存储在机械硬盘中。
现今几乎所有数据索引框架都同时支持SSD和机械硬盘。这里介绍几种该领域领先的数据索引框架,它们在大数据技术及Lambda架构这些背景中得到了广泛的应用,分别是Solr和Elastic(Elasticsearch)。这两个框架都基于Lucene引擎,Lucene是一种开源的全文索引引擎,Solr与Elastic的核心索引及检索能力均来自Lucene,它们也都各自实现了一些额外的索引及检索功能。这两个框架都能保证在海量数据集上亚秒级响应,适用于快速处理层的快速数据检索和持久化。Elastic与Solr都支持数据索引及快速检索。
- 基于存储的分类:当存储系统的差异更多的与访问模式相关时,数据存储可以根据存储机制来分类,如图2-11所示。
5.关系数据存储
此类数据存储系统是过去几十年最流行的,关系数据是结构化数据,代表了实体(entity)间的关系。关系数据存储(relational data store)系统多年之前就非常成熟了,在企业间被广泛使用。直到几年前,这些数据存储系统还用于构建每个企业的主存储层,几乎所有的企业数据都保存在关系数据存储系统中,因为它们提供了一种非常合理的组织和管理数据的方式。
6.分布式数据存储
虽然关系数据存储系统在处理关系数据库方面非常有效,但人们很快就意识到它们可能不适合处理其他类型数据的存储。其他类型的数据包括半结构化和非结构化数据。保持关系数据存储的可扩展性使之能适应海量数据的存储与访问涉及复杂的处理和实践。这些挑战已由最近出现的一系列的分布式数据存储(distributed data store)(以分布式文件系统方式实现)和NoSQL(Not only SQL)解决。Hadoop已经成为现今最流行的分布式文件系统,虽然已经有一些NoSQL数据存储存在了,它们中的每一种只解决了一类特定问题。所有NoSQL数据库在分布式数据管理实现上基于类似的理念,不过它们可以进一步分为以下几类,如图2-12所示。
图2-11 数据存储
图2-12 NoSQL数据存储分类
图2-12中显示的每一类都解决了特定的数据访问及管理问题。
例如,键/值存储最适合处理时钟或机器数据,而可访问性需求则可以通过基于key的访问来完成。同样地,列式存储(columnar store)提供了非规范化(denormalized)的存储机制,其中数据存储为列或列族,而不是行,列式存储适用于读操作为主的场景,预计将加大对写操作为主的场景的支持。文档存储(document store)主要适用于将整个文档按key存储的场景。这些文档通常是JSON格式的,这些存储系统也可以存储JSON文件,并提供了JSON友好的查询引擎对外提供查询服务。当需要海量数据集上实现亚秒级查询,且以查询操作为主时,索引存储(index store)是首选。
上面介绍的每种数据存储都有大量的相关出版物,因为它们都具有大量独有的特性,适用于企业中海量数据处理和管理的各种场景。就数据湖而言,我们将在后面的章节中挑选若干种数据存储系统来展示数据存储层的多个侧面。在第5章中将介绍HBase,在第10章中,将会介绍Elasticsearch如何作为NoSQL在数据湖中使用。
2.7 总结
在本章中,从较高的层次逐个介绍了数据湖及Lambda架构的组成部分,为本书后续章节的学习奠定了基础。之后将深入技术细节,介绍如何实现数据湖及Lambda架构。本章介绍了数据湖相关概念,以及某些关于数据获取层、消息层、数据摄取层以及Lambda架构层(快速处理层及批处理层)的高级概念。我们同时也在某种程度上讨论了数据存储及随机访问与随机访问之间的差异。