您的位置:首页 > 运维架构

hadoop、hbase的数据备份数(dfs.replication)问题

2013-11-13 11:30 281 查看
今天启动hadoop文件系统一直处理安全模式,日志报错(The ratio of reported blocks 0.9714 has not reached the threshold 0.9990. Safe mode will be turned off automatically.),究其原因是之前做hbase存储时要求数据存储三份,而我的hadoop为伪分布模式,数据只能有一个副本,通过hadoop fsck /命令可以看到 Missing replicas:
结果能达到近200%。以前我一直以为,hbase的Replication是根据hdfs的设置的,可是不然。通过查找和询问,最终是在hbase-site.xml里添加一个dfs.replication来设置hbase的replication数。

因是测试环境,解决办法如下:

1、 先手动退出安全模式:hadoop dfsadmin -safemode leave

2、启动hbase清空测试表数据,停止hbase、hadoop(减少hdfs的数据量,使正常数据块达到0.9990以上)

3、修改hbase-site.xml增加dfs.replication=1设置(后续操作hbase时只保存一个副本)

4、重启start-dfs.sh可正常退出安全模式。

附:hadoop的dfs.replication和备份数问题

首先 dfs.replication这个参数是个client参数,即node level参数。需要在每台datanode上设置。

其实默认为3个副本已经够用了,设置太多也没什么用。

一个文件,上传到hdfs上时指定的是几个副本就是几个。以后你修改了副本数,对已经上传了的文件也不会起作用。可以再上传文件的同时指定创建的副本数

hadoop dfs -D dfs.replication=1 -put 70M logs/2

可以通过命令来更改已经上传的文件的副本数:

hadoop fs -setrep -R 3 /

查看当前hdfs的副本数

hadoop fsck -locations

FSCK started by hadoop from /172.18.6.112 for path / at Thu Oct 27 13:24:25 CST 2011

....................Status: HEALTHY

Total size: 4834251860 B

Total dirs: 21

Total files: 20

Total blocks (validated): 82 (avg. block size 58954290 B)

Minimally replicated blocks: 82 (100.0 %)

Over-replicated blocks: 0 (0.0 %)

Under-replicated blocks: 0 (0.0 %)

Mis-replicated blocks: 0 (0.0 %)

Default replication factor: 3

Average block replication: 3.0

Corrupt blocks: 0

Missing replicas: 0 (0.0 %)

Number of data-nodes: 3

Number of racks: 1

FSCK ended at Thu Oct 27 13:24:25 CST 2011 in 10 milliseconds

The filesystem under path '/' is HEALTHY

某个文件的副本数,可以通过ls中的文件描述符看到

hadoop dfs -ls

-rw-r--r-- 3 hadoop supergroup 153748148 2011-10-27 16:11 /user/hadoop/logs/201108/impression_witspixel2011080100.thin.log.gz

如果你只有3个datanode,但是你却指定副本数为4,是不会生效的,因为每个datanode上只能存放一个副本。

hadoop fsck -locations 可以看到相应的提示信息,可以看到副本丢失率为33.33%:

/user/hadoop/logs/test.log: Under replicated blk_-45151128047308146_1147. Target Replicas is 4 but found 3 replica(s).

Status: HEALTHY

Total size: 4834251860 B

Total dirs: 21

Total files: 20

Total blocks (validated): 82 (avg. block size 58954290 B)

Minimally replicated blocks: 82 (100.0 %)

Over-replicated blocks: 0 (0.0 %)

Under-replicated blocks: 82 (100.0 %)

Mis-replicated blocks: 0 (0.0 %)

Default replication factor: 3

Average block replication: 3.0

Corrupt blocks: 0

Missing replicas: 82 (33.333332 %)

Number of data-nodes: 3

Number of racks: 1

FSCK ended at Thu Oct 27 13:22:14 CST 2011 in 12 milliseconds

参考:hdfs_design
http://hadoop.apache.org/common/docs/r0.20.204.0/hdfs_design.pdf http://hadoop.apache.org/common/docs/r0.20.204.0/hdfs_design.html
当一个文件上传时,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可以从上一个数据管道获取数据,并同时将数据发送到下一个数据管道。

今天用hadoop API打算往hadoop集群创建几个文件,然后写入数据试试,结果问题发生了,我的配置文件备份数是1,但是不管我怎么创建,创建的文件备份数都是3。代码如下:

public static void testHDFS() throws IOException{
String str="hdfs://cloudgis4:9000/usr/tmp/";
Path path=new Path(str);
Configuration conf=new Configuration();
FileSystem hdfs=path.getFileSystem(conf);
long begin=System.currentTimeMillis();
for(int i=0;i<10000;i++){
byte [] kkk=new byte[10000+1*i];
FSDataOutputStream fsDataOut=hdfs.create(new Path(str+i));
fsDataOut.write(kkk);
fsDataOut.close();
//hdfs.close();
}
long end=System.currentTimeMillis();
System.out.println("hdfs:"+(end-begin));
}

很奇怪,上网搜了一下发现了这个API:setReplication。用了这个之后,创建的文件备份数还是3,搜了下这个API的使用,发现这个API只能更改已经存在的文件的备份数。如果先创建再修改备份,无疑增加了框架的负担。后来想了想,明明配置文件修改成了1,那么就应该是这个应用程序没有读取配置文件。所以手动读取下配置文件就可以了。

conf.addResource(new Path("/usr/local/hadoop/conf/hdfs-site.xml"));

ps:hbase 权威指南上有这样一句话:

If you are configuring an IDE to run an HBase client, you could include the conf/

directory on your classpath. That would make the configuration files discoverable by

the client code.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: