1.dfs.replication属性的一些概念

  • dfs.replication是个client参数,即node level参数,需要在每台datanode上设置。默认为3个副本已经够用了,设置太多也没什么用。
  • Hadoop的备份系数是指每个block在hadoop集群中有几份,系数越高,冗余性越好,占用存储也越多。备份系数在hdfs-site.xml中定义,默认值为
  • 如果你只有3个datanode,但是你却指定副本数为4,是不会生效的,因为每个datanode上只能存放一个副本。
    hadoop fsck -locations 可以看到相应的提示信息,可以看到副本丢失率为33.33%:

2.dfs.replication属性值变更的影响

dfs.replication实质上是client参数,在create文件时可以指定具体replication,属性dfs.replication是不指定具体replication时的采用默认备份数。文件上传后,备份数已定,修改dfs.replication是不会影响以前的文件的,也不会影响后面指定备份数的文件。只影响后面采用默认备份数的文件

3.如何变更备份系数?

  • 首先stop-all.sh停止节点,修改master节点的hdfs-site.xml文件,设置dfs.relication值为目标值,启动hadoop集群。
  • 重启集群后发现,以前文件的备份系数仍是原来的值。Hadoop并不会自动的按照新的备份系数调整,我们需要手动完成。
  • hadoop fsck /or hadoop fsck -locations查看hadoop集群的备份冗余情况
  • hadoop dfs -setrep [-R] <path>修改hdfs文件备份系数,例如:hadoop dfs -setrep -w 3 -R /user/hadoop/dir1hadoop fs -setrep -R 3 / 就是把目录下所有文件备份系数设置为3
  • 如果再fsck时候出错,往往是由于某些文件的备份不正常导致的,可以用hadoop的balancer工具修复,自动负载均衡hadoop文件:hadoop balancer

4.程序里可能碰到的问题

  • 你可能没把conf文件夹加入到你的 project的classpath里,你的程序运行时取的dfs.replication可能是hdfs-default.xml里的 dfs.replication,默认是3。可能这个就是造成你为什么dfs.replication老是3的原因。你可以试试在创建文件时,显式设定replication。

5.client传数据到DataNode

  • client也可以通过Datanode上传数据到hdfs上,不用ssh登录到NameNode上,文件的第一个副本数在某个Datanode上,会将文件传到第二个节点上,而第二个节点在接收并保存数据时,又以4KB的速度将文件传到第三个节点上,以此类推。
  • 当一个文件上传时,client并不立刻联系namenode,而是先在本地缓存数据,当 缓存到达HDFS block size时,联系namenode,namenode将文件名插入到文件系统结构中,并为其分配一个数据块。namenode以datanode主机名和数据块的位置来响应client的请求。客户端从本地临时文件中将数据刷新到指定的datanode。当file关闭时,未刷新的临时文件将传输到datanode,client通知namenode 文件关闭。此时,namenode将文件创建操作提交到永久存储。如果namenode在file closes之前die,则文件丢失。
  • 创建副本过程:
    当client写文件到hdfs时,像前面提到的,先写文件到本地临时文件,假设设定hdfs的副本系数为3.当缓存的文件达到hdfs block size时,client从namenode检索一个datanode的列表。该列表包含将host该副本的datanode列表。client刷新数据到列表中的第一个datanode。第一个datanode以4kb为单位接收数据,将数据写到本地并传输到列表中的第二个datanode,第二个datanode也做同样操作。一个datanode可以从上一个数据管道获取数据,并同时将数据发送到下一个数据管道。

6.dfs.replication的其他问题

  • hadoop中dfs.replication、dfs.replication.min及dfs.safemode.threshold.pct关系

参考