(10)向HDFS中put文件时揭示“Name node is in safe mode”的原因及解决办法
向HDFS中put文件时,如果揭示:
put: org.apache.Hadoop.hdfs.server.namenode.SafeModeException: Cannot create file /XXX. Name node is in safe mode.
原因很显然了,name node处于安全模式,解决办法也很简单:kill掉name node的进程,然后重启之:
ps -ef | grep java
用该命令查看name node进程的PID,然后kill掉,然后再启动之:
start-dfs.sh
再确定一下name node进程是否启动了,如果成功启动了,就OK了。
这里有一个批量kill进程的技巧,其实就是几句shell语句:
PIDS=`ps -ef | grep -v grep | grep java | awk '{print $2}'`; for PID in $PIDS; do kill $PID; done
其中,“grep java”表示查找含有“java”关键字的进程名,“grep -v grep”表示过滤掉grep自己的这个进程名,awk 是用于打印出第2列的内容,即PID(进程号),而后面的 for 循环则是批量kill掉找到的进程。
(11)在shell中判断一个HDFS目录/文件是否存在
直接看shell代码:
hadoop fs -test -e /hdfs_dir
if [ $? -ne 0 ]; then
echo "Directory not exists!"
fi
hadoop fs -test -e 用于判断HDFS目录/文件是否存在,下一步检测该命令的返回值,以确定其判断结果。
-test -[ezd] <path>: If file { exists, has zero length, is a directory
then return 0, else return 1.
e,z,d参数必用其一,不可缺少。
(12)一次添加多个输入目录/文件到Map-Reduce job中
使用 FileInputFormat.addInputPaths(Job job, String commaSeparatedPaths) 方法,可以一次将多个目录/文件添加到M-R job中,其中,第二个参数是一个逗号分隔的路径列表,例如“/user/root/2012-01-01,/user/root/2012-01-02,/user/root/2012-01-03”。
(13)HBase中的TTL的单位
在hbase shell中,describe '表名'可以查看一个HBase表的结构和基本参数,例如:
hbase(main):005:0> describe 'TableName'
DESCRIPTION ENABLED
{NAME => 'TableName', FAMILIES => [{NAME => 'fam', COMPRESSION = > 'NONE', VERSIONS => '2', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}]}
里面的TTL的单位是秒,不做特别设置的时候,就是这个默认值(约为69年),超过此时间的记录会被删除。
(14)HBase中的VERSIONS(版本)的含义
如上例所示,你已经看到了VERSIONS这个参数,假设其值为2,那么它表示:row key、column family、qualifier 都相同的记录最多可以有2条,这2条记录的timestamp不同。例如用hbase shell查到的下面两条记录:
abc column=fam:\x11\x00\x00\x99, timestamp=1325260900000, value=?\x80\x00\x00
abc column=fam:\x11\x00\x00\x99, timestamp=1326828800000, value=?\x80\x00\x00
其中,“abc”是row key,“fam”是column family,“\x11\x00\x00\x99”是qualifier,这三者均相同,而这两条记录的timestamp不同,也就是VERSIONS为2。
(15)context.progress()的作用
假设在map()方法中,你有一个从数据库读取大量数据的操作,是用一个循环来完成的,并且,在读完全部的数据之前,你不会有任何的数据输出(纯读),那么,读完全部数据所需的时间可能很长,一直没有输出的话,这个task就会因为超时被杀掉,为了避免这个问题,可在以读取数据的循环中使用context.progress()方法来报告进度,那么该task就会被认为还活着,从而解决超时问题。
(16)Map-Reduce的单元测试,用MRUnit来做
我们不可能把每个M-R job都放到到实际的环境中去运行,靠打印log来调试其中的问题,单元测试是必须的,M-R的单元测试用MRUnit来做。
①MRUnit有两个ReduceDriver,一个是 org.apache.hadoop.mrunit.mapreduce.ReduceDriver,另一个是 org.apache.hadoop.mrunit.ReduceDriver,其中,前者是为更新的Hadoop API准备的,如果你发现IDE在ReduceDriver这里提示错误,但是又不知道哪里写错了的时候,可以查看一下是否是这个问题。
②在测试一个mapper类中的时候,MRUnit的setUp()函数比mapper类的setup(Context context)函数要先执行。
(17)调用一个Java Map-Reduce程序时,在命令行传入参数“-D mapred.queue.name=XXX”的作用
Hadoop集群中的job被分在不同的队列中,如果不设置mapred.queue.name参数,则job被放置在默认队列中,否则就被放在指定的队列中。各队列之间是有优先级之分的,同一个队列中的各job也有优先级之分,所以,我们需要的话,可以既设置队列,又设置job的优先级:
-D mapred.queue.name=XXX
-D mapred.job.priority=HIGH
这表示设置优先级为HIGH。
(18)继承自org.apache.hadoop.hbase.mapreduce.TableMapper这个抽象类的一个mapper类,当它的map()方法每被调用一次时,就有HBase的一行(row)被读入处理,由于是处理一行,所以对一个map()方法来说,row key是唯一的,column family可能有N个,每个column family下又可能有M个qualifier,每一个qualifier还可能会对应X个timestamp的记录(取决于你HBase的VERSIONS设置),你可以在map()方法中,一级级地遍历得到所有记录。