`
lc_koven
  • 浏览: 353558 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hdfs上的append测试

阅读更多
  hbase在写入数据之前会先写hlog,hlog目前是sequencefile格式,采用append的方式往里追加数据。之前团队的同学测试关闭hlog会一定程序上提升写hbase的稳定性。而在我之前的想象中,hlog的写入速度应该是稳定的。于是写了个append程序专门测试hdfs的append性能。

  代码如下:
  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可以影响这个不稳定因素。

  • 大小: 98.4 KB
  • 大小: 88.8 KB
  • 大小: 90.1 KB
  • 大小: 100.2 KB
分享到:
评论
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的日志进行处理。

非常感谢。我查看了代码。正是因为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的日志进行处理。

非常感谢。我查看了代码。正是因为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的日志进行处理。

相关推荐

    HDFS性能压测工具浅析

    SliveTest是另一种专门用于测试Namenode性能的工具,它通过大量map任务模拟各种RPC操作,如ls(列出文件和目录)、append(追加写文件)、create(创建文件)、delete(删除文件)、mkdir(创建目录)、rename(重命名文件)和...

    webhdfs-java-client-master

    综上所述,"webhdfs-java-client-master"是一个全面的WebHDFS Java客户端实现,涵盖了文件操作、安全认证、异步处理、错误处理等多个方面,是开发与Hadoop HDFS交互的Java应用的重要工具。通过深入研究该项目,...

    python存数据到hdfs.docx

    3. **实际应用**:通过循环调用`write2hdfs`函数来测试其功能。 ```python for i in range(100): write2hdfs("this is test!\n") ``` #### 四、总结 本文档详细介绍了如何使用Python操作HDFS,包括基本的连接...

    HDFS的透明压缩存储.pdf

    3. **特殊操作兼容**:针对append和随机读取等操作,设计专门的机制,如索引文件(Indexfile),以保持数据的完整性和访问效率。 #### 如何规避风险 为了确保数据安全和系统稳定性,透明压缩技术采取了以下几项...

    eclipse的实验操作,Hadoop实验操作

    5. 编译并运行程序,观察HDFS上的文件变化。 6. 准备对代码进行解释和演示,以满足教师的评分要求。 通过这个实验,学生将获得使用Hadoop HDFS API的实际经验,这对于理解和开发分布式系统至关重要。同时,这也强化...

    大数据开发中的Sqoop学习笔记(自己整理版).pdf

    这里 `<hostname>` 是数据库服务器地址,`<port>` 是数据库监听端口,`<database>` 是数据库名,`<tablename>` 是表名,`<username>` 和 `<password>` 是数据库连接的凭证,`<hdfs_path>` 指定HDFS上的目标存储位置...

    Hadoop实战

    - 在单机模式的基础上,进一步配置`hdfs-site.xml`和`mapred-site.xml`。 - 启动Hadoop服务,可以通过命令`start-dfs.sh`和`start-yarn.sh`启动HDFS和YARN服务。 4. **完全分布式模式安装**: - 这种模式下,...

    spark提交jdbc到pgsql测试代码

    本示例中的"spark提交jdbc到pgsql测试代码"旨在演示如何利用Python编程语言和Spark的SQL接口来实现这一功能。我们将深入探讨相关知识点。 首先,`spark_jdbc_pgsql.py`是主要的Python脚本文件,它包含了一个使用...

    08 安装配置hbase0.94.9

    - `dfs.support.append` 设置为 `true` 支持HDFS的日志追加功能。 4. **配置regionservers**: - 在 `conf/regionservers` 文件中,添加所有参与HBase集群的从节点(Slave)IP地址。 5. **分发HBase到其他节点**...

    hadoop平台下的数据导入导出工具sqoop

    - **测试连接**:使用`sqoop list-databases --connect jdbc:mysql://localhost:3306 --username root --password root`命令测试与数据库的连接是否成功。 #### 四、数据导入操作 - **基本导入命令**:`sqoop ...

    HADOOP的问题和下一代解决方案

    HDFS的文件访问方式是追加模式(Append-only),这限制了随机读写能力,对于需要频繁更新的应用来说,这是一个大问题。下游项目如HBase通过实现墓碑化和合并功能来解决这个问题,但在高负载下性能会受影响。WOTUNG的...

    hadoop单机版

    - `hdfs-site.xml`: 设置NameNode和DataNode的数据存储路径(`dfs.name.dir`和`dfs.data.dir`),以及副本数量(`dfs.replication`)和是否支持追加写入(`dfs.support.append`)。 - `core-site.xml`: 定义临时目录(`...

    Apache_Mahout_Cookbook(高清版)

    3. **测试模型**:使用`testclassifier`命令测试模型的准确性。 **实例代码(伪代码):** ```bash # 训练朴素贝叶斯分类器 mahout trainclassifier -i /path/to/training -o /path/to/output -type naivebayes ```...

    Sqoop学习文档(1){Sqoop基本概念、Sqoop的安装配置}.docx

    5. **测试连接**:使用 `bin/sqoop list-databases --connect jdbc:mysql://master:3306/ --username root --password root` 命令,检查 Sqoop 是否能成功连接到 MySQL 数据库,并列出所有数据库。 ### Sqoop ...

    Sqoop-linux.zip

    2. **增量导入**: `sqoop import --incremental append --check-column id --last-value 100 --connect ...` 3. **导出数据**: `sqoop export --connect ... --table new_employees --export-dir /user/hadoop/...

    IT运维中间件全面学习文档

    【IT运维中间件全面学习文档】涵盖了众多中间件技术,如MySQL、Redis、Tomcat、Nginx、Zabbix、Ansible、Docker、LVS+Keepalived、JDK、Kafka、MongoDB、Zookeeper、Kubernetes(K8s)、ELK、HBase、HDFS、Elastic...

    Doug Cutting:Apache Hadoop和大数据平台

    针对Hadoop生态系统的新发展,文章提到了Apache Hadoop 0.20.205版本的推出,该版本包含了附加的特性(append)和安全性增强。随后,0.23版本的到来预期将带来HDFS性能的提升、可扩展性(通过联邦机制实现)和可用性...

    Flume1.7.0用户指南

    4. **水槽(Sink)**:水槽负责从通道中取出事件,并将其写入外部存储(如HDFS)或传递给下一个Flume代理。水槽使用事务机制确保事件的可靠传输。 **可靠性机制:** Flume 使用事务来保证端到端的数据可靠性。事件在...

Global site tag (gtag.js) - Google Analytics