Hbase 原理及性能分析报告

nx42 贡献于2012-09-07

作者 ssmax  创建于2008-08-06 06:44:00   修改者ssmax  修改于2008-08-25 07:20:00字数23375

文档摘要:Hbase是一个分布式开源数据库,基于Hadoop分布式文件系统,模仿并提供了基于Google文件系统的Bigtable数据库的所有功能。<br> Hbaes的目标是处理非常庞大的表,可以用普通的计算机处理超过10亿行数据,并且有数百万列元素组成的数据表。<br> Hbase可以直接使用本地文件系统或者Hadoop作为数据存储方式,不过为了提高数据可靠性和系统的健壮性,发挥Hbase处理大数据量等功能,需要使用Hadoop作为文件系统,那么我们就先要了解Hadoop文件系统的基本特性和原理,才能更好地理解Hbase的工作方式。
关键词:

Hbase分析报告 本文基于环境hadoop-0.16.4 和 hbase-0.1.3 编写 Hbase是一个分布式开源数据库,基于Hadoop分布式文件系统,模仿并提供了基于Google文件系统的Bigtable数据库的所有功能。 Hbaes的目标是处理非常庞大的表,可以用普通的计算机处理超过10亿行数据,并且有数百万列元素组成的数据表。 Hbase可以直接使用本地文件系统或者Hadoop作为数据存储方式,不过为了提高数据可靠性和系统的健壮性,发挥Hbase处理大数据量等功能,需要使用Hadoop作为文件系统,那么我们就先要了解Hadoop文件系统的基本特性和原理,才能更好地理解Hbase的工作方式。 Hadoop文件系统 Hadoop文件系统是一个能够兼容普通硬件环境的分布式文件系统, 和现有的分布式文件系统不同的地方是Hadoop更注重容错性和兼容廉价的硬件设备,这样做是为了用很小的预算甚至直接利用现有机器就实现大流量和大数据量的读取。 Hadoop 使用了POSIX的设计来实现对文件系统文件流的读取。HDFS(Hadoop FileSystem)原来是Apache Nutch搜索引擎(从Lucene发展而来)开发的一个部分,后来独立出来作为一个Apache子项目。 Hadoop的假设与目标 1、 硬件出错,Hadoop假设硬件出错是一种正常的情况,而不是异常,为的就是在硬件出错的情况下尽量保证数据完整性,HDFS设计的目标是在成百上千台服务器中存储数据,并且可以快速检测出硬件错误和快速进行数据的自动恢复。 2、 流数据读写,不同于普通的文件系统,Hadoop是为了程序批量处理数据而设计的,而不是与用户的交互或者随机读写,所以POSIX对程序增加了许多硬性限制,程序必须使用流读取来提高数据吞吐率。 3、 大数据集,HDFS上面一个典型的文件一般是用GB或者TB计算的,而且一个数百台机器组成的集群里面可以支持过千万这样的文件。 4、 简单的文件模型,HDFS上面的文件模型十分简单,就是一次写入多次读取的模型,文件一旦创建,写入并关闭了,之后就再也不会被改变了,只能被读取,这种模型刚好符合搜索引擎的需求,以后可能会实现追加写入数据这样的功能。 5、 强大的跨平台兼容性,由于是基于java的实现,无论是硬件平台或者是软件平台要求都不高,只要是jdk支持的平台都可以兼容。 Hadoop体系结构 目录节点(NameNode)和数据节点(DataNodes) Hadoop文件系统是主从架构,一个Hadoop文件系统由唯一一个目录节点和数个数据节点组成。 Hadoop文件系统对外表现为一个普通的文件系统,用户可以用文件名去存储和访问文件,而实际上文件是被分成不同的数据块,这些数据块就是存储在数据节点上面。 目录节点是集群里面的主节点,负责文件名的维护管理,也是客户端访问文件的入口。文件名的维护包括文件和目录的创建、删除、重命名等。同时也管理数据块和数据节点的映射关系,客户端需要访问目录节点才能知道一个文件的所有数据块都保存在哪些数据节点上。 数据节点一般就是集群里面的一台机器,负责数据的存储和读取。在写入时,由目录节点分配数据块的保存,然后客户端直接写到对应的数据节点。在读取时,当客户端从目录节点获得数据块的映射关系后,就会直接到对应的数据节点读取数据。数据节点也要根据目录节点的命令创建、删除数据块,和冗余复制。 一个典型的Hadoop文件系统集群部署,是由一台性能较好的机器运行目录节点,而集群里面的其它机器每台上面运行一个数据节点。当然一个机器可以运行任意多个数据节点,甚至目录节点和数据节点一起运行,不过这种模式在正式的应用部署中很少使用。 唯一的目录节点的设计大大简化了整个体系结构,目录节点负责Hadoop文件系统里面所有元数据的仲裁和存储。这样的设计使数据不会脱离目录节点的控制。 Hadoop文件系统命名空间 Hadoop文件系统使用的是传统的分级文件体系,客户端程序可以创建目录并且在目录里面保存文件,类似与现在一般的文件系统。Hadoop允许用户创建、删除文件,在目录间转移文件,重命名文件等,但是还没有实现磁盘配额和文件访问权限等功能,也不支持文件的硬连接和软连接(快捷方式),这些功能在短期内不会实现。 目录节点负责存储和管理整个文件系统的命名空间,应用程序可以指定某一个文件需要在Hadoop文件系统中冗余多少份,这个在Hadoop中称为冗余因素,保存在目录节点里面。 Hadoop存储原理 冗余数据保存 Hadoop文件系统是为了大文件的可靠保存而设计的,一个文件被划分成一连串的数据块,除了文件的最后一块以外其它所有的数据块都是固定大小的,为了数据容错性,每一个数据块都会被冗余存储起来,而每个文件的块大小和冗余因素都是可以设置的,程序可以设置文件的数据块要被复制多少份,而且这个冗余因素除了可以在创建的时候指定,还可以在之后改变。在Hadoop文件系统里面文件只会被写入一次,并且任何时间只会有一个程序在写入这个文件。 目录节点是根据数据块的冗余状况来作出处理决策的,数据节点会定期发送一个存在信号(Heartbeat)和数据块列表给目录节点,存在信号使目录节点认为该数据节点还是有效的,而数据块列表包括了该数据节点上面的所有数据块编号。 数据存取策略 复制策略是hadoop文件系统最核心的部分,对读写性能影响很大,hadoop和其它分布式文件系统的最大区别就是可以调整冗余数据的位置,这个特性需要很多时间去优化和调整。 一、数据存放 目前hadoop采用以机柜为基础的数据存放策略,这样做的目的是提高数据可靠性和充分利用网络带宽。当前具体实现了的策略只是这个方向的尝试,hadoop短期的研究目标之一就是在实际产品环境中观察系统读写的行为,测试性能和研究更深入的规则。 一个大的hadoop集群经常横跨多个机柜,而不同机柜之间的数据通讯同经过交换机或者路由,所以同一个机柜中不同机器的通讯带宽是比不同机柜之间机器通讯时候的大。 Hadoop提供了一个api来决定数据机所属的机柜id,当文件系统启动的时候,数据机就把自己所属的机柜id发给目录机,然后目录机管理这些分组。 Hadoop默认是每个数据机都是在不同的机柜上面,这种方法没有做任何性能优化,但是也有不少优点: 1、 数据可靠性是最高的。因为这样可以防止机柜出错的时候数据丢失。 2、 在读取数据的时候充分利用不同机柜之间的带宽。 3、 而且这个策略可以很容易的完成负载平衡和错误处理。 缺点就是写入数据的时候并不能完全利用同一机柜里面机器的带宽。 在默认的配置下,hadoop的冗余复制因子是3,意思就是每一块文件数据一共有3个地方存放,hadoop目前的存放策略是其中两份放在同一个rack id的不同机器上面,另外一个放在不同rack id的机器上面,简单来说就是1/3的冗余数据在一个机柜里面,2/3的冗余数据在另外一个机柜里面,这样既可以防止机柜异常时候的数据恢复,又可以提高读写性能。 上面所说的策略目前还是在测试优化阶段。 二、数据读取 数据读取策略,根据前面所说的数据存放策略,数据读取的时候,客户端也有api确定自己的机柜id,读取的时候,如果有块数据和客户端的机柜id一样,就优先选择该数据节点,客户端直接和数据节点建立连接,读取数据。如果没有,就随机选取一个数据节点。 三、数据复制 主要是在数据写入和数据恢复的时候发生,数据复制是使用流水线复制的策略。 当客户端要在hadoop上面写一个文件,首先它先把这个文件写在本地,然后对文件进行分块,默认64m一块,每块数据都对hadoop目录服务器请求,目录服务器选择一个数据机列表,返回给客户端,然后客户端就把数据写入第一台数据机,并且把列表传给数据机,当数据机接收到4k数据的时候,写入本地并且发起连接到下一台数据机,把这个4k传过去,形成一条流水线。当最后文件写完的时候,数据复制也同时完成,这个就是流水线处理的优势。 通讯协议 hadoop的通讯协议基本是在tcp/ip的基础上开发的,客户端使用ClientProtocol和目录服务器通讯,数据机使用DatanodeProtocol和目录服务器通讯,而目录服务器一般只是应答客户端和数据机的请求,不会主动发起通讯。 数据错误和异常 hadoop文件系统的主要目标就是在硬件出错的时候保证数据的完整性,它把磁盘错误作为肯定会出现的情况来对待,而不是异常。一般数据存储中出现的错误有几种,分别是目录服务器错误,数据机错误,和网络传输异常。 1、 数据机出错,每个数据机会定时发送一个心跳信息给目录服务器,表明自己仍然存活,网络异常可能会导致一部分数据机无法和目录服务器通讯,这时候目录服务器收不到心跳信息,就认为这个数据机已经死机,从有效io列表中清除,而该数据机上面的所有数据块也会标记为不可读。这个时候某些数据块的冗余份数有可能就低于它的冗余因子了,目录服务器会定期检查每一个数据块,看看它是否需要进行数据冗余复制。 2、 出现数据异常,由于网络传输和磁盘出错的原因,从数据机读取的数据有可能出现异常,客户端实现对数据块的校验,用md5和sha1进行校验,客户端在创建文件的时候,会对每一个文件块进行信息摘录,并把这些信息写入到同一个路径的隐藏文件里面。当客户端读取文件的时候,会先读取该信息文件,然后对每个读取的数据块进行校验,如果校验出错,客户端就会请求到另外一个数据机读取该文件块,并且报告给目录服务器这个文件块有错误,目录服务器就会定期检查,并且重新复制这个块。 3、 目录服务器出错,FsImage和Editlog是目录服务器上面两个最核心的数据结构,如果其中一个文件出错的话,会造成目录服务器不起作用,由于这两个文件如此重要,所以目录服务器上面可以设置多个备份文件和辅助服务器,当这两个文件有改变的时候,目录服务器就会发起同步操作,虽然这样增加了系统的负担,但是在目前这个架构上面为了实现数据的可靠性,这个同步操作是非常必要的。 Hadoop文件系统尚未实现的功能总结: 1、 文件追加写入,这个功能近期内不会实现,没有这个功能会引起当文件尚未关闭的时候,数据服务器死机或者目录服务器死机,会引起文件文件丢失,并且不可后续恢复写入。 2、 系统快照,一个全系统的快照功能,如果没有这个功能就不能实现文件系统的回滚操作。 3、 集群负载均衡,均衡策略暂时没有实现,有几个策略十分有用,比如在某台数据机可能磁盘过低的时候,把该数据机上面的一些数据转移到还有很多空间剩余的数据机上;当某个文件突然被大量读写的时候,动态增加该文件的冗余因子,并且数据块复制到更多的数据机上面,以提高读取性能。 4、 文件系统的用户权限,这个也是近期内不会实现的了。 5、访问权限,现在是无限制访问的,没有访问权限控制。 Hadoop文件系统性能分析 由于没办法建立大型的Hadoop文件系统,只能节选一些网上的性能分析,以表示一二。 1、 和Kosmos Filesystem的比较,Kosmos Filesystem也是一个类似Google 文件系统的具体实现,所以和Hadoop具有比较的意义。KFS是用c++编写的,在代码执行效率上面比java好不少。 数据插入测试: 测试环境: · 1 1.8GHz Dual-core Opteron Processor 2210 · 4 GB RAM · 4 7200 RPM SATA drives (mounted JBOD) 测试使用Hypertable,这也是一个类似Google bigtable的具体实现,可以使用KFS和HDFS作为文件系统,在插入测试后,表格含有75,274,825个数据单元,每一个键值是7字节大小,每一个数据是15字节大小。 测试结果:KFS基本大幅度胜出。 HDFS (no flush)  Elapsed time:  170.66 s Avg value size:  15.25 bytes  Avg key size:  7.10 bytes    Throughput:  1792158.60 bytes/s  Total inserts:  14825279    Throughput:  86869.79 inserts/s  Elapsed time:  167.44 s Avg value size:  15.26 bytes  Avg key size:  7.11 bytes    Throughput:  1871062.70 bytes/s  Total inserts:  15185349    Throughput:  90690.84 inserts/s  Elapsed time:  179.91 s Avg value size:  15.20 bytes  Avg key size:  7.03 bytes    Throughput:  1737888.10 bytes/s  Total inserts:  15208310    Throughput:  84532.68 inserts/s  Elapsed time:  169.57 s Avg value size:  15.22 bytes  Avg key size:  7.11 bytes    Throughput:  1831688.52 bytes/s  Total inserts:  15080926    Throughput:  88937.45 inserts/s KFS (no flush)  Elapsed time:  125.51 s Avg value size:  15.25 bytes  Avg key size:  7.10 bytes    Throughput:  2436864.83 bytes/s  Total inserts:  14825279    Throughput:  118120.09 inserts/s  Elapsed time:  126.25 s Avg value size:  15.26 bytes  Avg key size:  7.11 bytes    Throughput:  2481447.59 bytes/s  Total inserts:  15185349    Throughput:  120276.33 inserts/s  Elapsed time:  135.51 s Avg value size:  15.20 bytes  Avg key size:  7.03 bytes    Throughput:  2307335.26 bytes/s  Total inserts:  15208310    Throughput:  112231.19 inserts/s  Elapsed time:  127.66 s Avg value size:  15.22 bytes  Avg key size:  7.11 bytes    Throughput:  2433069.68 bytes/s  Total inserts:  15080926    Throughput:  118137.45 inserts/s 2、 Hadoop读取测试,与本地文件系统比较 使用hadoop自带的FileBench程序,写入两个1g大小的文件,第一个是字节流文件,随机生成,第二个是字符文件,随机字典生成。下面是本地文件系统和hadoop文件系统的比较,由于集群是在极端条件下测试,目录服务器在广州网通机房,两台数据服务器一台在北京电信机房,一台在北京网通机房,所以测试的瓶颈基本在网络传输,估计在局域网中表现应该好很多。 本地文件系统测试: java -classpath hadoop-0.16.4-test.jar:hadoop-0.16.5-dev-core.jar:lib/commons-logging-api-1.0.4.jar:lib/log4j-1.2.13.jar:lib/commons-logging-1.0.4.jar:lib/commons-cli-2.0-SNAPSHOT.jar org.apache.hadoop.io.FileBench -dir /home/ssmax/test -nolzo -nozip DIR: file:/home/ssmax/test W SEQ_PLN: 42 seconds W TXT_PLN: 31 seconds R SEQ_PLN: 25 seconds R TXT_PLN: 21 seconds 第一行是流文件写入,第二行是文本文件写入,第三行是流文件读取,第四行是文本文件读取。 Hadoop文件系统测试: java -classpath build/hadoop-0.16.5-dev-test.jar:hadoop-0.16.5-dev-core.jar:lib/commons-logging-api-1.0.4.jar:lib/log4j-1.2.13.jar:lib/commons-logging-1.0.4.jar:lib/commons-cli-2.0-SNAPSHOT.jar org.apache.hadoop.io.FileBench -dir "hdfs://218.107.63.238:9000/user/ssmax" -now -nolzo -nozip DIR: hdfs://218.107.63.238:9000/user/ssmax W SEQ_PLN: 437 seconds W TXT_PLN: 439 seconds R SEQ_PLN: > 15分钟 R TXT_PLN: > 15 分钟 由于测试客户端上行比下行快很多,所以读取的时候很慢,超过了可以接受的时间,如果在数据机做读操作,读取速度会大大提高。 java -classpath hadoop-0.16.5-dev-test.jar:hadoop-0.16.5-dev-core.jar:lib/commons-logging-api-1.0.4.jar:lib/log4j-1.2.13.jar:lib/commons-logging-1.0.4.jar:lib/commons-cli-2.0-SNAPSHOT.jar org.apache.hadoop.io.FileBench -dir "hdfs://218.107.63.238:9000/user/ssmax" -now -nolzo -nozip DIR: hdfs://218.107.63.238:9000/user/ssmax R SEQ_PLN: 80 seconds R TXT_PLN: 63 seconds 所以得出结论就是rack id的配置十分重要,需要区分机柜,传输的瓶颈主要在网络。 上面就是关于Hadoop文件系统的原理和测试,Hbase可以通过配置使用本地文件系统或者Hadoop文件系统。而测试的过程中也发现了一个更成熟的组合,也是开源项目的Hypertable和KFS,这两个也是类似Bigtable和GFS的实现,主要是使用c++实现的,这里先记录一下,以后再做研究。 Hypertable作者语:Hypertable与HBase的差别是,Hypertable是Bigtable的一个更高性能的实现(InfoQ同样采访了HBase的团队)。我开始的时候跟Jim Kellerman以及Hadoop团队的一些成员一起为HBase工作。但我们对HBase应该变成什么样子有不同意见,对实现语言的选择也有不同意见。他们坚持用Java,而我力推C++。于是我就分出来,开始了Hypertable项目。 Hbase分布式数据库 数据模型 Hbase是一个类似Bigtable的分布式数据库,大部分特性和Bigtable一样,是一个稀疏的,长期存储的{存在硬盘上},多维度的,排序的映射表。这张表的索引是行关键字,列关键字和时间戳。每个值是一个不解释的字符数组,数据都是字符串,没类型。 用户在表格中存储数据,每一行都有一个可排序的主键和任意多的列。由于是稀疏存储的,所以同一张表里面的每一行数据都可以有截然不同的列。 列名字的格式是":

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档