2.4 大数据存储技术
传统的数据存储和管理以结构化数据为主,而大数据往往以半结构化和非结构化数据为主、结构化数据为辅,而且各种大数据应用通常要对不同类型的数据进行内容检索、交叉比对、深度挖掘与综合分析。同时,大数据的数据规模往往非常庞大,传统的关系型数据库就显得有些力不从心。
应对这类应用场景,基于Hadoop开源体系的系统平台更为擅长。它们通过对Hadoop生态体系的技术扩展和封装,实现对半结构化和非结构化数据的存储和管理,通过分布式存储与本地计算的方式,实现对PB量级、EB量级数据的存储和管理。
2.4.1 HDFS
Hadoop有3个核心组件:分布式文件系统HDFS、资源调度工具YARN和分布式计算框架 MapReduce。其中,HDFS 负责海量数据的存储,其主要角色有 NameNode、DataNode、SecondaryNameNode;YARN 负责海量数据运算时的资源调度,其主要角色有ResourceManager、NodeManager;MapReduce是一个计算框架,也可以认为它是一个应用程序开发包,可以实现分布式计算。
HDFS 是一个高度容错的文件系统,适合部署在廉价的机器上。HDFS 采用Master/Slave(主从)架构。一个HDFS集群是由一个NameNode和一定数目的DataNode组成的。NameNode是一个中心服务器,负责管理文件系统的命名空间及客户端对文件的访问。集群中的 DataNode 一般是一个节点,负责管理数据存储。HDFS 架构如图 2-17所示。
当一个大数据文件需要保存在HDFS上时,HDFS会先对这个文件进行切分,将其切分成若干个数据块。同时,HDFS 会复制这些数据块,并将它们放置在服务器群的计算节点中,这样就可以在这些节点上处理这些数据。
其中,NameNode的职责包括:
● 负责文件元数据信息的操作,以及处理客户端的请求;
● 管理HDFS的命名空间;
● 管理文件树及文件树中所有的文件和文件夹的元数据信息;
● 维护文件到块的对应关系和块到节点的对应关系;
● 记录命名空间镜像文件和操作日志文件,这些信息会被存储在RAM和本地硬盘中;
● 记录每个文件中各个块所在的数据节点的位置信息,但它并不永久保存块的位置信息,因为这些信息在系统启动时会由数据节点进行重建的。
图2-17 HDFS架构
在HDFS中,NameNode(NN)与DataNode(DN)通过心跳机制进行通信,由NN全权管理数据块的复制,周期性地接收DN的心跳信息和块的状态报告。若接收到心跳信息,则NN认为DN工作正常。如果超过10分钟还未接收到DN的心跳信息,那么NN会认为DN已经宕机,这时NN会重新复制DN上的数据块。块的状态报告中包含一个DN上所有数据块的列表,该报告每隔1小时发送一次。
在HDFS中,NameNode负责文件元数据的操作,负责处理文件内容的读写请求,但数据流不经过NameNode,会询问它跟哪个DataNode联系,然后直接由该DataNode进行相应的数据交互操作。
某个DataNode宕机,不会影响整个集群的运行,NameNode会判断在此机器上的文件副本在哪里还有备份,并复制一份到另外的机器上,从而保证整个集群数据的可靠性。但是,如果NameNode坏掉,那么HDFS就不能工作了,整个文件系统中的文件都会丢失(其实没有丢失,只是分不清楚有哪些文件,以及哪些文件的哪些副本在哪台机器上),因此NameNode的容错机制非常重要,Hadoop提供了两种容错机制。
第一种是将持久化存储在本地硬盘的文件系统元数据备份。Hadoop 可以通过配置来让NameNode将它的持久化状态文件写到不同的文件系统中。这种写操作是同步的,并且是原子化的。比较常见的配置是在将持久化状态文件写到本地硬盘的同时,也将其写入一个远程挂载的网络文件系统(NFS)中。
第二种是运行一个辅助 NameNode,即 SecondaryNameNode。事实上,SecondaryNameNode 并不是被用作 NameNode 的备份。它的主要作用是定期地将命名空间镜像文件与操作日志文件合并,以防止操作日志文件变得过大。通常,SecondaryNameNode 运行在一个单独的物理机上,因为合并操作需要占用大量的 CPU时间,以及和NameNode相当的内存。Secondary NameNode上保存着合并后的命名空间镜像文件的一个副本,这个副本在NameNode宕机时可以用上。
但是,辅助NameNode总是落后于主NameNode的,所以在NameNode宕机时,数据丢失是不可避免的。在这种情况下,要结合第一种机制中提到的远程挂载的网络文件系统中的NameNode元数据文件来使用,把NFS中的NameNode元数据文件复制到辅助NameNode中,并把辅助NameNode作为主NameNode来运行。
在HDFS中DataNode是真正存放数据的节点,数据被保存在DataNode的磁盘上,数据文件会被切成块,一个块默认的大小是128MB。同时,一份数据会被复制多个副本,一般默认的副本数是3个。数据块被NameNode分配在不同的DataNode中,从而保证将来数据处理的并行性及数据的可靠性(不会因为一台机器坏掉而丢失)。
DataNode负责处理文件系统客户端的读写请求,在NameNode的统一调度下进行数据块的创建、删除和复制。集群中单一 NameNode 的结构大大简化了系统的架构。NameNode 是所有 HDFS 元数据的仲裁者和管理者,但是,用户数据永远不会流过NameNode。正因为数据不会通过 NameNode,数据又存在多个副本,所以 HDFS 可以实现高吞吐量的数据访问。当执行一个任务时,这个任务会被分解成不同的子任务,所有的子任务被并行执行,所以会在很短的时间内执行完任务。
可通过编程或命令行的方式与HDFS进行交互,HDFS的命令和Linux文件系统的命令有很多相似之处,几乎本地文件系统的所有操作命令在HDFS中都可以找到对应的命令,如创建目录、复制文件、更改权限等,所以HDFS的文件操作非常简单。
2.4.2 NoSQL数据库
NoSQL数据库泛指非关系型数据库。大数据的发展导致传统的关系型数据库在处理数据时显得力不从心,而非关系型数据库则由于其自身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合中多重数据种类带来的挑战,尤其是大数据应用难题。
NoSQL 数据库有如下优点:NoSQL 数据库种类繁多,其共同的特点是去掉了关系型数据库的关系型特性,即数据之间无关系,这样就非常容易扩展,无形中也给架构层面带来了扩展能力;NoSQL数据库具有很好的读写性能,在大数据量下同样表现优秀。
常见的NoSQL数据库包括4类:键值存储数据库、列式存储数据库、文档数据库、图形数据库。
键值存储数据库(也称“键值数据库”)使用简单的键值方法来存储数据,将数据存储为键值对集合,将键作为唯一标识符。键和值可以是从简单对象到复杂复合对象的任何内容。键值存储数据库是高度可分区的,并且允许以其他类型数据库无法实现的规模进行水平扩展。例如,如果现有分区已被填满,并且需要更多的存储空间,那么键值存储数据库就会将额外的分区分配给表。常见的键值存储数据库有 Amazon DynamoDB、Apache Cassandra、Redis等。
列式存储数据库(也称“列存储数据库”)用来应对分布式存储的海量数据。传统的关系型数据库,如Oracle、DB2、MySQL、SQL Server等采用行式存储法。在基于行式存储的数据库中,数据是以行为基础逻辑存储单元进行存储的,一行中的数据在存储介质中以连续存储形式存在。列式存储是相对于行式存储而言的,新兴的HBase、HP Vertica、EMC Greenplum 等分布式数据库均采用列式存储。在基于列式存储的数据库中,数据是以列为基础逻辑存储单元进行存储的,一列中的数据在存储介质中以连续存储形式存在。行式存储的写入是一次性完成的,消耗的时间比列式存储少,并且能够保证数据的完整性。缺点是数据读取过程中会产生冗余数据,如果只有少量数据,此影响可以忽略;反之,可能会影响数据的处理效率。虽然列式存储在写入效率、保证数据完整性方面都不如行式存储,但它的优势在于读取过程中不会产生冗余数据,这适用于对数据完整性要求不高的大数据处理领域。查询过程中,可针对各列的运算并发执行(SMP),在数据列中高效查找数据,无须维护索引(任何列都能作为索引);在查询过程中能够尽量减少无关 IO,避免全表扫描;因为各列独立存储,且数据类型已知,所以可以根据列的数据类型、数据量大小等因素动态选择压缩算法,以提高物理存储利用率;如果某一行的某一列没有数据,那么存储时就可以不存储该列的值,这将比行式存储更节省空间。
一般来说,一个OLAP类型的查询可能需要访问几百万甚至几十亿个数据行,且该查询往往只关心少数几个数据列。例如,查询今年销量最高的前20个商品,这个查询只关心3个数据列:时间、商品及销量。商品的其他数据列,如商品URL、商品描述、商品所属店铺等,对这个查询都是没有意义的。列式存储数据库只需要读取存储时间、商品、销量的数据列,而行式存储数据库则需要读取所有数据列。因此,列式存储数据库大大提高了OLAP大数据量查询的效率。
很多列式存储数据库还支持列族,即将多个经常一起访问的数据列的各个值存放在一起。如果读取的数据列属于相同的列族,列式存储数据库可以从相同的地方一次性读取多个数据列的值,从而避免了多个数据列的合并。列族是一种行列混合存储模式,这种模式能够同时满足OLTP和OLAP的查询需求。
实操中会发现,行式存储数据库在读取数据的时候存在一个固有的“缺陷”。例如,所选择查询的目标只涉及少数几项属性,但由于这些目标数据埋藏在各行数据单元中,而行单元往往又特别大,所以应用程序必须读取每一条完整的行记录,从而导致读取效率大大降低。对此,行式存储数据库给出的优化方案是加索引。
在OLTP类型的应用中,通过索引机制或给表分区等手段,可以简化查询操作步骤,提升查询效率。但针对海量数据背景的 OLAP 应用(如分布式数据库、数据仓库),行式存储数据库就有些力不从心了,因为行式存储数据库建立索引和物化视图需要花费大量时间和资源,而且无法从根本上解决查询性能和维护成本等问题,所以后来出现了列式存储数据库。对于数据仓库和分布式数据库来说,大部分情况下,它们会从各个数据源汇总数据,然后进行分析和反馈,其操作大多是围绕同一列属性的数据进行的,而当查询某属性的数据记录时,列式存储数据库只需要返回与列属性相关的值。在大数据量查询场景中,列式存储数据库可在内存中高效组合各列的值,最终形成关系记录集,因此,可以大大减少IO消耗,并缩短查询响应时间,非常适合数据仓库和分布式数据库。
文档数据库是用来管理文档的。在传统的数据库中,信息被分割成离散的数据段,而在文档数据库中,文档是处理信息的基本单位,并且文档可以很长、很复杂、无结构,与字处理文档类似。一个文档相当于关系型数据库中的一条记录,文档数据库可存放并获取文档,其格式可以是XML、JSON、BSON等,这些文档具备可述性,呈现分层的树状结构,可以包含映射表、集合和纯量值。数据库中的文档彼此相似,但不必完全相同。文档数据库中所存放的文档,就相当于键值存储数据库中所存放的“值”。文档数据库可被视为其值可查的键值存储数据库。但是,包含多项操作的复杂事务不适合采用文档数据库,因为文档数据库不适合执行“跨文档的原子操作”。目前,国外比较流行的文档数据库有CouchDB、MongoDB等。国内也有文档数据库SequoiaDB,而且已经开源。
图形数据库使用灵活的图形模型,并且能够扩展到多个服务器上。图形数据库在处理关联关系方面具有极大的优势,特别是在这个社交网络得到极大发展的互联网时代。比起传统的信息存储和组织模式,图形数据库能够清晰揭示复杂的模式,尤其在错综复杂的社交、物流、金融风险控制领域效果更为明显。
图形数据库虽然弥补了很多关系型数据库的缺陷,但仍有一些不足的地方。例如,图形数据库不适合记录大量基于事件的数据(如日志数据),不适合存储二进制数据,不适合对并发性能要求高的项目等。
目前,不少行业已将图形数据库纳入实施计划。近年来,世界五百强公司中使用图形数据库的比例也不断提高。在金融领域,人们利用图形数据库来实现反欺诈。软件、物流、新零售、航空、电信、医疗等领域也在大量使用图形数据库。
图形数据库善于处理大量、复杂、互联、多变的网状数据,其效率比传统的关系型数据库高百倍、千倍,甚至万倍。图形数据库特别适用于社交网络、实时推荐、银行交易环路、金融征信系统等领域。领英、沃尔玛、Cisco、HP、eBay等全球知名企业都在使用图形数据库 Neo4j,中国企业也逐步开始用图形数据库来构建自己的应用。除了 Neo4j,图形数据库还有InfoGrid、Infinite Graph等供选择。