• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Hbase使用hadoop分析
 

Hbase使用hadoop分析

on

  • 3,386 views

 

Statistics

Views

Total Views
3,386
Views on SlideShare
3,267
Embed Views
119

Actions

Likes
5
Downloads
99
Comments
1

6 Embeds 119

http://hadoopguru.info 106
http://1qibu.com 5
http://58.215.188.40 3
http://highscalability.info 2
http://zhaicl.com 2
http://www.1qibu.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • hbase
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Hbase使用hadoop分析 Hbase使用hadoop分析 Document Transcript

    • 文档名称:HBase 使用 hadoop 特点分析文档 HBase 使用 hadoop 特点分析文档文档版本控制 文档版本号 日期 作者 审核人 说明 V0.2 刘景龙 -1-
    • 文档名称:HBase 使用 hadoop 特点分析文档目录1. HDFS 设计目标 ........................................................................................................................ 32. HBase 需求分析 ....................................................................................................................... 4 2.1 随机读 ................................................................................................................................ 4 2.1.1 数据发送接收 .................................................................................................................. 4 2.1.2 连接管理 .......................................................................................................................... 4 2.1.3 连接重用 .......................................................................................................................... 6 2.1.4 本地文件操作 .................................................................................................................. 6 2.1.5 Read/pread 使用 ............................................................................................................... 7 2.1.6 HDFS 块信息预取 ........................................................................................................... 8 2.1.7 锁控制 .............................................................................................................................. 8 2.1.8 社区相关动向 .................................................................................................................. 8 2.2 Append & flush .................................................................................................................. 8 2.2.1HLog 写入......................................................................................................................... 9 2.2.2 Mem store flush 过程 ....................................................................................................... 9 2.3 Client 容错 ....................................................................................................................... 103. 总结 ......................................................................................................................................... 104. 后续工作计划 ......................................................................................... 错误!未定义书签。5. 参考文档 ................................................................................................................................. 116. 快速索引 ................................................................................................. 错误!未定义书签。 -2-
    • 文档名称:HBase 使用 hadoop 特点分析文档1. HDFS 设计目标 本文档分析是基于 HBase0.20.4 和 Hadoop0.20.2,主要讨论了 HBase 典型应用场景 中 hadoop 相关特点,进而整理 HBase 对 HDFS 系统特性的需求,以便完成后期的迁移, 开展后续工作。对于 hbase 中可采用的相关优化点,暂不予讨论。HDFS 的设计目标主 要包括以下几方面: 1. Hardware Failure 2. Streaming Data Access 3. Large Data Sets 4. Simple Coherency Model 5. Moving Computation is Cheaper than Moving Data 6. Portability Across Heterogeneous Hardware and Software Platforms 不难看出最初 HDFS 是针对 mapreduce 设计的,其设计目标主要是针对流式大规模 数据访问。对比 mapreduce 和 hbase 应用的特点,mapreduce 需求包括以下几个特点[1]: 1. Mapreduce task 输出数据特点:顺序写。 2. Mapreduce task 输入数据特点:顺序读。 3. 通常来讲一个 task 有一个输入,一个输出,平均每个节点有 8-16 个 task。对于 datanode 来讲,并发 client 相对固定,而且数量较小。 4. Mapreduce task 可以在任意节点运行。 HBase 对 HDFS 需求包括以下几点: 1. 随机读。对应于 HBase 中 get 操作。 2. Append & flush。Sync 操作的支持,需要保证 HLog 可以被可靠存储。并且在语 义上保证: a) 对文件的 append 不影响之前已经 flush 的数据。如果 append 失败,其他 reader 能够访问 append 之前 flush(或者 close)的数据。 b) flush 可确保数据被持久化存储到 hdfs。 3. Client 容错。Client 容错是说对于 DFSClient 进行容错处理(该 DFSClient 对应于 HBase 中的 region server 和 HMaster) ,在语义上保证 2 点: a) 控制 DFSClient 对上层应用 (即:HBase) 抛出异常, 并在 DFSClient 层进行 fail over 处理 b) 如果遇到致命错误,需要向 HBase 抛出异常,则需要 HBase 对应节点进行 出错处理,避免由于个别 exception,导致 HBase 集群不可用的情况。([注] 致命错误: 会造成 region server down 机, 并导致 region 在其他 region server 上加载) 需求 MR HBase 大规模存储 √ √ 系统容错 √ √ 顺序写 √ √ -3-
    • 文档名称:HBase 使用 hadoop 特点分析文档 顺序读 √ √ 随机读 - √ client 容错 - √ Append & flush - √2. HBase 需求分析2.1 随机读 本章我们将分为以下几个主题来展开讨论,目标是分析可能影响延迟的因素,结合当前实现方式,明确其优缺点。由于 HBase 当前写入模式采取异步写的模式,写入操作会先写入 memstore,当 memstore 达到一定阈值时进行 flush,写入延迟不大,因此本文档中暂不讨论写过程。2.1.1 数据发送接收 本节我们主要关注的是数据的发送与读取,对于大规模顺序读写(类 mapreduce 应用) ,预取数据会节省大量的网络交互。 但是对于 HBase 这种随机读/顺序读操作为主的应用而言。预读机制有可能会造成巨大的资源浪费,并有可能影响操作的实时性。 当前实现中为了对大规模顺序读性能进行优化,每次读块的时候,datanode 会将当前偏移量到块结束的全部数据发送给 DFSClient。 多余的数据会存放在 datanode 的 tcp send queue和 DFSClient 的 tcp receive queue 中,当连接数过多的时候, 有可能造成 DFSClient (即: regionserver)的 socket OOM。但是这种设计对于连接数较少,大规模顺序读写为主的 mapreduce应用是有很大好处的,大量的读操作实际并不需要进行网络通信,只需从本地的 buffer 中取数据即可。但是对于随机读操作,该实现方式将会造成大量多余数据的传输。严重影响每次操作的延迟。因此,我们有必要更精细的控制 datanode 对 DFSClient 的数据发送。修改的时候需要注意以下几点: a) 尽量不改变现有 HBase 和 HDFS api 接口 b) datanode 是否需要多发数据,依赖于 client 端的操作模式(顺序读或者随机读) ,所 以是否需要多发数据应通过 client 设置。 ★★2.1.2 连接管理HDFS 中使用的连接包括 2 种,一种是 RPC 调用,另一种是 socket 连接。1. RPC 分析 当前实现中,rpc client 使用 rpc 通常有以下 2 种方式。 a) RPC.waitforProxy 该调用主要用于 datanode 访问 namenode 时(和 secondary namenode 访问 namenode 时) 。它封装了 getProxy,与 getProxy 不同的是,它考虑了 namenode 没 有 启 动 , 或 者 namenode 忙 的 情 况 , catch 住 了 ConnectException , SocketTimeoutException,并进行了无限重试(重试上限为 Long.MAX) b) RPC.getProxy -4-
    • 文档名称:HBase 使用 hadoop 特点分析文档 该调用主要用于 client 连接 datanode 和 client 连接 namenode 的时候。 后面我们会 做详细讨论。 此外当系统 close 或应用结束时,rpc 通信组件中的一些资源需要显式回收。这个操 作是在 RPC.stopProxy 中完成。这个操作被封装到 FileSystem 的 close()操作中。 Rpc client 端连接管理中,我们主要关注连接数和重试机制造成的延时。连接数有可 能会对系统稳定性造成影响,而不恰当的重试机制有可能会造成过多的延迟。 (1) Rpc 建立连接阶段 在建立连接的时候,当前实现中,新建 socket 连接会设置以下几个参数: a) tcpNoDelay,通过 ipc.client.tcpnodelay 设置, 默认为 false b) socket timeout,通过 ipc.ping.interval 设置, 默认为 1 分钟 c) socket connect() 通过 NetUtils.connect 设置超时,为 20 s 如果连接失败会进行重试, a) 当遇到 SocketTimeoutException 的时候,会 close 掉之前的连接(如果有的话), sleep 1 秒,然后进行重试。对于 SocketTimeoutException 的最大重试次数为 45 b) 当遇到其他 IOException 的时候,会 close 掉之前的连接(如果有的话), sleep 1 秒 , 然 后 进 行 重 试 。 对 于 其 他 IOException 的 最 大 重 试 次 数 通 过 ipc.client.connect.max.retries 进行设置, 默认为 10。 由上可见,对于 rpc 连接对应的机器,最差情况下,会有 (20 + 1) * (45 + 10) = 1155 s = 19.25 min 的时间花在 rpc 的新建连接上。如果当时对应机器恰好网络繁忙,则有可 能造成一个 rpc 的延迟超高。 建议: 可以参考 HADOOP-6889 的思想, 引入 rpc timeout。对于延迟 敏感的应用 (比 如:HBase) ,过多的重试次数,有可能会造成响应时间的浪费。 (2) Rpc 执行阶段 Rpc client 中最重要的数据结构是 Connection id 到 Connection 对象的 hashmap。其 中 Connection id 包含了 remote address, port 等信息, Connection 对象包含了 socket 而 和由 socket 建立的输入/输出流。 Rpc client 使用的是短连接,每次 rpc call 会新建一个 socket 连接,在收到 rpc server 响应的时候关闭连接。rpc 接受响应是通过从 PingInputStream 中读取响应数据来实现, PingInputStream 在 读 操 作 中 会 捕 捉 SocketTimeoutException, 当 出 现 SocketTimeoutException 的时候,ping 远程机器。如果 ping 不通 rpc server,则 close 掉 连接,否则重新从 socket 中读取数据。重复以上步骤,直到正常读出数据为止。 对于 client 或者 datanode 连接 namenode 的时候,如果 namenode 暂时无法访问, 则集群命名空间暂时不可用,client 有必要一直重试,直到 namenode 可访问为止。至 于 client 会通过 rpc 连接 datanode,只有当 DFSClient 写数据失败,进行 block recovery 的时候才会发生。这种情况下,不断重试也是合理的。 server 端一共有 3 个线程,handler,listener,responser。listener 中用了 select()处 理 client 端的请求。当 listener 收到一个请求后,accept 该 client 连接,并将该连接注册 到 read key。在 read 中将数据放入到 call queue 队列中。而 handler 线程则不停的从 callQueue 中取出 Call 对象执行。处理完成后,调用 responder.doRespond(),将该次 rpc 的应答放到 responseQueue 中,由 responser 线程的主循环发送应答到 client 端。 综上,我们可以看到在 RPC 框架中,RPC 调用采用短连接的方式,因此不会由于过 多连接导致系统稳定性问题。 RPC 的 fail over 处理方面可以通过以下方式进行优化:在 RPC 连接建立的时候,可 以通过修改 SocketTimeoutException 的重试次数和 ipc.client.connect.max.retries 来调优打 -5-
    • 文档名称:HBase 使用 hadoop 特点分析文档 开连接所用时间开销。★ [注]:该优化对于系统空闲状态时,无优化效果。2. Socket(由于当前版本 RPC 也是基于 socket 实现,这里我们特指非 RPC 的 socket 应用) DFSClient 使用 Socket 主要分为 2 个场景,读和写。 读操作时连接的建立包括 2 个时机,调用 read() 接口和 pread() 接口。 当使用 read() 接口时,连接的建立有 2 个入口。 a) blockSeekTo()的时候, 会将之前 DFSInputStream 已经持有的 socket 关闭。 然后 选择合适的 datanode, 建立连接。 如果 blockSeekTo 的 datanode 与之前 datanode 相同,则连接建立销毁的时间开销会影响单次操作的延迟。★ b) 调用 readBuffer 进行实际读数据的时候,如果发生 IOException 异常,(比如: 网络超时), 则会通过 blockSeekTo()关闭连接,建立连接。如果此时 DFSClient 同 datanode 之间网络不稳定,造成瞬断的情况,有可能造成无谓的重试。对 单次读操作的延迟会有影响。 ★ 当使用 pread()接口时, 如果需要的 block 信息没有被预取, 则会 RPC 调用 namenode 的 getBlockLocation()方法获取块的位置信息。 然后对每一个需要读的块重复以下几步操 作: a) 创建 socket 连接 b) 进行数据传输 c) 当数据传输完毕,关闭 socket 连接 写操作时,DFSClient 仅当分配一个新 block 时会调用 createBlockOutputStream()建立 一条到第一个 datanode 的 socket 连接。 该连接设置了连接超时和 socket 超时均为 1 分零 9 秒。 (3000 * nodes.length + dfs.socket.timeout。默认 nodes.length 为 3, dfs.socket.timeout 为 1 分钟) ,socket send buffer 为 128K。该连接仅当主动 close 文件和创建连接出错时, 会被关闭。 在 HBase 应用中,写文件主要有 2 个时机,mem store flush 和写 HLog。 Mem store flush 时,会新建一个 HFile,然后将 mem store 中的内容写入 HFile,完成 flush 后,将文件 close 掉,因此不会造成过多连接。 创建 region 的时候会新建一个日志文件,DFSClient 保持一条到 datanode 的连接。 RollWriter()调用时会 close 掉该文件(close 文件操作中会 close 掉 DFSClient 到 datanode 的连接)Rollwriter 有 2 个触发时机, region 新建的时候 。 (1) (HMaster 启动或者 create table 的时候) ,会 new HLog 对象,此时会调用 roll writer,close 掉对应连接。(2) 每小时会进 行一次日志滚动,这时对应的日志文件会被 close 掉。 每一个 region server 到 datanode 的连接数上限为该 region server 拥有的 region 数。 且每小时日志滚动时会将对应连接 close 掉。 因此, 在写操作时不会造成连接数过多的问 题。2.1.3 连接重用 当前 HDFS 实现中,每个 DFSClient 同 datanode 之间维护一个独立的连接,通过该连接进行交互通信,在不同 DFSClient 之间连接不进行共享。在 HBase 中,单个 region server 在scan 的时候, 有可能会打开很多文件 (文件数依赖于 scan 的 region 数和每个 region 的 storefile 数,此时连接的数量是应用相关的) 。作为平台,有必要在 HDFS 进行连接重用。★★ 相关 patch : HBASE-2492, HDFS-9412.1.4 本地文件操作 主要针对 datanode 中 meta 文件和 block 的文件的处理。 -6-
    • 文档名称:HBase 使用 hadoop 特点分析文档 在 HDFS 读操作中,每次读操作都会 new 一个 BlockSender 对象,在此对象中打开 block 和 meta 文件,读完一个块的时候,关闭这两个文件。block 读取的策略是从当前 offset 到块的结束顺序读完全部内容, 并发回给 DFSClient。每次读文件的大小为 64K (如 果 offset 到块结尾不足 64k,则为 block 长度 - 当前 offset) 读的过程中,每 。 io.bytes.per.checksum (默认为 512B) ,进行一次 checksum 校验。 当前 datanode 实现方式造成性能损耗的地方包括以下几处: 1. 每读一个块都需要重新打开,关闭 block 和 meta 文件。 建议: 建立 fd 池,缓存 fd。减少重复打开关闭文件的开销。 ★★ 相关 patch: HDFS-1323 2. 循环顺序读,且每次读 64k 的方式不适合随机读的方式。 建议:将 datanode 增加无预读模式或者少量预读(随机读操作有可能会取某个 row 的多个 version, 多个 version 之间的访问为顺序读,这种情况少量预读有利于提高 读效率) ,以减少额外的数据传输开销。 ★★★ 3. 每 512 个字节进行一次 checksum 校验的方式,会浪费大量 cpu 时间。 建议:io.bytes.per.checksum 约等于一行的长度。由于 HBase 中保证行的原子性。 Checksum 可以基于行(对于一行做一次 checksum)★2.1.5 Read/pread 使用 Read/pread 基本流程请见 6.2。Pread: Pread(是 position read 的简称)是指 int read(long position, byte[] buffer, int offset, intlength)接口。在语义上该函数相当于 seek + read。 该函数根据要读的数据的 offset 和 readLen,计算出要读的 blockRange。getBlockRange()这个函数中要判断要读的 blocks 是否在 locatedBlocks 中,如果不在,要向 namenode 查询。 然后再针对获得的 blockRange 中每个 block 读取数据,选取 datanode,创建连接,对每个 block 重新生成一个 BlockReader。 Seek+read: 此 read 为 int read(byte[] buffer, int offset, int length)接口。默认情况下该函数顺序读,当需要随机读的时候需要结合 seek()使用。 在 new BlockReader 的时候,read 会把当前位置到 block 结束的长度传给 datanode,这样 DataNode 就可以 read ahead,这样由于 tcp buffer 作用可以加快连续读的性能。 如果 seek 的时候 seek 的目的位置和当前位置在同一个 block 就只需直接读取。如果不在,则需调用函数 blockSeekTo()建立到目的 datanode 的连接。 Pread 和 seek+read 主要不同的地方在于 getBlockRange(用于 pread)和 getBlockAt(用于 read) Pread 中 getBlockRange 是取从当前 position 到 buffer 结束的块位置信息。read 中 。的 getBlockAt 是取当前 position 对应的块信息。所以,getBlockRange() 同 getBlockAt() 相比会获取更多的 block location 信息。对于当前 HBase 应用来讲,buffer 的大小约为 64K(一个HBase block 的大小) ,所以 getBlockRange()至多比 getBlockAt()多获取 1 个块的信息。 如果 buffer 刚好跨过 2 个 HDFS block, pread 需要获取 2 个块的位置信息。 则 此外,pread中每次调用都需要调用 getBlockRange()对 cache 中的 block location 信息进行查找。而 read仅当跨块的时候,才会调用 getBlockAt()在 cache 中寻找 block location 信息。 综上,read()同 pread()相比节省了 cache 查找的开销和 getBlockRange()多取块的开销。但由于这两项均为内存操作(pread 至多比 read 多一次 getBlockLocation() RPC 调用) ,性能优化空间很小,可暂不优化。 -7-
    • 文档名称:HBase 使用 hadoop 特点分析文档 相关 patch : HBASE-1505, HBASE-21802.1.6 HDFS 块信息预取 分析: 评估 dfs.read.prefetch.size 大小对于延迟的影响 当前 hdfs 会在文件 open 的时候,取一定数量块的位置信息(默认取 10 块) 。 预取块的特性有利于类 mapreduce 的应用(大规模顺序读写) ,当大规模顺序读写 的时候,可以有效减少对 namenode 的 getBlockLocations()调用。但是对于大量随机读操 作的时候,预取可能会造成对 namenode 的额外压力。 建议: HBase 在使用 DFSClient 的时候,根据应用随机程度设置预取块数。2.1.7 锁控制 1.Datanode 中锁机制的分析 Datanode 中的操作大都需要通过 FSDataset 完成,FSDataset 中的操作会加一把大锁。每个操作都会锁住整个 FSDataset 对象。定性的,我们可以考虑使用读写锁代替互斥锁。以减少同步的开销。★ 相关 patch : HDFS-11482.1.8 社区相关动向 在完成了之前的分析, 我们发现社区中有很多聪明的人们在和我们做同样的工作。 我们可以通过学习和分析相关的 issue 取其精华。针对 2.1.4, HDFS-1323 将本地对 block 文件和 meta 文件的访问池化,避免重复 open file HDFS-1034 Enhance datanode to read data and checksum file in parallel针对 2.1.3, HDFS-380 在 DFSClient pread() 时建立长连接,以提高 hdfs 随机读的性能 HDFS-1325 设置读 timeout,避免 idle 连接长期占用资源针对 2.1.2,HADOOP-6889 增加 rpc timeout,修改 rpc 的重试机制针对 2.1.7,HDFS-1148 Convert FSDataset to ReadWriteLock其他: HDFS-1214 hdfs client metadata cache HDFS-516 Low Latency distributed reads测试相关: HADOOP-6637 Benchmark overhead of RPC session establishment HDFS-236 Random read benchmark for DFS迁移相关 HADOOP-6904, HDFS-1335 使不同版本 DFSClient 和 Namenode 可以互相访问。2.2 Append & flush 根据之前的调研,我们整理了有可能需要 append 和 flush 功能的相关应用场景。主要包括:(注:这里说的 flush 是指通用文件系统语义的 flush 操作,相当于 hdfs 中的 sync) 1. HLog 写入 2. Mem store flush 3. Compaction -8-
    • 文档名称:HBase 使用 hadoop 特点分析文档 此外, 需要写文件的场景还包括日志分割。 但是日志分割的场景主要用于 HMaster 启动时,使用一次,然后关闭文件。不增加 flush 接口,也不会造成数据丢失。但是按照当前日志分割的流程: 1. 打开对应日志文件,将其中内容读入到 queue 中。 2. 然后将对应日志文件删除 3. 将 queue 中的数据分发到不同的 HLog 文件中,然后将 HLog close 掉 在 3 完成之间,就会将之前的日志文件删除,所以有可能造成日志数据丢失,需要修改HBase 使用方式。★★★ 下面我们分析下以上 3 个相关应用场景中,使用当前版本 hdfs 可能潜在的风险:2.2.1HLog 写入 写入 HLog 的场景包括 Delete(), incrementColumnValue(), put()。HLog 的写入就是append 到 sequence file 一个 key-value 对,该操作本身并不保证数据安全性。当前 HBase 为了防止日志数据丢失,引入了日志的滚动机制。 日志滚动的目的主要是保证日志滚动之前的日志可以被可靠存储,删除多余的日志文件。每个 region server 中有一个 LogRoller 线程,每 hbase.regionserver.logroll.period 进行一次日志滚动。 (默认 1 小时滚动一次) 。日志滚动所做的事情就是 close()掉之前的日志,并删除已经 flush 的 log 文件,重新 create 一个 HLog。此外,日志滚动时,会 schedule flush,异步的将 mem store 中的数据 flush 到 HFile。 所以, 我们可以认为, 在日志滚动的 1 小时间隔内, HLog 的数据是不安全的。 如果 regionserver down 机,会导致 HLog 数据丢失。需求功能: (请参见 HADOOP-1700)★★★1. 单 Writer 和多个 Reader 可以并发访问。2. Writer 调用 flush 之后,保证数据被持久化。3. Writer 频繁 flush 不会对 HDFS 造成过高负载。4. Reader 可以读取到其 open 之前 flush 的数据。5. HDFS 不偷偷丢数据。7. append 之后,之前已经 flush(或者 close)的数据不会丢。2.2.2 Mem store flush 过程 在 region server 中有单独一个线程处理 mem store 的 flush。 操作将数据塞到 mem store Put中,当 mem store 的大小满足一定大小(通过 hbase.hregion.memstore.flush.size 配置,默认为 64M)将数据刷到 hdfs 上。 每次 Mem flush 操作将 memstore 中的数据写入到 StoreFile 中。对于每个 store,flush 结束会立即 close 掉对应的 store file,以保证数据安全。 当之前的 StoreFile 被 close 之后, 会重新打开一个新的 store file, 并从中读取 index 信息。所以当 mem flush 结束时,region server 会拥有一条到 datanode 的 socket 长连接。 在 flush 结束的时候,在 HLog 中写入一条 FLUSHCACHE-COMPLETE 记录,只是 append一个 key-value 到 HLog 中,当前 HDFS 实现并不保证这条记录被持久化。 由上述过程,我们可以认为在每次 flush mem store 之后,数据是安全的。 在 flush memstore 过程中, 如果 region server down 机,会导致未 flush 的 store 和 mem store中的数据丢失。此类错误在其他 region server 接管该 region,replay HLog 的时候,可以修复丢失数据。 此外, memstore flush 之前, 在 如果 region server 挂掉, 会导致 mem store 中的数据丢失。但是如果 HLog 已经被持久化,则当 region server 重新启动时,可以通过 replay HLog 完成数据恢复。 -9-
    • 文档名称:HBase 使用 hadoop 特点分析文档2.3 Client 容错 在 mapreduce 计算框架中,如果一个 task 计算失败,框架会将 task 重新启动,所以 task失效不是个很严重的问题。而对于 HBase 而言,region server 作为 client,如果其失效退出,将导致某些 region 不可访问,即使其他 region server 重新加载该 region,也会造成一定时间的系统 down time。 我们需要做两方面工作: 1. 优化重试机制,避免一个节点失效导致多次重试失败的情况。 (比如:HDFS-630) ★★★ 2. 重新设计 DFSClient 对 Exception 处理的机制。当 DFSClient 重试了 n 次后,当前实 现会丢出一个 Exception。★★★★ 相关 patch:HDFS-127 HDFS-927 3. 总结 本文档中对 HBase 使用 hdfs 相关功能的需求进行了定性的分析汇总。 本文档从随机读,数据安全,client 容错三方面分析了 HBase 对 HDFS 使用的特性,并对相关功能点进行详细分析。第二章中列出了需要解决的相关问题,并以红星标出。红星越多则越重要。 在此我们按照优先级列出当前版本 hdfs 需要改进的地方。 功能: 1. Sync() 功能支持(sequence file) Sync 操作需要实现以下语义: Sequence file 提供 sync() 接口,实现 flush 的语义。 2. Datanode 多发数据问题 当前 client 的实现,如果 client 请求一个字节,datanode 会将该字节 offset 到 block 结尾的全部数据发送给 client。由于 HBase 需要同时满足顺序读和随机读的需求, 需要通过 client 配置,决定是否多发数据。 稳定性: 1. Review DFSClient 异常处理机制 (HDFS-127 HDFS-927) 在 DFSClient 层保证处理不致命的错误。将致命错误抛出。 ([注] 致命错误:会造成 region server 进程退出,并导致该 region 在其他 region server 上加载。会存在一段时间的 down time。) 2. Datanode 坏盘导致 region server 退出的问题 (HDFS-630)。 3. Client 到 datanode 连接数过多问题 解决方案分为 3 层: a) HBase 清理其不需要的资源。包括 close()不需要的文件。 b) 实现 DFSClient 到 datanode 的连接重用,包括读写。 c) DFSClient 对未关闭的连接进行回收。避免影响其他应用。 性能: 1. 增加 Block sender 本地读 fd 池,避免每次读操作都打开/关闭本地文件。 2. 合并 meta 和 block 文件,以减少随机读 2 个本地文件造成的磁盘寻道开销。 3. 文件 open 的时候,加大预取块位置信息的大小。 4. 如果不改变 datanode 的时候,blockSeekTo 重用之前已有连接。 5. 改变 io.bytes.per.checksum 减少 checksum 时间花费。 - 10 -
    • 文档名称:HBase 使用 hadoop 特点分析文档 6. 在 FSDataset 中使用读写锁。 4. 参考文档 [1] HBase and HDFS by Todd Lipcon of Cloudera http://wiki.apache.org/hadoop/HBase/HBasePresentations?action=AttachFile&do=view &target=HUG9_HBaseAndHDFS_ToddLipcon_Cloudera.pdf [2] http://wiki.apache.org/hadoop/Hbase 5. 附录 6.1 相关 jira HDFS-1323 将本地对 block 文件和 meta 文件的访问池化,避免重复 open file HDFS-1034 Enhance datanode to read data and checksum file in parallel, HDFS-380 在 DFSClient pread() 时建立长连接,以提高 hdfs 随机读的性能 HDFS-1325 设置读 timeout,避免 idle 连接长期占用资源 HADOOP-6889 增加 rpc timeout,修改 rpc 的重试机制 HDFS-1148 Convert FSDataset to ReadWriteLock HDFS-1214 hdfs client metadata cache HDFS-516 Low Latency distributed reads HADOOP-6637 Benchmark overhead of RPC session establishment HDFS-236 Random read benchmark for DFS HADOOP-6904,HDFS-1335 使不同版本 DFSClient 和 Namenode 可以互相访问 - 11 -