- 浏览: 349968 次
- 性别:
- 来自: 杭州
最新评论
-
penkee:
为何我启动 zookKeeper bookie 10 不能创 ...
bookkeeper安装及测试体验 -
Golden-jin:
1楼也好时髦呀
bookkeeper简单分析 -
xGss2000:
要是减少到300个 region,block就0.04s了。话 ...
多region下的hbase写入问题 -
brandom520:
请问lz,我从hbase0.94版本上的数据导入到0.96.1 ...
在不同版本hdfs集群之间转移数据 -
huanghaifeng1990:
您好,我想请问一下,我执行了会发生OOM溢出的Deflater ...
perftools查看堆外内存并解决hbase内存溢出
hbase在写入数据之前会先写hlog,hlog目前是sequencefile格式,采用append的方式往里追加数据。之前团队的同学测试关闭hlog会一定程序上提升写hbase的稳定性。而在我之前的想象中,hlog的写入速度应该是稳定的。于是写了个append程序专门测试hdfs的append性能。
代码如下:
可以看到,append的过程分两步:先write,然后执行sync(),如果不执行sync,理论上会存在丢失数据的风险。
由于不清楚是sync不稳定,还是write本身不稳定。所以对打开和关闭sync均做了测试。
图1:打开sync功能
图2:关闭sync功能
从图1和图2的结果可以看到打开和关闭sync操作同样不稳定,因此可以判断不稳定因素主要出在write本身上。观察write函数,发现在创建它时需要一个blocksize参数,我的代码中一开始是设置的1MB。于是修改为32MB,绝大部分毛刺消失了。进一步修改为64MB,性能有进一步的提升。如下图
图3:设为32MB
图4:设为64MB
这个参数是决定多大的文件在hdfs上可读的。传统的hdfs写文件要满足dfs.block.size大小(默认64MB)才可读。但是在append模式下这个可读的大小是由这里的blocksize决定的。默认值在本地文件系统下由fs.local.block.size决定,在hdfs文件系统下仍由dfs.block.size决定。如果设为1MB,那么hdfs上每append 1MB的大小,就可以读到了。当写入的数据达到这个大小时,会触发namenode执行fsync()操作。而在日志中观察到,每次发生这个操作时,都会造成读响应的变慢。
fsync()操作的内容比较多,没有仔细看源码,知道原理的同学联系我吧。
从附图中可以看到,append_block_size从1MB提高到32MB,再提高到64MB,都会有一定程序的稳定性改善。再提高就没有用了,因为hlog和dfs.block.size的默认大小都是64MB。不过hbase每1s会强制刷新执行一次fsync,所以会看到hbase在打开日志的情况下每1s会有一次小的响应时间波动
结论有两点:
1 hdfs的append的确是有一点不稳定的
2 修改fs.local.block.size或dfs.block.size可以影响这个不稳定因素。
自己写的,这是excel中的图,很土吧:)
非常感谢。我查看了代码。正是因为fsync的这些操作导致append的速度是不平稳的。另外更正一下,append下fsync的间隔在hdfs文件系统上仍然是由dfs.block.size决定的,另外hlog每1s也会强制执行一次fsync操作
是的,一个块只会执行一次fsync操作,用了一个boolean变量来判断是否需要执行fsync,当向NN申请了一个块时,该变量为true,则当flush时会执行fsync操作,之后会将其改为false,直到下一个新申请的块将其设为true后,才会再次执行该操作。
非常感谢。我查看了代码。正是因为fsync的这些操作导致append的速度是不平稳的。另外更正一下,append下fsync的间隔在hdfs文件系统上仍然是由dfs.block.size决定的,另外hlog每1s也会强制执行一次fsync操作
代码如下:
FSDataOutputStream stm = fs.create(path, true, conf.getInt("io.file.buffer.size", 4096), (short)3, blocksize); String a = make(1000); stm.write(a.getBytes()); stm.sync();
可以看到,append的过程分两步:先write,然后执行sync(),如果不执行sync,理论上会存在丢失数据的风险。
由于不清楚是sync不稳定,还是write本身不稳定。所以对打开和关闭sync均做了测试。
图1:打开sync功能
图2:关闭sync功能
从图1和图2的结果可以看到打开和关闭sync操作同样不稳定,因此可以判断不稳定因素主要出在write本身上。观察write函数,发现在创建它时需要一个blocksize参数,我的代码中一开始是设置的1MB。于是修改为32MB,绝大部分毛刺消失了。进一步修改为64MB,性能有进一步的提升。如下图
图3:设为32MB
图4:设为64MB
这个参数是决定多大的文件在hdfs上可读的。传统的hdfs写文件要满足dfs.block.size大小(默认64MB)才可读。但是在append模式下这个可读的大小是由这里的blocksize决定的。默认值在本地文件系统下由fs.local.block.size决定,在hdfs文件系统下仍由dfs.block.size决定。如果设为1MB,那么hdfs上每append 1MB的大小,就可以读到了。当写入的数据达到这个大小时,会触发namenode执行fsync()操作。而在日志中观察到,每次发生这个操作时,都会造成读响应的变慢。
fsync()操作的内容比较多,没有仔细看源码,知道原理的同学联系我吧。
从附图中可以看到,append_block_size从1MB提高到32MB,再提高到64MB,都会有一定程序的稳定性改善。再提高就没有用了,因为hlog和dfs.block.size的默认大小都是64MB。不过hbase每1s会强制刷新执行一次fsync,所以会看到hbase在打开日志的情况下每1s会有一次小的响应时间波动
结论有两点:
1 hdfs的append的确是有一点不稳定的
2 修改fs.local.block.size或dfs.block.size可以影响这个不稳定因素。
评论
6 楼
Faeries
2013-03-21
不错,hadoop0.20.2之后的版本 直接支持sync()?
5 楼
lc_koven
2011-11-28
hf81970 写道
能问下您用的测试工具是什么吗?这些图都是自动生成的吗?
自己写的,这是excel中的图,很土吧:)
4 楼
hf81970
2011-11-28
能问下您用的测试工具是什么吗?这些图都是自动生成的吗?
3 楼
lance_123
2011-05-12
lc_koven 写道
lance_123 写道
fsync()操作就是对当前的文件记录一下日志信息,包括当前的操作标记位op_add,文件的相关属性,以及文件的当前块信息。
代码如下:
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
DeprecatedUTF8 nameReplicationPair[] = new DeprecatedUTF8[] {
new DeprecatedUTF8(path),
FSEditLog.toLogReplication(newNode.getReplication()),
FSEditLog.toLogLong(newNode.getModificationTime()),
FSEditLog.toLogLong(newNode.getAccessTime()),
FSEditLog.toLogLong(newNode.getPreferredBlockSize())};
logEdit(OP_ADD,
new ArrayWritable(DeprecatedUTF8.class, nameReplicationPair),
new ArrayWritable(Block.class, newNode.getBlocks()),
newNode.getPermissionStatus(),
new DeprecatedUTF8(newNode.getClientName()),
new DeprecatedUTF8(newNode.getClientMachine()));
}
作用就是当在写操作失败后,NN会根据日志信息,当操作标记位为op_add,表示失败前正在写操作,于是先启动该数据块的恢复操作,等该文件恢复完后,才会将lease释放掉。
然后回到FSEditLogLoader类中的loadEditRcords()方法有对标记位为op_add的日志进行处理。
代码如下:
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
DeprecatedUTF8 nameReplicationPair[] = new DeprecatedUTF8[] {
new DeprecatedUTF8(path),
FSEditLog.toLogReplication(newNode.getReplication()),
FSEditLog.toLogLong(newNode.getModificationTime()),
FSEditLog.toLogLong(newNode.getAccessTime()),
FSEditLog.toLogLong(newNode.getPreferredBlockSize())};
logEdit(OP_ADD,
new ArrayWritable(DeprecatedUTF8.class, nameReplicationPair),
new ArrayWritable(Block.class, newNode.getBlocks()),
newNode.getPermissionStatus(),
new DeprecatedUTF8(newNode.getClientName()),
new DeprecatedUTF8(newNode.getClientMachine()));
}
作用就是当在写操作失败后,NN会根据日志信息,当操作标记位为op_add,表示失败前正在写操作,于是先启动该数据块的恢复操作,等该文件恢复完后,才会将lease释放掉。
然后回到FSEditLogLoader类中的loadEditRcords()方法有对标记位为op_add的日志进行处理。
非常感谢。我查看了代码。正是因为fsync的这些操作导致append的速度是不平稳的。另外更正一下,append下fsync的间隔在hdfs文件系统上仍然是由dfs.block.size决定的,另外hlog每1s也会强制执行一次fsync操作
是的,一个块只会执行一次fsync操作,用了一个boolean变量来判断是否需要执行fsync,当向NN申请了一个块时,该变量为true,则当flush时会执行fsync操作,之后会将其改为false,直到下一个新申请的块将其设为true后,才会再次执行该操作。
2 楼
lc_koven
2011-05-11
lance_123 写道
fsync()操作就是对当前的文件记录一下日志信息,包括当前的操作标记位op_add,文件的相关属性,以及文件的当前块信息。
代码如下:
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
DeprecatedUTF8 nameReplicationPair[] = new DeprecatedUTF8[] {
new DeprecatedUTF8(path),
FSEditLog.toLogReplication(newNode.getReplication()),
FSEditLog.toLogLong(newNode.getModificationTime()),
FSEditLog.toLogLong(newNode.getAccessTime()),
FSEditLog.toLogLong(newNode.getPreferredBlockSize())};
logEdit(OP_ADD,
new ArrayWritable(DeprecatedUTF8.class, nameReplicationPair),
new ArrayWritable(Block.class, newNode.getBlocks()),
newNode.getPermissionStatus(),
new DeprecatedUTF8(newNode.getClientName()),
new DeprecatedUTF8(newNode.getClientMachine()));
}
作用就是当在写操作失败后,NN会根据日志信息,当操作标记位为op_add,表示失败前正在写操作,于是先启动该数据块的恢复操作,等该文件恢复完后,才会将lease释放掉。
然后回到FSEditLogLoader类中的loadEditRcords()方法有对标记位为op_add的日志进行处理。
代码如下:
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
DeprecatedUTF8 nameReplicationPair[] = new DeprecatedUTF8[] {
new DeprecatedUTF8(path),
FSEditLog.toLogReplication(newNode.getReplication()),
FSEditLog.toLogLong(newNode.getModificationTime()),
FSEditLog.toLogLong(newNode.getAccessTime()),
FSEditLog.toLogLong(newNode.getPreferredBlockSize())};
logEdit(OP_ADD,
new ArrayWritable(DeprecatedUTF8.class, nameReplicationPair),
new ArrayWritable(Block.class, newNode.getBlocks()),
newNode.getPermissionStatus(),
new DeprecatedUTF8(newNode.getClientName()),
new DeprecatedUTF8(newNode.getClientMachine()));
}
作用就是当在写操作失败后,NN会根据日志信息,当操作标记位为op_add,表示失败前正在写操作,于是先启动该数据块的恢复操作,等该文件恢复完后,才会将lease释放掉。
然后回到FSEditLogLoader类中的loadEditRcords()方法有对标记位为op_add的日志进行处理。
非常感谢。我查看了代码。正是因为fsync的这些操作导致append的速度是不平稳的。另外更正一下,append下fsync的间隔在hdfs文件系统上仍然是由dfs.block.size决定的,另外hlog每1s也会强制执行一次fsync操作
1 楼
lance_123
2011-05-08
fsync()操作就是对当前的文件记录一下日志信息,包括当前的操作标记位op_add,文件的相关属性,以及文件的当前块信息。
代码如下:
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
DeprecatedUTF8 nameReplicationPair[] = new DeprecatedUTF8[] {
new DeprecatedUTF8(path),
FSEditLog.toLogReplication(newNode.getReplication()),
FSEditLog.toLogLong(newNode.getModificationTime()),
FSEditLog.toLogLong(newNode.getAccessTime()),
FSEditLog.toLogLong(newNode.getPreferredBlockSize())};
logEdit(OP_ADD,
new ArrayWritable(DeprecatedUTF8.class, nameReplicationPair),
new ArrayWritable(Block.class, newNode.getBlocks()),
newNode.getPermissionStatus(),
new DeprecatedUTF8(newNode.getClientName()),
new DeprecatedUTF8(newNode.getClientMachine()));
}
作用就是当在写操作失败后,NN会根据日志信息,当操作标记位为op_add,表示失败前正在写操作,于是先启动该数据块的恢复操作,等该文件恢复完后,才会将lease释放掉。
然后回到FSEditLogLoader类中的loadEditRcords()方法有对标记位为op_add的日志进行处理。
代码如下:
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
DeprecatedUTF8 nameReplicationPair[] = new DeprecatedUTF8[] {
new DeprecatedUTF8(path),
FSEditLog.toLogReplication(newNode.getReplication()),
FSEditLog.toLogLong(newNode.getModificationTime()),
FSEditLog.toLogLong(newNode.getAccessTime()),
FSEditLog.toLogLong(newNode.getPreferredBlockSize())};
logEdit(OP_ADD,
new ArrayWritable(DeprecatedUTF8.class, nameReplicationPair),
new ArrayWritable(Block.class, newNode.getBlocks()),
newNode.getPermissionStatus(),
new DeprecatedUTF8(newNode.getClientName()),
new DeprecatedUTF8(newNode.getClientMachine()));
}
作用就是当在写操作失败后,NN会根据日志信息,当操作标记位为op_add,表示失败前正在写操作,于是先启动该数据块的恢复操作,等该文件恢复完后,才会将lease释放掉。
然后回到FSEditLogLoader类中的loadEditRcords()方法有对标记位为op_add的日志进行处理。
发表评论
-
lease引发的血案
2011-12-19 23:01 6115今天线上出现了一个故障惊出一身冷汗,经过查明原来是lease引 ... -
hbase写被block住的典型案例分析
2011-11-10 22:32 5881今天一个线上集群出现莫名奇妙不能写入数据的bug,lo ... -
在不同版本hdfs集群之间转移数据
2011-10-26 18:56 7147本文仅供记录一下程序心得: 很多人会有这样一个需求:将 ... -
hbase中的deleteColumn
2011-10-26 16:59 5108Delete类的接口有两个方法:deleteColum ... -
splitlog期间丢失数据的问题
2011-10-18 22:26 3654splitlog是保证在重启或rs挂掉后,恢复hlog ... -
hbase中多次加载root及meta的bug
2011-10-18 22:24 3120执行以下case可以见到root或meta被加载两次: ... -
两次hbase丢失数据的故障及原因分析
2011-10-18 18:12 16590hbase的稳定性是近期社区的重要关注点,毕竟稳定的系 ... -
hbase中regionserver常见的oom原因分析
2011-09-15 10:40 8972首先要清楚reginserver中内存是如何使用的。 ... -
hbase的export与import工具
2011-09-01 08:01 11238hbase提供了导出表的方案,将指定的表导出到HDFS ... -
disable table失败的处理
2011-08-30 20:02 4290相信每一个维护hbase集群的运维人员一定碰到过dis ... -
使用zookeeper管理多个hbase集群
2011-08-16 15:30 18076zookeeper是hbase集群的"协调器 ... -
一次奇异的getRegionInfo异常定位
2011-08-10 19:55 2481今天在线上环境的 ... -
多region下的hbase写入问题
2011-08-10 13:13 9199最近在集群上发现hbase写入性能受到较大下降,测试环 ... -
hbase上应用lucene创建索引及检索
2011-07-21 17:14 11530hbasene(https://github.com/ ... -
hbase-0.90.4的主要更新
2011-07-15 22:15 2771apache邮件列表中提 ... -
hbase中缓存的优先级
2011-06-15 16:30 4083今天同事问到hbase中in-memory属性的作用, ... -
hbase交流记录
2011-06-02 10:34 3491前几天和公司的同事杨传辉(http://www.nosqlno ... -
secondary index for hbase
2011-05-07 23:05 5745最近因为业务需求 ... -
hbase写入性能影响续
2011-04-18 15:28 10551今天发现hbase在写入一张新表时,写入过程中时常会出 ... -
hbase中的缓存的计算与使用
2011-04-13 20:20 8298hbase中的缓存分了两层:memstore和b ...
相关推荐
hadoop HDFS append功能的设计,涉及读写一致性的保证等,对设计类似分布式文件系统有参考意义。
HDFS测试案例v0.3
HDFS 读写性能测试
HDFS并发性能测试文.pdf
Hadoop分布式文件系统(HDFS)运行测试
分布式文件系统(HDFS)的高可靠性主要是由多种策略及机制共同作用实现的。
本文重在探索hdfs分布式文件系统的元数据合并及更新原理。
HDFS具有高容错性,可以部署在通用硬件设备上,适合数据密集型应用,并且提供对数据读写的高吞 吐量。HDFS能 够提供对数据的可扩展访问,通过简单地往集群里添加节点就可以解决大量客户端同时访问的问题。HDFS支持...
hdfs文件的查看 hdfs fs -cat /文件名
从本地上传文件到HDFS上的代码!使用hadoop的API操作,使本地文件的代码上传到HDFS上!!!
flime安装+配置+测试+案例(采集日志至HDFS)+理论+搭建错误解决,超详细flum搭建,一篇带你入门flume,通俗易懂,详细步骤注解!!!
windows平台下的HDFS文件浏览器,就像windows管理器一样管理你的hdfs文件系统。现在官网已经停止更新这款软件。具体配置如下: HDFS配置页面及端口http://master:50070 配置HDFS服务器 配置WebHDFS HDFS Explorer...
本文通过对一些常见场景的测试,重在探索hdfs分布式文件系统的文件读写原理
简单的介绍在HDFS中使用lucene完成索引和搜索的代码实例
hadoop测试(1)---HDFS文件操作 完整测试代码, 相关文章:http://www.cnblogs.com/yinpengxiang/archive/2011/07/03/2096605.html
hdfs 文件的上传,hdfs fs -put /文件名
HDFS测试环境配置文件,稳定运行无异常,分享给大家学习参考用;
人工智能-hdfs
4.3.1 Datanode上数据块副本的状态 335 4.3.2 BlockPoolSlice实现 335 4.3.3 FsVolumeImpl实现 342 4.3.4 FsVolumeList实现 345 4.3.5 FsDatasetImpl实现 348 4.4 BlockPoolManager 375 4.4.1 ...
安装CentOS7-X64,选择带GUI的服务器,非管理结点也可以最小安装+开发。选择带Infiniband 支持,Hdfs高性能稳定性集群搭建