当今信息化时代充斥着大量的数据。海量数据存储是一个必定的趋势。然而数据怎样的存储和查询,尤其是当今非结构化数据的高速增长。对其数据的存储。处理,查询。使得现在的 关系数据库存储带来了巨大的挑战。分布存储技术是云计算的基础,主要研究怎样存储、组织和管理数据中心上的大规模海量数据.由于面临的数据规模和用户规模更加庞大,在可扩展性、容错性以及成本控制方面面临着更加严峻的挑战[1]。
对于大量的半结构化数据(semi-structure data)和非结构化数据,对其存储和并发计算以及扩展能力而设计出了NoSQL,像有google的Bigtable,Amaze 的Dynamo,以及Apache的Hbase。
NoSQL支持强大的水平扩展能力和高性能。与关系数据库不同的是,NoSQL能够採用松弛一致性(relax consistant),可是提供终于一致性保证数据的读的不一致。
像在Dynamo中为了提供高的写的能力(购物时不会由于并发而不会加入购物车不能成功,而影响用户体验),不得不採取终于一致性。
依据CAP原理,一致性、高可用性、分区容忍性(Partition-tolerance)三者中最多择其二。舍其一。在Dynamo牺牲了一致性,可是提供高的可用性[6]。另外Dynamo採用非集中化管理,使得每一个节点都是同等地位,充分利用分布式哈希表(DHT)的一种实现即一致性哈希,使得Dynamo提供强大的可扩展性。Hbase能够说提供强的一致性。可是牺牲掉了一定的高可用性,比方存在单点故障。在当一个Regionserver出问题或失去联系时。须要master来又一次部署原Regionserver以下的是Region到别的空暇的server下。这段时间无法与以下的Region联系。Hbase是Apache的顶级项目Hadoop的一个组成部分,hadoop是一种分布式系统基础架构。
它能够充分利用集群的威力高速运算和存储。以下着重介绍Hbase。
一、非结构化数据存储结构
Hbase是Apache的顶级子项目,它的理念来自于Google的Bigtable。它是分布的、面向列的、多维的数据库系统,它提供高的容错性和可扩展性,它是建立HDFS(Hadoop分布式文件系统)之上。Hbase的表的每一行有行键(row key)和随意多的列(column)组成。当中多个列能够组成列族(column family)。
每一个数据单元(cell)能够拥有数据的多个版本号(version),这个是使用时间戳来区分。
所以Hbase是拥有map:(行键,列族:列,时间戳)相应一个值[2][7]。
Hbase是应用在分布式系统之中。他将大量的行分成行区域(Region),将化分后的区域分布到集群中去。
Hbase与HDFS同样是使用master-slave结构。在Hbase中slave相应是Regionserver。负责管理master分下来的Rregion。同一时候master还负责负载平衡以及当Region出现错误时,master会收到Regionserver的请求消息。会又一次分配到新的空暇的节点(这涉及到HLog)。
正如上所说。Hbase是面向列的存储,它在实际的物理存储器中是以列族的存储。所以在列族同样的会在存储在一起。在与面向行的关系数据库比較,这会节省了大量为空的属性。Hbase也是一种NoSQL,它不像关系数据库那样提供结构化查询语句来訪问当中的数据。NoSQL是一种模式自由(schema-free)的数据库,良好是设计会提升数据结构而不存在表的重写[3]。
Hbase的容错性不得不提到HDFS,HDFS是Hadoop 分布式文件系统,它能够部署在便宜的机器上。提高系统的容错性和高的吞吐量。
HDFS分为一个Namenode和多个Datanode,Namenode管理文件系统的名字空间,它维护着文件系统树以及整个树内全部的文件和文件夹。Datanode存储着数据块。负责删除加入等操作。Hbase的文件被分为固定大小的块(默认的为64M),块server是存储块和对指定块的读写操作。在分布式的集群中,机器故障乃是常态。为了安全问题,所以不断的检測机器的状况和数据的备份时必须的。
HDFS的副本一般的情况下分为3份。一份是同个节点中,第二份放在不在机架上的还有一个节点,最后一份是放在第二份同样机架的不同节点中[4]。
Master存储着文件系统元数据(metadata)。主要分为3种元数据:文件和块的名字空间、文件到块的映射和块副本的位置。块server存储着数据,所以master必要和块server保持者联系。Master定期发送心跳(heartbeat)与块server了解块server的状况。客户读写数据是都首先和master先取得联系然后再与块server完毕读写操作。
在一致性上。HDFS 是一个松散的一致性检查的模型。
他主要是为了追加(append)操作而不是覆盖重写(overwrite)操作。由于覆盖重写的话可能在一次读的操作会读到与其它副本不一致的数据。而在追加操作,当中一个副本的不一致也不会导致client读到不一致的数据。同一时候HDFS在追加操作时採用租用(Lease)机制,即将块的写操作授权给主块server(primary chunk server),另外的副本称为次块server(secondary chunk server)。当多个client的并发写操作时。主块server缓存其写的顺序。之后联系次server进行追加操作。从这里能够看出。在HDFS的基础之上提供版本号一致性。
而不同Dynamo採用矢量时钟即(节点,计数器)(node,counter)列表来钟捕捉同一不同版本号的对象是否有因果关系。当client更新一个对象,它必须指定它正要更新哪个版本号,当存在因果关系,直接覆盖之前的版本号。
若是两个独立的版本号,更新其矢量时钟,使得存在多个版本号。
同事Dynamo採用了NRW机制(N: 复制的节点数量,R: 成功读操作的最小节点数,W: 成功写操作的最小节点数)。当R+W>N时能够说明至少有一个版本号是最新的版本号,这样在数据的读操作就能够保证数据的一致性。
[6]当然在这里也体现出了Dynamo的高可用行。比方设置W=1。即表明仅仅要正确读入一个节点就可以,不须保证写入的值全部传给副本。
二、非结构化数据的读写操作
对Hbase中数据的读写首先是依据行键值或行键值域(row key range)来检索,行键值是依照字典序排列的,针对同一时候訪问的数据设计好类似的行键值会相应地降低I/O操作。
上面提过,由于行区域到达一定大小时会分解并分布到集群中去,在Hbase中使用B+树来存储某个区域的位置信息。在树顶是root表,其保存META表的Region信息,而且root表仅仅有一个,META表中存储着各个被划分的区域的信息。所以通过行健訪问时首先訪问root再一次訪问META表。由此client訪问数据须要经过多次的网络交互,所以client能够使用缓存来缓解。client是採用RPC机制与server端即master或RegionServer进行通信。
另外Hbase还採用缓冲池来保持每次的连接。保证通信不必产生又一次连接的时间开销。
client要求更新数据的时候。为了容错性。数据首先是HLog中。当HLog写成功是,之后数据是写入到menstore。当数据达到一定的大小时,数据会将内存刷新(flush)到本地磁盘中,形成存储文件(storefile)。此时文件仅仅是可读的。当存储文件的大小到达一定的大小,会进行合并(compact)。这个合并将行键值同样的合并到一起形成一个比較大的存储文件,其过程是对版本号的合并与删除的过程。所以从这个角度来看,Hbase是一个追加的过程。当然存储文件的大小到达一定的阀值时,会分裂(split)成两个存储文件[2]。存储文件在组织成HFile以块的形式存在底层的HDFS上。
在[5]中介绍Hbase作为HDFS上层的来评估在大规模数据中随机读和随机写的性能,文中是利用MySQL作为HDFS上层来存储与此作对照。结果显示在多用户多并发读和写时Hbase--HDFS组合负载表现更加的理想。
三、数据的搜索与查找方法探索
现在数据的以PB级别的,海量数据不断增长,怎样高速的存储以及搜索和查找指定的文件所需的时间问题。
在关系数据库中。利用索引降低I/O次数来降低读指定的数据的时间。在Hbase中同样能够使用索引。
Hbase一般设置行键作为主键来查找数据,而行键是依照字典序排的,同一时候Hbase支持利用前缀来,所以合理利用行键会提高查找效率的。在[2]中提到二级索引(secondary index)解决不仅仅是利用行键最为自己的主键。比方购物站点用户Hbase表的行键是用户ID,可是站点为了统计某个时间段的交易记录,在原来表的表上进行扫描可能会扫描整个表。为此我们能够设计还有一张表,而这张表的主见是时间+用户,在Hbase进行按前缀扫描时,所须要的数据可能是放在同一块中。降低了I/O次数。
在[9]中是利用Hbase来存储来处理资源描写叙述框架(RDF)的WEB数据,针对PDF的三元(triple)结构(S,P,O),当中该文章中S代表行键,P代表列,O代表单元(cell)的值。
数据检索默认是依照行键值进行的,文章中建立了6个索引表( PSO, POS, SPO, SOP, OPS and OSP),这包括了全部行键与列的组合。当然这样做,会产生了数据的冗余。由于多建了5个索引。
可是多出的索引满足多种查找。
这也是二级索引的应用。
在[11]中利用Hadoop架构对半结构化数据和非结构化数据的存储、索引构建、数据查询的总体设计。
总体分为两个过程。第一步原始须要存储的数据经过Uploader形成Hbase面向列结构的表,下一步通过indexer形成对数据整理后的索引。第一步与第二步中中涉及到MapReduce操作,MapReduce是google提出的一种编程模型,是来处理大规模数据集的并行运算模型,它分为两个部分:map操作和reduce操作。Map操作将数据进行处理形成一个中间数据。且数据是(key,value)形式,reduce操作将map操作的结果作为输入数[8],即:
map (k1,v1) ——————> list(k2,v2)
reduce (k2,list(v2)) ————>list(v2)
当中在第一步中的MapReduce操作依据索引规则(index rule)进行操作(索引规则是利用半结构化数据或结构化数据的某种边界特征来分解原数据集)。clientAPI能够通过index table进行对特定值或某个范围值进行检索。再从内容表(content table)中寻找指定的值。
在Hbase中为client提供一系列的API来訪问数据,get(byte[] row)来获取指定的行相应的数据。然后实际上是client在指定的Region中收集到的行后在client来进一步运行。另外利用mapreduce尽管提供了强大的计算能力,可是它并非在线业务的非常好的方案。在[10]中提到一种协处理(Coprocessor)框架,它同意HBase 管理员在Region server中加载定制的代码,使的能够实现一些集合函数像行计数器、求最大值、最小值等。
Coprocessor的机制能够理解为,Regionserver端加入了一些回调函数。
client能够在多个节点调用而且能够并行运行。这样使得client不像曾经那样请求到的数据在client进一步运行。而是请求在各个Region中并发运行后的结果直接返回给client,大大提高了效率。