



近年来,随着移动互联网和物联网的快速发展,数据存储系统面临着两大挑战:一是数据量呈指数级增长,规模达到EB级、数据访问频率达到亿级每秒;二是现代的业务负载动态变化,存储系统需要有极强的弹性伸缩能力和智能资源管理能力。为了满足大数据存储的业务需求,数据存储的机制经历了从传统的数据管理系统到以NoSQL为代表的结构性变革。尽管基本架构共享一些原则,但在实现层面差异很大,并非一致。
数据存储系统一般由以下子部分组成:一是数据采集与建模,该部分主要负责采集数据和进行数据清洗、转换和建模等工作;二是分布式文件系统和分布式数据库(包括传统关系型数据库和NoSQL数据库)、数据仓库,主要实现数据的存储;三是统一数据访问接口,该层旨在屏蔽不同数据库间的数据访问的接口差异。
本章主要围绕数据存储系统的架构展开介绍,首先介绍了数据建模,其次介绍了数据的物理存储方式,即分布式文件系统,主要包含分布式文件系统概述、两个经典的分布式文件系统GFS和HDFS、主流分布式文件系统对比,然后介绍了数据的逻辑存储部分,即NoSQL数据库,包含NoSQL数据库的定义及其适用场景和经典分类等,最后介绍了统一数据访问接口。
1.什么是数据建模
数据建模是对现实世界各类数据的抽象组织,确定数据库管辖的范围、数据的组织形式等,直至转化成现实的数据库。即数据建模是为整个或部分信息系统创建可视化表达形式的过程,用于传达数据点和结构之间的联系。数据建模的目的是说明系统中使用和存储的数据类型、数据类型之间的关系、数据的分组和组织方式及其格式和属性。
对于从需求到实际的数据库存储数据,数据建模的模型有三种不同的类型。首先,用于信息系统的数据模型作为一个概念数据模型,本质上是一组记录数据要求的最初的规范技术。将满足企业最初要求的数据模型转变为一个逻辑数据模型,该模型可以在数据库中的数据结构概念模型中实现。一个概念数据模型的实现可能需要多个逻辑数据模型。数据建模的最后一步是确定从逻辑数据模型转换到物理数据模型的过程中,对数据访问性能和存储的具体要求,然后按照具体要求进行物理数据模型的设计。数据建模定义的不只是数据元素,也包括它们的结构和它们之间的关系。
2.数据建模的意义
数据建模的意义在于全面优化的数据模型有助于创建简化的逻辑数据库,消除冗余数据、减少存储需求并实现高效检索。此外,数据建模可为数据管理系统提供至关重要的单一真实数据源,帮助系统实现高效运营,数据建模在大数据转型中起到了关键作用。数据建模可以记录这些设想,并为软件设计人员提供设计路线图。完整定义并记录数据库和数据流,并根据定义的规范完成系统开发后,系统应提供预期的功能,确保数据准确(假设完全按照该程序执行)。
例如在设计一个复杂的大型大数据软件项目时,其数据来源极其复杂,且在设计和构建任何软件项目之前,开发人员必须先创建文档,设想最终产品的结构和功能,其中的一个重要环节就是制定用于管理目标功能的业务规则。此外,描述数据也很重要,即描述用于支持目标功能的数据流(或数据模型)和数据库。数据建模也是用户主要的决策工具,即分析和可视化。随着数据和用户的数量不断增加,需要设法将原始数据转化为可指导行动的信息,为决策流程提供支持。因此,大数据时代对数据分析工具的需求大幅增长。而数据可视化工具能以图形的形式呈现数据,让数据对用户而言更易于理解。
总而言之,数据建模的意义在于可以将抽象的原始数据转换为有用的信息,继而通过数据建模软件将其转换为动态的可视化内容。通过对数据做如下处理,数据建模的基本流程能够为数据分析做好准备,比如清理数据、定义度量和维度、通过建立层次结构来增强数据、设置单位和货币以及添加公式。
3.数据建模的模型分类
数据模型的类型有很多,可能的布局类型也很多。在数据处理方面,有三种公认的建模模型,分别代表了模型开发时的思维抽象级别。
数据模型所描述的内容主要包括三个部分:数据结构、数据操作、数据约束。
数据结构:数据模型中的数据结构主要描述数据的类型、内容、性质以及数据间的联系等。数据结构是数据模型的基础,数据操作和约束都建立在数据结构上。不同的数据结构具有不同的操作和约束。
数据操作:数据模型中的数据操作主要描述相应的数据结构上的操作类型和操作方式。
数据约束:数据模型中的数据约束主要描述数据结构内数据间的语法、词义联系、它们之间的制约和依存关系,以及数据动态变化的规则,以保证数据正确、有效和相容。
数据模型按不同的应用层次分成三种类型,分别是概念数据模型、逻辑数据模型、物理数据模型。
(1)概念数据模型
概念数据模型(conceptual data model)简称概念模型,主要用来描述世界的概念化结构,它使数据库设计人员在设计的初始阶段摆脱计算机系统及数据库管理系统(DataBase Management System,DBMS)的具体技术问题,集中精力分析数据及数据之间的联系等。概念数据模型必须转换成逻辑数据模型,才能在DBMS中实现。概念数据模型是最终用户对数据存储的看法,反映了最终用户综合性的信息需求,它以数据类的方式描述企业级的数据需求,数据类代表了在业务环境中自然聚集的几个主要类别数据。
概念数据模型的内容包括重要的实体及实体之间的关系。在概念数据模型中不包括实体的属性,也不用定义实体的主键。这是概念数据模型和逻辑数据模型的主要区别。
概念数据模型的目标是统一业务概念,作为业务人员和技术人员之间沟通的桥梁,确定不同实体之间的最高层次的关系。在某些数据模型的设计过程中,概念数据模型和逻辑数据模型合在一起进行设计。
(2)逻辑数据模型
逻辑数据模型(logical data model)简称数据模型,是用户从数据库角度看到的模型,是具体的DBMS所支持的数据模型,如网状数据模型(network data model)、层次数据模型(hierarchical data model)等。该模型既要面向用户,又要面向系统,主要用于DBMS的实现。
逻辑数据模型反映了系统分析设计人员对数据存储的观点,是对概念数据模型进一步的分解和细化。逻辑数据模型是根据业务规则确定的,是关于业务对象、业务对象的数据项及业务对象之间关系的基本蓝图。逻辑数据模型的内容包括所有的实体和关系,需要确定每个实体的属性、定义每个实体的主键、指定实体的外键,对此进行范式化处理。
逻辑数据模型的目标是尽可能详细地描述数据,但并不考虑数据在物理上如何实现。逻辑数据建模不仅会影响数据库设计的方向,还间接影响最终数据库的性能和管理。如果在实现逻辑数据模型时投入得足够多,那么在物理数据模型设计时就有许多可供选择的方法。
(3)物理数据模型
物理数据模型(physical data model)简称物理模型,是面向计算机物理表示的模型,描述了数据在存储介质上的组织结构,它不但与具体的DBMS有关,而且还与操作系统和硬件有关。每一种逻辑数据模型在实现时都有对应的物理数据模型。DBMS为了保证其独立性与可移植性,大部分物理数据模型的实现工作由系统自动完成,而设计者只设计索引、聚集等特殊结构。
物理数据模型是在逻辑数据模型的基础上,考虑各种具体的技术实现因素,进行数据库体系结构设计,真正实现数据在数据库中的存放。物理数据模型的内容包括确定所有的表和列、定义外键用于确定表之间的关系、基于用户的需求可能进行反范式化等。在物理实现上的考虑,可能会导致物理数据模型和逻辑数据模型有较大的不同。
物理数据模型的目标是明确如何用数据库模式来实现逻辑数据模型以及存储数据。
总之,三级模型应该相互独立,即物理模型的改变(数据存储方式的改变、数据划分的调整等)不影响逻辑模型和概念模型的内容;逻辑模型的改变(数据表修改、属性的增减、值域的调整等)不影响概念模型的定义。
在数据建模的过程中,通常会对特定的业务模型进行分析与集成,首先对数据需求和业务过程模型进行综合考量,进行逻辑数据建模之后得到逻辑数据模型,再结合技术需求和性能需求得到物理数据模型,最后再将业务数据结合前面的数据模型存储到指定的媒介中。图4-1展示了整个业务模型的数据建模流程。
图4-1 数据建模的流程
数据建模大体可以分成三个阶段:概念建模、逻辑建模、物理建模。值得注意的是,概念建模和逻辑建模阶段不需要考虑任何具体的数据库,即与SQL、NoSQL等系列数据库不相关,只需要考虑实体的属性以及实体之间的联系即可。而物理建模则是在逻辑建模的基础上,与具体的数据库有着密切的联系。
数据建模中的主要活动包括以下几点:
确定数据及业务流程和需求。
定义数据(如数据类型、大小、值域等)。
确保数据的完整性。
定义操作过程。
选择数据存储技术(如关系、分层或索引存储技术等)。
下面详细介绍数据建模的过程和工具。
1.数据建模的过程
数据建模一般要经过概念建模、逻辑建模、物理建模三个阶段,前一阶段的成果是后一阶段的输入,每个阶段需要考虑的问题也不一样,如图4-2所示。
图4-2 数据建模的不同阶段
(1)概念建模
概念模型主要用于信息世界的建模,是现实世界到信息世界的第一层抽象。这种层次的模型将世界中的客观对象抽象为某一种信息结构,这种信息结构并不依赖于具体的计算机系统,不是某一个DBMS支持的数据模型。对概念模型的验证包括确保所用的理论和假设是正确的,当考虑模型的特征时,要确保所规划的用途合理。
概念建模主要做三件事情:
1)与客户交流;
2)理解客户需求;
3)将需求映射成实体。
以上三件事情并不能一次性完成,需要经过反复迭代。在概念建模阶段,需要尽量理解客户的需求,明确当前业务需要解决的问题、当前项目和软件需要完成的功能,有任何不明白或有歧义的地方都需要及时和客户交流,最后落实到实体中。但在现实生活中,用户可能不太清楚自己的需求,此时需要和用户先进行交流,将交流的结果转变为需求,之后再落实到实体中。需要记住的是,上述三件事情需要反复迭代,因为用户的需求有可能会发生变化。
在设计概念模型时,需要定义业务问题和解决这些问题所需的功能。最佳做法是与实际使用应用程序的人员交谈包括尽可能多的业务或用户方案,确定系统潜在用户的标识和数量,以及所涉及数据的大小和范围。虽然收集此信息可能是设计过程中最不技术的方面,但它是最重要的方面之一。若要设计良好的概念模型,应清楚地了解需要解决的业务问题和流程。
在概念建模阶段,只需要关注实体即可,不用关注任何实现细节。很多人都希望在这个阶段把具体表结构、索引、约束,甚至是存储过程都想好,这是比较困难的。因为这些东西是在物理建模阶段需要考虑的东西,这个时候考虑还为时尚早。
(2)逻辑建模
逻辑数据建模是在概念建模的基础上对实体进行细化,考虑将其细化成具体的表,同时丰富表结构。这个阶段的产物是可以在数据库中生成的具体表及其他数据库对象(包括主键、外键、属性列、索引、约束、视图以及存储过程)。在实际项目中,除了主键、外键之外,其他的数据库对象都可以在物理建模阶段建立,因为其他数据库对象需要结合开发一起进行。
逻辑数据建模的逻辑模型是利用实体及相互之间的关系,准确描述业务规则的实体关系图。逻辑模型要保证业务所需数据结构的正确性及一致性,使用一系列标准规则将对象的各种特征体现出来,并对各实体之间的关系进行准确定义。同时,逻辑模型也为构建物理模型提供了有力的参考依据,并支持转换为物理模型,是数据库设计过程中必不可少的一个阶段。也就是说,逻辑数据模型作为已用数据的蓝图,建立数据元素的结构及其之间的关系。它独立于详细说明数据将如何实现的物理数据库。逻辑数据模型为概念数据建模的元素添加了更多信息,其包含了在日常业务运行中所有至关重要的信息元素。
逻辑数据建模的注意事项如下:
不只针对当前业务现状,还要考虑业务将来的发展计划。
必须有熟知业务的人员参与建模,将实际业务所需内容充分反映在模型中。
确保设计的逻辑模型在向物理模型转换时具有较高的效率。
物理特性放在物理建模阶段考虑。
实体、属性、关系等必须与实际业务中的信息能够对应。
逻辑数据模型独立于任何物理数据存储设备,例如文件系统。
逻辑数据模型的设计必须独立于技术,以免受到技术快速变化的影响。
(3)物理建模
物理数据建模是指按照一定规则和方法,将逻辑模型中所定义的实体、属性、属性约束、关系等要素转换为数据库软件能够识别的表、关系图的一种物理描述。
物理数据建模的注意事项如下:
物理模型要确保业务需求及业务规则所要求的功能得到满足,性能得到保障。
物理模型要确保数据的一致性及数据的质量。
新业务或新功能增加时能够以较少的改动或不改动满足需求的扩展。
架构师可以将逻辑建模阶段创建的各种数据库对象生成为相应的SQL代码,通过运行来创建相应的具体数据库对象(大多数建模工具都可以自动生成DDL SQL代码)。但是这个阶段不仅能创建数据库对象,针对业务需求,也可能做数据拆分(水平或垂直拆分)。例如,在一个购物网站中,可以将商家和用户放在同一个表里,但出于性能考虑,可将其拆分成两个表,随着业务量的提升,事务表越来越大,系统性能逐渐变慢,这个时候便可以考虑数据拆分或读写分离等。
2.如何选择数据建模工具
所有的数据建模工具不仅仅局限于特定物理模型的特定软件产品和服务,因此在选择建模工具时,可以考虑业务需求和现有基础结构的产品,即结合现实和需求,参考以下几个指标。
(1)数据建模工具是否直观
实现模型的技术人员或许能够用任何工具完成工作,但如果工具不易于使用,那么业务人员和用户以及整个业务就无法充分利用工具的价值。
(2)数据建模工具运行状况如何
另一个重要属性是性能,即速度和效率,它体现了在用户运行分析时保持业务顺畅开展的能力。实际情况中可能涉及业务增长和数据量增加、检索和分析,如果经过出色规划的数据模型无法在这些条件下正常工作,那么该模型就称不上表现出色。
(3)数据建模工具是否需要维护
如果每次对业务模型进行更改都需要对数据模型进行烦琐的更改,那么业务将无法充分利用模型或关联的分析。通过使用相应的数据建模工具,数据维护和更新工作变得轻松,业务可以根据需要进行数据透视,同时仍然能够访问最新数据。
(4)数据是否安全
政府法规要求对客户数据进行保护,但业务的可行性要求对所有数据进行保护,因为这些数据是宝贵的资产。需要确保选择的工具具有强大的内置安全措施,包括控制授予需要该工具的用户访问权限,以及阻止不需要该工具的用户访问。
随着移动互联网、互联网、云计算等技术的快速发展,全球数据量呈现指数级增长,目前规模已经到达了EB级。传统的数据存储系统无法满足爆炸式增长的海量数据存储需求,尤其是对非结构化数据的存储。为了解决信息存储容量、数据备份、数据安全等问题,分布式文件系统应运而生,如今得到广泛应用。
本节将阐述分布式文件系统的概念和发展历程,并结合在大数据分析中分布式文件系统的应用情况,对几种典型的分布式文件系统的概念、特点、架构进行介绍,最后将它与相关文件系统进行比较。
1.传统文件系统
文件系统按照计算环境和提供功能的不同,一般可以划分为几个层次:
单处理器单用户的本地文件系统,如DOS文件系统。
多处理器单用户的本地文件系统,如OS/2文件系统。
多处理器多用户的本地文件系统,如UNIX、Linux本地文件系统。
多处理器多用户的分布式文件系统,如NFS、Lustre、GFS等文件系统。
前三者都可以归类为传统文件系统,在传统的文件系统中,所有数据和元数据存储在一起,通过单一的存储服务器提供。这种模式有一个不可避免的问题,就是随着客户端数目的增加,服务器就成了整个系统的瓶颈,如图4-3所示。因为系统所有的数据传输和元数据处理都要通过服务器,单个服务器不仅处理能力有限,存储能力受到磁盘容量的限制,吞吐能力也受到磁盘I/O和网络I/O的限制。在当今对数据吞吐量要求越来越大的大数据应用中,传统的文件系统很难满足应用的需要。
图4-3 传统模式数据存储原理
传统文件系统只能访问与主机通过I/O总线直接相连的磁盘上的数据。当局域网出现后,各台主机间通过网络实现互联。如果每台主机上都保存一份大家都需要的文件,既浪费存储资源,又不容易保持文件数据的一致性。于是就提出了文件共享的需求,即一台主机需要访问其他主机的磁盘,这直接导致了分布式文件系统的诞生。
2.分布式文件系统的定义
分布式文件系统(Distributed File System,DFS)中的文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连。分布式文件系统基于客户端/服务器(C/S)模式而设计,通常一个网络内可能包括多个可供用户访问以存储资源的服务器。同时,分布式文件系统的对等性也允许一些系统在扮演客户端的同时扮演服务端。例如,用户可以发布一个允许其他客户端访问的目录,一旦被访问,这个目录对于其他客户端来说就像使用本地驱动器一样。
3.分布式文件系统的发展历程
在信息增长爆炸的时代,通过指定的文件访问接口在不同主机之间共享文件数据的需求日益增强,不同的需求也促使着分布式文件系统不断进化。最初的分布式文件系统应用出现在20世纪70年代,之后便拓展到各种应用领域,尤其是互联网、金融领域。从早期的NFS到现在的云文件系统,分布式文件系统在体系架构、系统规模、性能和可拓展性等方面经历了巨大变化。
(1)萌芽与初步探索阶段(1970-1990年)
分布式文件系统的概念出现于20世纪70年代,随着计算机网络的初步构建与扩展,其需求逐渐显现。此阶段,分布式文件系统主要聚焦于提高以标准化接口实现远程文件访问的效率和数据可靠性。此阶段的代表性成果包括NFS(Network File System)和AFS(Andrew File System)。
NFS,即网络文件系统,自1985年问世以来,凭借跨平台兼容性,成为分布式文件系统的标杆。NFS是由SUN公司研制的UNIX表示层协议,允许网络中的计算机通过TCP/IP网络共享资源,使得本地客户端可像访问本地文件一样,透明地读写远端服务器上的文件。
而AFS,即安德鲁文件系统,由卡内基·梅隆大学开发,特别强调在不安全网络环境下的安全访问与系统的可扩展性。在安全性方面,AFS要求用户验证身份,并读取相应的访问控制列表(ACL),以确定其是否有权读写某个文件。AFS具有良好的可扩展性,能够轻松支持成千上百个节点,应对相当多的读请求。尤其是当读比写更频繁时,它能够减少与服务器的交流,降低网络延时影响,提高响应效率。另外,当远程文件无法访问时,AFS可利用本地存储作为分布式文件的缓存,以确保大规模分布式文件系统的可用性。
在这个阶段,分布式文件系统经历了从无到有、逐步发展的过程。从远程文件访问的基本功能,到关注访问性能和数据可靠性,分布式文件系统的功能和技术不断得到完善。
(2)技术深化与广域网应用阶段(1990-1995年)
在20世纪90年代初,随着广域网(WAN)技术的成熟与大规模存储需求的增长,分布式文件系统面临着新的挑战与机遇。此阶段,分布式文件系统逐渐突破了局域网的限制,致力于解决广域网环境下的缓存优化、数据传输效率及系统架构创新等问题。此阶段的代表性成果包括XFS(eXtended File System)、Tiger Shark、Frangipani和SFS(Slice File System)等。
Tiger Shark是一个可扩展的并行文件系统,旨在支持实时多媒体应用等大型应用程序,采用先进策略(资源预留、加大数据块、分片存储等)以确保数据传输的实时性与稳定性。它支持连续时序数据,还提供了可扩展性、高可用性。比如,它通过数据复制机制,提高系统可用性。
Frangipani是一个分布式文件系统,它提供递增可扩展、高可用、自动管理的虚拟磁盘。它将多台机器的磁盘作为共享的存储池来管理,且使用分布式锁来确保一致性。与集中式网络文件服务器相比,它将文件系统负载进行分割,并转移到使用文件的机器上,提供了更好的负载平衡。
(3)性能与容量追求阶段(1995-2000年)
在这一阶段,随着存储成本的下降、网络技术的发展,以及存储系统瓶颈的凸显,分布式文件系统需进一步优化物理设备访问、磁盘布局与检索效率,以及元数据管理。此时期,分布式文件系统在设计上更加注重性能与容量的双重提升,出现了多种新型架构与优化策略。如GPFS(General Parallel File System),即通用并行文件系统,由IBM等业界巨头联合开发,适用于高性能计算与大规模数据存储场景。
(4)现代化与多元化发展阶段(2000年至今)
数据量的爆炸性增长,以及云计算、互联网、物联网的飞速发展,要求分布式文件系统能够存储海量数据、具备弹性扩展能力、能够提供可靠而高效的数据存取服务等,这进一步推动了分布式文件系统的发展。在这一时期,人们开始探索分布式文件系统架构和技术的新发展,多个创新型成果涌现,如分布式文件系统与其他技术的融合等。这一时期的分布式文件系统,其性能与可靠性进一步提升,应用场景也随之拓展,且更加标准化与开放化。尤其是,分布式文件系统的开源社区在这一时期也得到了快速发展。开源社区为用户提供了更多的选择和定制化的可能性,同时也促进了技术的交流和共享。这一时期的代表性成果包括Google的GFS(Google File System)、IBM推出的StorageTank等。这一时期的分布式文件系统具有以下特点。
1)新型文件系统涌现:这些系统不仅提供了高效的数据存储和访问能力,还针对特定的应用场景进行了优化。
2)技术融合与集成:如与分布式计算框架(如MapReduce)的集成,使得数据处理能力得到了显著提升。
3)性能与可靠性提升:通过优化数据布局、提高I/O性能等技术手段,实现了对大规模数据集的高效访问。通过数据复制、节点故障检测与恢复等技术手段,确保了数据的可靠性和可用性。
4)应用场景拓展:在大数据处理、云计算、虚拟化存储等领域有了更广泛的应用。
5)标准化与开放化:标准与规范统一,技术之间共享与交流。
4.分布式文件系统的优点
与传统文件系统相比,分布式文件系统具有如下优点:
方便数据管理。分布式文件系统在设计时就考虑了数据的管理,特别是海量数据的管理,通过使用虚拟化技术,可以方便地完成数据的备份以及迁移等操作。
可扩展性高,支持线性扩容。当存储空间不足时,可以采用热插拔的方式增加存储设备,方便扩展。
可靠性强。分布式文件系统包含冗余机制,能够自动对数据实行备份,在数据发生损坏或丢失的情况下,可以迅速恢复。
可用性好。用户只需要拥有网络就可以随时随地访问数据,不受设备、地点的限制。
作为互联网技术的先驱,谷歌率先遇到了大数据(即大规模的搜索索引)的问题。2003年,谷歌发表了GFS(Google File System)论文,向业界介绍了其分布式文件系统设计方案,GFS具有可伸缩、高可用、高可靠性,并按层级目录来组织文件。
1.GFS的设计思想
GFS与过去的分布式文件系统有很多共同目标,但GFS的设计受到了当前及预期的应用工作负载及技术环境的驱动,显然与早期的文件系统有不同的设想。这就需要重新检验传统的选择并探索完全不同的设计观点。
GFS和以往分布式文件系统的不同点如下:
硬件错误不再被当作异常,而是将其作为常见的情况加以处理。因为文件系统由成百上千个用于存储的机器构成,而这些机器是由廉价的普通硬件组成,并被大量的客户端访问。硬件的数量和质量导致一些机器随时都有可能无法工作并且有一部分还可能无法恢复。所以实时监控、错误检测、容错、自动恢复对系统来说必不可少。
按照传统的标准,文件都非常大,长度达几个GB的文件是很常见的,每个文件通常包含很多应用对象。当经常处理快速增长、包含数以万计的对象、长度达TB的数据集时,管理成千上万的KB规模的文件块变得困难,即使底层文件系统提供支持。因此,设计中操作的参数、块的大小必须重新考虑。系统不仅要对大型文件做到高效管理,对小型文件也必须支持,但不必优化。
大部分文件的更新是通过添加新数据完成的,而不是覆写已存在的数据。在一个文件中随机写的操作几乎不存在。数据一旦写入,文件就只可读。很多数据都有以下特性,有些数据可能组成一个大仓库以供数据分析程序扫描;有些数据是运行中的程序连续产生的数据流;有些是档案数据;有些是在某个机器上产生、在另外一个机器上处理的中间数据。由于对大型文件的访问方式,添加写操作成为性能优化和原子性保证的焦点,而在客户端中缓存数据块则失去了吸引力。
2.GFS的体系结构
整个GFS系统包括几个角色:多个GFS客户端(GFS client)、一个GFS主服务器(GFS master server)、0个或多个GFS影子主服务器(GFS shadow master server)和多个GFS数据块服务器(GFS chunk server)。
GFS客户端:通过GFS提供的客户端库使用GFS提供的功能。客户端是给应用使用的API,这些API与POSIX API类似。GFS客户端缓存从GFS主服务器读取的数据块信息(即元数据),尽量减少与GFS主服务器的交互。
GFS主服务器:主服务器存放了整个GFS系统的元数据(命名空间、权限控制、文件/数据库/副本之间的映射)。对元数据进行修改前,要先写操作日志,只有在写日志成功后才能对元数据进行修改。操作日志保存在磁盘上,且在多个机器上保存多份。为了避免操作日志变得太大,每隔一段时间,GFS就创建一个检查点(checkpoint)。检查点被组织成一棵紧凑的树(类似于B树的形式)存储在磁盘上,便于快速加载到内容中使用。GFS系统重启或恢复时,仅需要加载最新的检查点,然后再重放操作日志即可。
GFS影子主服务器:影子主服务器对外提供“只读”服务,其中保存的元数据不保证是最新的,与主服务器上保存的元数据相比可能会有一点滞后(通常不到1秒)。因此,在主服务器重启期间,那些接收非最新数据的应用可以通过影子服务器继续使用GFS。
GFS数据块服务器:数据块的实际存储者,它和主服务器通过心跳信号联系,并告诉主服务器它上面保存的文件块信息,主服务器据此维护其保存的元数据。
每个GFS文件都被分成固定大小的数据块(64 MB)。数据块以文件的形式被保存在运行Linux的GFS数据块服务器上。为了增强可靠性,每个数据块被保存在多个数据块服务器上(默认为3个)。GFS主服务器通过周期性的心跳信号监控数据块服务器的状态。
3.GFS的容错和诊断
GFS为了实现高可靠性的需求,通常采用如下策略:
快速恢复。不管如何终止服务,主服务器和数据块服务器都会在几秒钟内恢复状态和运行。实际上,GFS不对正常终止和不正常终止进行区分,服务器进程都会被切断而终止。客户端和其他服务器经历一个小小的中断后,它们的特定请求超时,然后重新连接重启的服务器,重新请求。
数据块备份。每个数据块都会被备份到位于不同机架上的不同服务器上。对不同的名字空间,用户可以设置不同的备份级别。在数据块服务器掉线或是数据被破坏时,主服务器会按照需要来复制数据块。
主服务器备份。为确保可靠性,主服务器的状态、操作记录和检查点都在多台机器上进行了备份。一个操作只有在数据块服务器硬盘上更新并被记录在主服务器和其备份上才算成功。如果主服务器或是硬盘故障,系统监视器会发现并通过改变域名启动它的一个备份机,而客户端则仅仅通过使用规范的名称来访问,并不会发现主服务器的改变。
而GFS的数据完整性,则是指每个数据块服务器都利用校验和来检验存储数据的完整性。因为每个服务器随时都有可能发生崩溃,并且在两个服务器间比较数据块也是不现实的,同时,在两个服务器间拷贝数据并不能保证数据的一致性。在空闲时间,服务器会检查不活跃数据块的校验和,这样可以检查出不经常读的数据的错误。一旦错误被检查出来,服务器会拷贝一个正确的数据块来代替它。
Hadoop分布式文件系统(Hadoop Distributed File System,HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统,它以分布式进行存储,主要负责集群数据的存储与读取。HDFS采用主/从(Master/Slave)结构,从某个角度看,它和传统的文件系统一样。HDFS支持传统的层次型文件组织结构,用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似,可以通过文件路径对文件执行创建、读取、更新和删除操作。但是由于分布式存储的性质,它又和传统的文件系统有明显的区别。
HDFS是一个具有高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合应用于大规模数据集上。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的,它是Apache Hadoop的核心组件之一。值得注意的是,HDFS是GFS的第一个开源实现版本,HDFS与GFS的架构基本一致,但术语不同。
1.HDFS的设计思想
硬件错误是常态而不是异常。HDFS可能由成百上千的服务器构成,每个服务器上存储着文件系统的部分数据。面对的现实是构成系统的组件数目是巨大的,而且任一组件都有可能失效,这意味着总是有一部分HDFS的组件是不工作的。因此错误检测和快速、自动恢复是HDFS最核心的架构目标。
流式数据访问。运行在HDFS上的应用和普通的应用不同,需要流式访问它们的数据集。HDFS的设计中更多地考虑到了数据批处理,而不是用户交互处理。相较于数据访问的低延迟问题,更关键的在于数据访问的高吞吐量。POSIX标准设置的很多硬性约束对HDFS应用系统不是必需的。为了提高数据的吞吐量,在一些关键方面对POSIX的语义做了一些修改。
使用大规模数据集。运行在HDFS上的应用具有很大的数据集,HDFS上的一个典型文件大小一般都在G字节至T字节。因此,HDFS被调节以支持大文件存储。它应该能提供整体上高的数据传输带宽,能在一个集群里扩展到数百个节点。一个单一的HDFS实例应该能支撑数以千万计的文件。
简单的一致性模型。HDFS应用需要一个“一次写入多次读取”的文件访问模型。一个文件经过创建、写入和关闭之后就不需要改变。这一假设简化了数据一致性问题,并且使高吞吐量的数据访问成为可能。Map/Reduce应用或者网络爬虫应用都非常适合这个模型。目前计划扩充这个模型,使之支持文件的附加写操作。
移动计算比移动数据更划算。一个应用请求的计算,离它操作的数据越近就越高效,在数据达到海量级别时更是如此。因为这样就能降低网络阻塞的影响,提高系统数据的吞吐量。将计算移动到数据附近,相较于将数据移动到应用所在位置显然更好。HDFS为应用提供了将它们自己移动到数据附近的接口。
2.HDFS的体系结构
从图4-4中可以看出,HDFS由一个名称节点(NameNode)、一个第二名称节点(Secondary NameNode)、若干数据节点(DataNode)和客户端(Client)组成,采用主/从结构,存储的基本单位是块。打个比方,如果把HDFS比作一本书,名称节点存储的是书的目录,数据节点存储的则是书的正文内容,一章是一个文件,一节是一个块,目录称为元数据,目录指明的各章节页码称为映射,用户访问数据,首先要访问名称节点。在此介绍几个HDFS的重要概念。
图4-4 HDFS体系结构
块是HDFS的基本操作单位,HDFS把一个文件被分成多个块,以块作为存储单位,默认一个块为64MB~128MB,这里和GFS非常像。这是因为HDFS采用抽象的块概念可以带来以下几个明显的好处:支持大规模文件存储、简化系统设计、适合数据备份。
名称节点为“主”节点,存储元数据(文件、块与数据节点之间的映射),元数据保存在内存中。名称节点由FsImage、EditLog两个文件组成,具体信息如图4-5所示。FsImage保存文件、块的目录结构;EditLog保存对文件、块的操作,如创建、删除等。在名称节点统一调度下进行数据块的创建、删除和复制等操作。
图4-5 名称节点结构
数据节点是“从”节点,存储文件内容,其数据主要保存在磁盘中,维护块ID(Block ID)到数据节点本地文件的映射关系,向名称节点定期发送自己所存储的块的列表(心跳),且向第二名称节点进行冷备份。
HDFS中,第二名称节点扮演着重要的辅助角色,用于帮助名称节点合并EditLog日志和FsImage文件,生成新的FsImage文件,以减少主名称节点的启动时间和内存消耗。第二名称节点定期从名称节点复制当前的FsImage和EditLog,合并它们,并创建一个新的包含最新元数据的FsImage文件。它在一定程度上也是名称节点的备份。
3.HDFS的存储原理
HDFS文件系统在设计之初就充分考虑到了容错问题,会将同一个数据块对应的数据副本(副本个数可设置,默认为3)存放在多个不同的数据节点上。某个数据节点宕机后,HDFS会从备份的节点上读取数据,这种容错性机制能够确保即使节点故障而数据不会丢失。
数据存放有几个策略。在第一个副本存放策略中,如果保存请求来自集群内部,第一个副本存放在发起者(应用)所在的节点,如图4-6所示,一个在DataNode1上的应用发起保存数据请求,那它的第一个副本也存放在DataNode1;如果保存请求来自集群外部,HDFS会随机挑选一个磁盘不太忙且CPU不太忙的节点来存放第一个副本。在第二个副本存放策略中,第二个副本放在和第一个副本不同机架的节点上,如存放在图4-6中的DataNode4上,它和DataNode1在不同机架上。其余的存放策略则是放在和第一个副本相同的机架的其他节点,如图4-6中的DataNode2或DataNode3。
图4-6 数据存放策略
在数据读取过程中,HDFS提供了一个API,可以确定一个数据节点所属的机架ID,客户端也可以调用API获取自己所属的机架ID。当客户端读取数据时,从名称节点获得数据块不同副本的存放位置列表,列表中包含了副本所在的数据节点,可以调用API来确定客户端和这些数据节点所属的机架ID。当发现某个数据块副本对应的机架ID和客户端对应的机架ID相同时,就优先选择该副本读取数据,如果没有发现,就随机选择一个副本读取数据。
图4-7中给出了HDFS读取文件的大致流程。客户端调用文件系统对象使用open()方法,获取一个分布式文件系统实例。将读取文件的请求发送给NameNode,然后NameNode返回文件数据块所在的DataNode列表(是按照客户端距离DataNode网络拓扑的远近进行排序的),同时也会返回一个文件系统数据输入流(FSDataInputStream)对象。客户端调用read()方法,会找出最近的DataNode并连接;数据从DataNode源源不断地流向客户端。
图4-7 HDFS文件读取过程
HDFS写入文件的过程如图4-8所示。客户端通过调用分布式文件系统的create()方法创建新文件,将文件写入请求发送给NameNode,此时NameNode会做各种校验,比如文件是否存在、客户端有无权限去创建等,如果校验不通过则会抛出I/O异常。如果校验通过,NameNode会将该操作写入编辑日志中,并返回一个可写入的DataNode列表,同时,也会返回文件系统数据输出流(FSDataOutputStream)对象。客户端在收到可写入列表之后,会调用write()方法将文件切分为固定大小的数据块,并排成数据队列;数据队列中的数据块会写入第一个DataNode,然后第一个DataNode会将数据块发送给第二个DataNode,以此类推。DataNode收到数据后会返回确认信息,等收到所有DataNode的确认信息之后,写入操作完成。
图4-8 HDFS文件写入过程
4.HDFS的容错与数据恢复
HDFS具有较高的容错性,可以兼容廉价的硬件,它把硬件出错看作一种常态,而不是异常,并设计了相应的机制来检测数据错误并进行自动恢复。出错主要包括以下几种情形:名称节点出错、数据节点出错和数据出错。
名称节点出错。名称节点保存了所有的元数据信息,其中,最核心的两大数据结构是FsImage和EditLog,如果这两个文件发生损坏,那么整个HDFS实例将失效。因此,HDFS设置了备份机制,把这些核心文件同步复制到备份服务器Secondary NameNode上。当名称节点出错时,就可以根据备份服务器SecondaryNameNode中的FsImage和EditLog数据进行恢复。
数据节点出错。每个数据节点会定期向名称节点发送“心跳”信息,向名称节点报告自己的状态。当数据节点发生故障或者网络发生断网时,名称节点无法收到来自一些数据节点的心跳信息,这时,这些数据节点就会被标记为“宕机”,节点上面的所有数据都会被标记为“不可读”,名称节点不会再给它们发送任何I/O请求。
数据出错。网络传输和磁盘错误等因素,都会造成数据错误。客户端在读取到数据后,会采用md5和sha1对数据块进行校验,以确定读取到正确的数据。在文件被创建时,客户端会对每一个文件块进行信息摘录,并把这些信息写入同一个路径的隐藏文件里面。当客户端读取文件的时候,会先读取该信息文件,然后,利用该信息文件对每个读取的数据块进行校验,如果校验出错,客户端就会请求到另外一个数据节点读取该文件块,并且向名称节点报告这个文件块有错误,名称节点会定期检查并且重新复制读块。
在本小节将会对几个经典的分布式文件系统做一些简单的对比。
目前已经有很多种分布式文件系统,判断一个分布式文件系统是否优秀,可以参考以下几点因素:
1)持久化存储:对用户而言是否透明,是否能够像使用本地文件系统那样直接使用它。
2)响应效率:从接收到用户的请求开始,到向用户反馈结果,系统所用的时长。包括解析请求、定位操作对应的节点、执行操作流程、节点间数据传输等流程。
3)可扩展性:当数据压力逐渐增长时,系统能否顺利、高效地扩容。
4)数据安全:系统是否具备可靠的安全机制,来保证数据安全。如,采用冗余备份、镜像等方式,保证即便发生了节点故障,也能够进行数据恢复。
5)数据一致性:同一数据的各数据副本之间是否一致,只要数据内容不变化,能否保证任意时间的读取都能读到一样的内容。
目前市面上主流的分布式文件系统有:GFS、HDFS、Ceph、Lustre、MogileFS、FastDFS、TFS等,接下来将对这些文件系统做简单的介绍并用表进行对比。
GFS是谷歌公司开发的一款基于Linux的、高性能、高可用性和可扩展的分布式文件系统,它采用分布式架构和冗余备份策略来提供可靠的存储服务,并广泛应用于谷歌的各种大数据应用场景中。
HDFS是Hadoop生态系统的核心组件之一,作为最底层的分布式存储服务存在。它继承了GFS的核心设计理念和架构,同时根据Hadoop生态系统的需求进行了优化和改进。
Ceph由Sage Weil发表,并将之贡献给了开源社区。Ceph是一个去中心化的分布式存储系统,提供高性能、可靠性和可扩展性,并支持多种存储类型和接口。
Lustre文件系统是一个基于对象存储的分布式文件系统,也是一个开源项目。该项目于1999年在卡内基·梅隆大学启动,现在已经发展成为应用最广泛的分布式文件系统。Lustre已经运行在当今世界上最快的集群系统中,如Bule Gene和Red StorM等计算机系统,用来进行核武器相关的模拟以及分子动力学模拟等。
Lustre文件系统是一个高度模块化的系统,主要由三部分组成:客户端(Client)、对象存储服务器(Object Storage Target,OST)和元数据服务器(Meta Data Server,MDS)。这三个组成部分除了各自的独特功能外,相互之间共享诸如锁、请求处理和消息传递等模块。为了提高Lustre文件系统的性能,通常Client、OST和MDS是分离的。当然,这些子系统也可以运行在同一个系统中。
MogileFS由LiveJournal旗下的Danga Interactive公司开发,目前国内使用MogileFS的有图片托管网站yupoo等。MogileFS是一套高效的文件自动备份组件,支持多节点冗余、自动文件复制、名称空间的使用、不共享磁盘等特性。MogileFS适用于存储海量小文件,它不支持文件随机读写,更适合于文件写入后基本上不需要修改的应用。
FastDFS是一款类似于Google FS的开源的、轻量级的分布式文件系统。FastDFS是为互联网应用量身定做的,非常适合存储用户图片、视频、文档等文件,不适合分布式计算场景。
GlusterFS最早由Gluster公司开发,其目标是为客户提供全局命名空间、分布式前端及高达数百PB级的扩展性。GlusterFS没有元数据服务器的设计,使得整个服务没有单点故障的隐患。它可以将多台异构服务器的存储空间整合,提供统一命名空间。适用于数据密集型任务的可扩展网络文件系统,具有可扩展性、高性能、高可用性等特点。
TFS(Taobao File System)是阿里巴巴集团开发的,专为高可用性、高性能及低成本存储而设计。它主要针对海量的非结构化数据,构筑在普通的Linux机器集群上,可为外部提供高可靠和高并发的存储访问。
表4-1汇总了对上述文件系统的对比,但由于GFS是Google公司开发且并未开源,很多特性不可知,所以就不将其加入对比。
表4-1 分布式文件系统的综合对比
移动互联网、物联网、云计算等技术的快速发展,EB级大规模数据对数据存储提出了新的需求,主要有以下几点:
低延迟读写速度。
能够支撑海量数据和流量。
大规模集群管理,可以便捷部署分布式应用。
降低庞大运营成本,例如硬件成本、软件成本。
数据库技术从20世纪60年代末开始,经历了层次数据库、网状数据库和关系数据库而进入数据库管理系统(DBMS)阶段,直至今日,数据库技术的研究也在不断取得进展。传统的关系型数据库虽然在数据存储方面占据了很大比例,可随着数据规模的增长,数据也变得多种多样,传统的关系型数据库变得无法满足大规模数据存储的需求,原因有如下几点:
数据库扩展困难。
数据库读写速度慢,随着数据量增加和业务逻辑复杂度提高,读写速度下滑。
存储容量有限,关系型数据库难以存储海量数据。
业界为了解决大规模数据存储的困难,推出了多款新型的数据库,由于其设计和传统的关系型数据库有很大不同,故被统称为NoSQL数据库。需要注意的是,NoSQL仅仅是一个概念,NoSQL通常被解释为non-relational或Not Only SQL,泛指非关系型数据库,区别于关系型数据库,它们不保证关系型数据的ACID特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
本节主要围绕NoSQL的定义、类型和适用场景等展开相关讨论。
1.NoSQL定义
NoSQL数据库,是指运用非关系型的方法解决传统数据库无法解决的问题,而并非要取代现在广泛应用的传统关系型数据。
NoSQL遵守CAP原则和BASE思想,CAP原则指的是在分布式系统中,只可以同时满足一致性(Consistency)、可用性(Availability)、区分容错性(Partition tolerance)中的两种要求,不能三种兼顾。因此,不同的NoSQL数据库会根据自身的开发目的选择满足哪些要求,比如MongoDB满足CP要求,见图4-9。BASE是基本可用(Basically Available)、软状态(Soft state)、最终一致性(Eventually consistent)三个术语英文首字母的缩写。基本可用性是指在分布式系统出现故障时,允许系统部分失去可用性,保证核心部分的可用性;软状态是指允许系统不同节点同步有延时;最终一致性是指系统所有数据最后能达到一致的状态。大部分NoSQL数据库都遵循BASE思想,舍去高一致性以得到可用性和可靠性。
在CAP原则中需要注意的是,CAP中的C和A与SQL数据库的ACID属性中的C和A是不一样的。前者的C表示一致性,是指数据在不同副本之间的一致性,而后者则表示数据库内容处于一致的状态,例如表之间的主键和外键的一致性。前者的A表示系统的可用性,后者则是指事务的原子性。
图4-9 CAP原则
2.NoSQL特性
对于NoSQL并没有一个明确的范围和定义,但是它们都普遍存在以下共同特性:
不需要预定义模式。数据中的每条记录都可能有不同的属性和格式。当插入数据时,并不需要预先定义它们的模式。
无共享架构。共享架构将所有数据存储到远端服务器,通过网络进行访问,而NoSQL往往将数据划分后存储在各个本地服务器上。因为从本地磁盘读取数据的性能往往好于通过网络传输读取数据的性能,从而提高了系统的性能。
弹性可扩展。可以在系统运行的时候,动态增加或者删除节点。不需要停机维护,数据可以自动迁移。
分区。相对于将数据存放于同一个节点,NoSQL数据库需要将数据进行分区,将记录分散在多个节点上面,并且通常在分区的同时还要进行复制。这样既提高了并行性能,又能保证没有单点失效的问题。
异步复制。和共享架构存储系统不同的是,NoSQL中的复制往往是基于日志的异步复制。这样,数据就可以尽快地写入一个节点,而不会因网络传输而延迟。缺点是并不总能保证一致性,在出现故障的时候,该方式可能会丢失少量的数据。
NoSQL数据库虽然数量众多,但归结起来,典型的NoSQL数据库通常包括键值数据库、列族数据库、文档数据库和图数据库。
1.键值数据库
键值数据库是一种非关系型数据库,如图4-10所示,它使用简单的键值对方法来存储数据。键值数据库将数据存储为键值对集合,其中键作为数据唯一标识符。键和值都可以是从简单对象到复杂复合对象的任何内容。
Redis是典型的键值数据库,键类型是字符串,值类型是字符串、字符串集合(Set)、有序集合(Sorted Set)、字符串列表(List)、哈希(Hash)等。其中,Hash类型是一种字符串为键、字符串为值的键值对集合,类似键值类型都为字符串的Map。
图4-10 键值数据库的键值对
键值数据库采用高效的存储结构,能够灵活处理不断增长且结构多样化的大规模数据。与块存储系统不同,键值数据库以细粒度的键值对(而非固定大小的数据块)存储数据,这种设计显著提升了查询响应速度。键值数据库将数据存储为小型独立对象,使其易于配置和管理。由于采用无模式(schema-less)设计,同一数据库中的记录可以包含不同结构或格式的值,从而提供更高的灵活性。此外,键值存储通常占用更少的内存,并能高效扩展以支持海量记录的写入和读取。
键值数据库特别适合基于主键(key)的快速查询,但如果需要基于多个属性(特征)进行复杂查询,它可能不是最佳选择,因为它通常不支持多条件检索或复杂索引。典型的键值数据库应用场景包括在线游戏(如玩家数据缓存)、电子商务(如购物车管理)以及其他需要高速访问大量小型记录的互联网应用。关于键值数据库的特性总结参考表4-2。
表4-2 键值数据库的特性总结
2.列族数据库
列族(column-family)数据库通常用来应对分布式存储的海量数据。其中,“键”仍然存在,但是“键”可以指向多个列。列族数据库支持定义多个列族,每个列族内允许定义可变数量的列,支持动态定义新列。通常将逻辑上相关、经常同时访问的数据放在一个列族内,具体可以参考图4-11。和关系数据模型相比,可以把列族看成关系模型的一个列,列对应的值是一个复杂结构。
图4-11 列族数据库的形式
列族数据库适用于垂直分区、连续存储、压缩存储系统。列族数据库将数据的列分开存储,而不像传统存储那样将数据以完整记录的形式存储。此类系统中的数据读取和属性检索非常快且成本相对较低,因为仅访问相关列并为每个列执行并发进程。列族数据库具有高度可扩展性和最终一致性,为可靠且高度可用的存储应用程序提供支持。列族数据库的应用领域包含客户记录分析、数据仓库、患者数据管理、图书馆系统,以及任何需要分析以聚合相似数据项的地方。此外,使用面向列的结构,可以方便地在所有行中添加新功能。例如,某在线购物网站可以对特定时间段内最常浏览或订购的商品、网购的流行类别等进行聚合。关于列族数据库的特性总结参考表4-3。
表4-3 列族数据库的特性总结
3.文档数据库
文档数据库不同于关系型数据库,关系型数据库是高度结构化的,而文档数据库允许创建许多不同类型的非结构化的或任意格式的字段,且不提供对参数完整性和分布事务的支持。但它和关系型数据库也不是相互排斥的,它们之间可以相互交换数据,从而相互补充、扩展。
文档数据模型类似于键值对结构,以键和值的形式存储数据并作为对文档的引用,如图4-12所示。但是,文档数据库支持更复杂的查询和层次关系。这种数据模型通常实现JSON格式并提供非常灵活的模式。尽管结构化数据的存储架构是无模式的,但索引在文档数据库中得到了很好定义。文档数据库的应用领域包括社交网络上的用户配置文件、网站分析和复杂的交易数据应用程序。例如,在社交平台上,用户可能会在其个人资料中提供较少或较多的信息,每个用户配置文件都将存储为一个文档。面向文档的数据存储模型提供的启发式模式的性能取决于用户输入和查询的性质。关于文档数据库的特性总结参考表4-4。
图4-12 文档数据库的索引关系
表4-4 文档数据库特性总结
4.图数据库
图结构的数据库同其他NoSQL和SQL数据库不同,它使用灵活的图模型,并且能够扩展到多个服务器上。图数据库支持非常灵活的实体关系,实体称为节点,实体间的关系称为边。在图数据库中,边是内嵌的概念,其中边和节点可以参考图4-13。
图数据库是存储数据和关系的最佳选择,它提供对象和关系的持久存储,并使用自己的语法支持简单易懂的查询。现代企业有望为其复杂的业务流程和互联数据实施图数据库,因为这种关系数据结构提供了轻松的数据遍历。高频交易系统和推荐系统更喜欢用图数据库来实现低延迟。例如,在商业网站上从客户反馈数据中获取推荐,需要对传统数据库进行自连接、多级查询,这是一个非常复杂的操作,相比之下,对于图数据库,这种数据操作非常简单,只需两行代码,而不会影响数据的结构。关于图数据库的特性总结参考表4-5。
图4-13 图数据库的边和节点
表4-5 图数据库特性总结
关系型数据库(SQL数据库),是创建在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。在这样的系统中,信息遵循一种利用表或关系的结构化方法。随着大数据时代的到来,结构化方法已经无法满足巨大的信息处理需求,这些信息往往是非结构化的。随着时间的推移,SQL数据库经历了许多迭代,以支持大量的数据处理。然而,对于期望快速响应和最高可扩展性的大数据系统来说,它仍然是低效的。
一种被称为NoSQL的新方法被引入,是为了解决前者带来的限制。NoSQL系统在处理非结构化数据或处理大数据应用时能够快速扩展。NoSQL数据库使用键值对、文档、图结构或没有典型模式的列族存储数据。它还可以横向扩展,而不是像关系型数据库那样难以纵向扩展。NoSQL展示了成为大数据应用的理想数据库系统的巨大前景,但是它也有一些缺点。NewSQL应运而生,它是数据库系统世界中的最新发展。
NewSQL是新一代兼具可扩展性与高性能的关系型数据库的统称。这类数据库在完整保留传统数据库ACID事务特性和SQL兼容性的前提下,通过分布式架构实现了对海量数据的高效存储与线性扩展能力。典型的NewSQL数据库代表有Google Spanner、CockroachDB、TiDB等。SQL、NoSQL和NewSQL三者的对比可以参考表4-6。
表4-6 SQL、NoSQL和NewSQL三者对比
该节围绕NoSQL数据库进行说明,并对每种类型的NoSQL数据库进行简短介绍,说明各种类型数据库的适用场景及特性。但在数据存储系统中,各类数据库的访问接口不一致,数据接口访问复杂度高,为了统一不同数据接口的访问标准,便需要引入统一数据访问接口的概念,这也是在下一节中进行讨论。
大数据的出现给信息技术领域带来了新的挑战,因其数据量巨大、增长速度快、数据类型多样,关系型数据库已经很难满足大数据存储的需求。非关系型数据库因其具有高效的读写性能及良好的可扩展性,数据存储模式更为灵活等特点,非常适合大数据的存储。在构建大数据存储与分析平台应用系统中,多种非关系型数据库并存的架构能够充分发挥各存储系统的优势,但是不同的非关系型数据库数据模型不同,数据访问方式也不一致,构建多源异构的大数据存储系统因而变得十分复杂。另外,非关系型数据库在使用中存在性能上的问题,在高负载数据传输的环境下阻塞式的通信模式会引起数据库性能的降低。
为了解决应用程序对不同数据库的访问和数据交换问题,一种流行的方式就是使用数据库接口,数据库接口就是业务程序与数据库进行通信的技术。目前在市面上最流行的两种数据库接口是ODBC(Open DataBase Connectivity)和JDBC(Java DataBase Connectivity)。
微软于1991年提出ODBC,并在1992年发布首个可用版本。作为早期整合异构数据库的标准化接口,ODBC基于X/Open和ISO/IEC 9075-3:1995(SQL/CLI)的调用级接口(Call-Level Interface,CLI)标准,使用SQL作为统一的数据库访问语言。
ODBC的核心是一组标准化的API函数,应用程序通过调用这些函数执行SQL语句,而无须直接与底层数据库管理系统交互。其架构采用分层设计:
应用程序通过ODBC API发送SQL请求。
驱动程序管理器负责加载合适的ODBC驱动程序。
驱动程序将ODBC调用转换为特定DBMS支持的指令。
数据源(如MySQL、Oracle等)最终处理请求并返回结果。
ODBC的关键特性有以下几点:
数据库无关性:应用程序只需使用标准ODBC接口,不需要针对不同DBMS修改代码。
驱动透明性:类似打印机驱动模型,用户通过统一接口访问不同数据库。
广泛兼容性:支持关系型和非关系型数据库,成为跨平台数据访问的事实标准。
而JDBC是Java语言中规范应用程序如何访问数据库的应用程序接口,提供了诸如查询、更新的方法。在项目实际开发过程,有的直接采用JDBC技术进行数据库持久化操作,有的采用目前很好用的ORM框架来进行数据库持久化操作。但是为了方便使用接口,且为了能具备事务管理、异构数据库转换等复杂功能,需要一个抽象层用于屏蔽不同数据库之间的差异。这就引入了数据访问层。
对数据访问层的介绍,先从三层架构讲起。通常把应用系统划分为:表现层、业务逻辑层和数据库访问层。这样的设计是为了实现“高内聚,低耦合”的设计思想。数据库访问层在三层架构中只负责数据存储与读取。业务逻辑层作为数据库访问层的上层,内部调用数据库访问层提供的方法,来完成数据的存储与读取。也就是说,抽取数据库访问层的主要作用是进行隔离,把与数据库打交道的事情都放在数据访问层解决,在其他层则只要调用数据访问层就可以了,不必和具体的ORM层相耦合。
接下来详细介绍数据访问层。它又称为持久层,其功能主要是负责数据库的访问。简单地说就是实现对数据表的Select(查询)、Insert(插入)、Update(更新)、Delete(删除)等操作。如果要加入ORM的思想,就会包括对象和数据表之间的映射,以及对象实体的持久化操作。它能够将应用程序中的数据持久化到存储介质中,通常使用的数据库都是关系型数据库,采用的数据模型都是对象模型,这就需要数据库访问层实现对象模型与关系模型直接的、互相的转换。
数据库访问层与底层数据库应该是独立的,好的数据库访问层方案是能够在不修改程序代码功能的基础之上实现不同类型数据库的动态切换。比较熟悉的做法就是通过XML配置文件来完成底层数据库的切换。目前很多流行的数据库访问层框架都是采用这种方式来实现数据库的动态切换。
常见的数据访问层的实现有:数据存取对象(Data Access Object,DAO)、基于对象/关系映射(Object/Relation Mapping,ORM)的实现、服务数据对象(service data object)、服务中间件(service middleware)。
但是,当系统扩展为需要访问跨平台的异构数据库时,系统可能是UNIX、Linux或Windows,数据可以是表单、邮件、XML文档、EJB组件、Web服务、图像、音视频文件或其他非结构化数据,DAL很难支持这种跨平台的异构数据库访问。
为了解决跨平台异构数据库的问题,使得数据访问层能够针对不同数据类型、多种标准技术的大数据应用跨平台异构数据库,能够满足不同数据类型的读写要求,数据访问层的设计需要与各种标准技术和产品兼容。
在这种场景下,抛出了统一数据访问接口(UDAI)的概念,其目的是基于统一数据接口,支持分布式环境下的跨平台异构数据的统一访问。
UDAI的主要功能有以下几点:
统一数据显示、存储和管理。
分离访问接口和实现代码,底层数据库连接的更改不影响统一的数据访问接口。
屏蔽数据源的差异和数据库操作的细节,使应用层专注于数据应用程序。
提供统一的访问接口和统一的查询语言。
图4-14给出了UDAI的一般架构,主要包括统一查询语言、数据模型、数据转换引擎、数据源包装器等几个构件,这些构件都是为了将来自不同数据源的不同格式的数据转换为统一的数据服务,使数据处理系统能够统一检索所需的数据。
图4-14 UDAI的架构
数据存储是大数据分析的第一步,而数据存储也不仅仅是简单地将数据存储在物理媒介中。数据存储系统有着自己的一套架构体系,主要包含数据采集与建模、分布式文件系统、NoSQL数据库、统一数据访问接口等。
本章对数据存储系统的每一层展开叙述,首先介绍数据建模的相关内容,围绕数据建模的定义、数据模型的分类以及如何进行数据建模展开;其次便是对分布式文件系统进行介绍,主要介绍了分布式文件系统的发展进程,并且用两个典型的分布式文件系统GFS、HDFS举例,围绕分布式文件系统的设计理念、体系架构等展开;然后对NoSQL数据库的由来、特性和类别进行介绍,并且用表的形式对各类数据库的特性进行总结;最后,为了方便数据的统一访问,引入了统一数据访问接口的概念,并对其做了简短的介绍。
1.【单选】以下哪个不是数据建模的目的?( )
A.优化数据模型
B.减少存储需求
C.提高数据安全性
D.实现高效检索
2.【单选】以下哪个是NoSQL数据库的一种?( )
A.MySQL
B.Oracle
C.MongoDB
D.SQL Server
3.【单选】NoSQL数据库适用于以下哪种情况?( )
A.需要低延迟读写速度的场景
B.需要支撑海量数据和流量的场景
C.需要降低运营成本的场景
D.以上所有选项
4.论述统一数据访问接口的意义和作用。
5.分布式文件系统和传统文件系统的主要区别是什么?