现在的位置: 首页 > 综合 > 正文

hadoop使用笔记

2018年03月30日 ⁄ 综合 ⁄ 共 11587字 ⁄ 字号 评论关闭

1Hadoop
解除 "Name node is in safe mode" 
bin/hadoop dfsadmin -safemode leave 

就可以把safemode解除 
safemode
模式 
NameNode
在启动的时候首先进入安全模式,如果datanode丢失的block达到一定的比例(1-dfs.safemode.threshold.pct),则系统会一直处于安全模式状态即只读状态。 
dfs.safemode.threshold.pct
(缺省值0.999f)表示HDFS启动的时候,如果DataNode上报的block个数达到了元数据记录的block个数的0.999倍才可以离开安全模式,否则一直是这种只读模式。如果设为1HDFS永远是处于SafeMode 
下面这行摘录自NameNode启动时的日志(block上报比例1达到了阀值0.9990 
The ratio of reported blocks 1.0000 has reached the threshold 0.9990. Safe mode will be turned off automatically in 18 seconds. 

hadoop dfsadmin -safemode leave 
有两个方法离开这种安全模式 
 
1修改dfs.safemode.threshold.pct为一个比较小的值,缺省是0.999 
 
2.hadoop dfsadmin -safemode leave命令强制离开 
http://bbs.hadoopor.com/viewthread.php?tid=61&extra=page%3D1 
----------------------------- 
Safe mode is exited when the minimal replication condition is reached, plus an extension 

time of 30 seconds. The minimal replication condition is when 99.9% of the blocks in 
the whole filesystem meet their minimum replication level (which defaults to one, and 
is set by dfs.replication.min). 
安全模式的退出前提 -
整个文件系统中的99.9%(默认是99.9%,可以通过dfs.safemode.threshold.pct设置)的Blocks达到最小备份级别(默认是1,可以通过dfs.replication.min设置) 
dfs.safemode.threshold.pct      float       0.999 

The proportion of blocks in the system that must meet the minimum 
replication level defined by dfs.rep lication.min before the namenode 
will exit safe mode. Setting 
this value to 0 or less forces the name-node not to start in safe mode. 
Setting this value to more than 1 means the namenode never exits safe 
mode. 
----------------------------- 
用户可以通过dfsadmin -safemode value 
来操作安全模式,参数value的说明如下: 
enter -
进入安全模式 
leave -
强制NameNode离开安全模式 
get - 
返回安全模式是否开启的信息 
wait -
等待,一直到安全模式结束。

2Hadoop启动时出现Unrecognized
option: -jvm
Could not create the Java virtual machine 
发现是在hadoop/bin/hadoop中有如下一段shell: 
  
<strong>CLASS='org.apache.hadoop.hdfs.server.datanode.DataNode' 
if [[ $EUID -eq 0 ]]; then 
HADOOP_OPTS="$HADOOP_OPTS -jvm server $HADOOP_DATANODE_OPTS" 
else 
HADOOP_OPTS="$HADOOP_OPTS -server $HADOOP_DATANODE_OPTS" 
fi 
</strong>

其中的 
  

<strong>if [[ $EUID -eq 0 ]]; then 
HADOOP_OPTS="$HADOOP_OPTS -jvm server $HADOOP_DATANODE_OPTS" 
</strong>


如果 $EUID
0,什么意思呢
有效用户标识号(EUID):该标识号负责标识以什么用户身份来给新创建的进程赋所有权、检查文件的存取权限和检查通过系统调用kill向进程发送软中断信号的许可权限。 
root用户下echo $EUIDecho结果为

ok,在root下会有-jvm选项添加上去,上面说的Unrecognized
option: -jvm
难道就是这里产生的。

两个想法。一个想法是自己改了这shell代码,去掉里面的-jvm。另外一个想法是既然这里要求
$EUID -eq 0
,那别用$EUID0的(root用户)用户运行即可。果断试试,换上普通用户根据文档提示做。ok,成功。好奇的再试试第一个想法,其实暂时还是不太想动源码。但是这shell动动也没妨,果断去掉上面的-jvm,直接把上面的if
else
结构直接去掉改为 
 
HADOOP_OPTS="$HADOOP_OPTS -server $HADOOP_DATANODE_OPTS"

同样运行成功。

3ssh无密码登陆不成功问题?
关闭SElinux就好了
关闭SELinux的方法:
  修改/etc/selinux/config文件中的SELINUX=""
disabled
,然后重启。
  如果不想重启系统,使用命令setenforce 0
注:
setenforce 1
设置SELinux
成为enforcing模式
setenforce 0
设置SELinux
成为permissive模式 
  在lilo或者grub的启动参数中增加:selinux=0,也可以关闭selinux 
#---------------------------------------------------------------
查看selinux状态:
/usr/bin/setstatus -v 

如下:
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   permissive
Mode from config file:          enforcing
Policy version:                 21
Policy from config file:        targeted 
  

  getenforce/setenforce查看和设置SELinux的当前工作模式。


4
Linux关闭防火墙
1)     
重启后永久性生效:
  开启: chkconfig iptables on
  关闭: chkconfig iptables off
2)     
即时生效,重启后失效:
  开启: service iptables start
  关闭: service iptables stop
  需要说明的是对于Linux下的其它服务都可以用以上命令执行开启和关闭操作。
  在开启了防火墙时,做如下设置,开启相关端口,
  修改/etc/sysconfig/iptables
文件,添加以下内容:
  -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
  -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
  或者:
  /etc/init.d/iptables status
会得到一系列信息,说明防火墙开着。
  /etc/rc.d/init.d/iptables stop
关闭防火墙
  最后:
  在根用户下输入setup,进入一个图形界面,选择Firewall configuration,进入下一界面,选择Security
Level
Disabled,保存。重启即可。
  ======================================================
  ———————————————————————————————
  fedora
  /etc/init.d/iptables stop
  =======================================================
  iptables
linux下一款强大的防火墙,在不考虑效率的情况下,功能强大到足可以替代大多数硬件防火墙,但是强大的防火墙如果应用不当,可能挡住的可不光是那些潜在的攻击,还有可能是你自己哦.这个带来的危害对于普通的个人PC来说可能无关紧要,但是想象一下,如果这是一台服务器,一旦发生这样的情况,不光是影院正常的服务,还需要到现场去恢复,这会给你带来多少损失呢?
  所以我想说的是,当你敲入每一个iptables
相关命令的时候都要万分小心.
  1.应用每一个规则到 DROP target,都要仔细检查规则,应用之前要考虑他给你带来的影响.
  2.redhat中我们可以使用service
iptables stop
来关闭防火墙,但是在有些版本如ubuntu中这个命令却不起作用,大家可能在网上搜索到不少文章告诉你用iptables
-F
这个命令来关闭防火墙,但是使用这个命令前,千万记得用iptables
-L
查看一下你的系统中所有链的默认target,iptables -F这个命令只是清除所有规则,只不会真正关闭iptables.想象一下,如果你的链默认targetDROP,本来你有规则来允许一些特定的端口,
但一旦应用iptables -L ,清除了所有规则以后,默认的target就会阻止任何访问,当然包括远程ssh管理服务器的你.
  所以我建议的关闭防火墙命令是
  iptables -P INPUT ACCEPT
  iptables -P FORWARD ACCEPT
  iptables -P OUTPUT ACCEPT
  iptables -F
  总之,当你要在你的服务器上做任何变更时,最好有一个测试环境做过充分的测试再应用到你的服务器.除此之外,要用好iptables,那就要理iptables的运行原理,知道对于每一个数据包iptables是怎么样来处理的.这样才能准确地书写规则,避免带来不必要的麻烦。


5
、建立ssh无密码登录

NameNode
[whycold@station1 ~]$ ssh-keygen -t dsa -P '' -f /home/whycold/.ssh/id_dsa
会在~/.ssh/生成两个文件:id_dsaid_dsa.pub。这两个是成对出现的。
[whycold@station1 ~]$ cat id_dsa.pub >> authorized_keys
id_dsa.pub文件追加到DataNode上的authorized_keys(默认是没有这个文件的)内。
[whycold@station1 ~]$ scp authorized_keys 
whycold@192.168.128.22:/home/whycold/.ssh/
 
修改station1station2authorized_keys的权限,设为755(注意还得在station2上修改.ssh的权限,设为755
[whycold@station1~]$ chmod 755 .ssh/authorized_keys
[whycold@station2~]$ chmod 755 .ssh/authorized_keys

6、一定要在namenode和所有datanode上修改/etc/hosts
/etc/sysconfig/network
文件
hosts
:(一定得设为这样,不能有多余的内容,不然会找不到datanode
127.0.0.1 localhost 

192.168.1.110 master 
192.168.1.100 slave 
 /etc/sysconfig/network 修改机器名
NETWORKING=yes
HOSTNAME=master

7、要重新格式化namenode时,须在所有节点上删除tmp/下所有相关文件,hadoop开头的文件,Jetty开头的文件夹和hsperfdata_whycold文件夹,还有hadoop安装目录下的logs文件夹。


8
、在map输入时,默认是用tab键来分键key/value,否则将一行作为value输入。


9
、若要排序输出,可指定一个partitioner类。


10
、多少个输入文件就有多少个map任务,同理多少个输入文件也有多少个reduce任务。map任务开始前,系统可能会将原始输入文件分割成M个输入文件,而map
输出可能会被系统分割成P个输出文件,这p个输出文件将作业reducer任务的输入文件,默认一个reducer
任务输出一个文件,但可以通过参数设置,从而输出多个文件。


11
、排序的原理

先说明一点,熟悉MapReduce的人都知道:排序是MapReduce的天然特性!在数据达到reducer之前,mapreduce框架已经对这些数据按键排序了。

所以,在这个排序的job里,不需要特殊的MapperReducer类。用默认的 
IdentityMapper
IdentityReducer即可。

既然排序是天然特性,那么1TB排序的难点在哪里呢??答:100亿行的数据随即分散在1000多台机器上,mapperreducer都是Identity的,这个难点就在MapReduceshuffle阶段!关键在如何取样和怎么写Partitioner

好在这个排序的源代码已近包含在hadoopexamples里了,下面我们就来分析一下。


11.1
取样和partition的过程

面对对这么大量的数据,为了partition的更均匀。要先取样

1) Math.min(10, splits.length)split(输入分片)进行随机取样,对每个split10000个样,总共10万个样 
2) 10
万个样排序,根据reducer的数量(n),取出间隔平均的n-1个样 
3)
将这个n-1个样写入partitionFile(_partition.lst,是一个SequenceFile)key是取的样,值是nullValue 
4) partitionFile写入DistributedCache

接下来,正式开始执行MapReduce job 
5)
每个map节点: 
          a.
根据n-1个样,build一棵类似于B-数的索引树 
                    *
每个非叶子节点,都有256个子节点。 
                    *
不算根节点的非叶子节点有1层,加上根节点和叶子节点,共3层。 
                    *
非叶子节点代表key“byte path” 
                    * 每个叶子节点代表key的前2bytes
path 

                    * 叶子节点上,保存的是partition number的范围,有多少个reducer就有多少partition
number

          b.前缀相同的key,被分配到同一个叶子节点。 
          c.
一个子节点上,可能有多个reducer 
          d.比第i个样小的key,被分配到第ireducer,剩下的被分配到最后一个reducer

6) 针对一个keypartition的过程:

          a. 首选判断key的第1byte,找到第1层非叶子节点 
          b.
再根据key的第2byte,叶子节点 
          c.
每个叶子节点可能对应多个取样(即多个reducer),再逐个和每个样比较,确定分配给哪一个reducer


11.2
、图解partition索引树

对上面的文字描述可能比较难理解,etongg
同学建议我画个图。所有才有了下面这些文字。感谢etongg和大家对本帖的关注。

索引树的作用是为了让key快速找到对应的reducer。下图是我画的索引树示意图:


对上面的图做一点解释: 
1)
为了简单,我只画了ABC三个节点,实际的是有256个节点的。 
2)
这个图假设有20reducer(下标019),那么我们最终获得n-1个样,即19个样(下标为18的为最后一个样) 
3)
图中的圆圈,代表索引树上的节点,索引树共3层。 
4)
叶子节点下面的长方形代表取样数组。红色的数字代表取样的下标。 
5)
每个节点都对应取样数组上的一个下标范围(更准备的说,是对应一个partition number的范围,每个partition
number
代表一个reducer)。这个范围在途中用蓝色的文字标识。


前面文中有一句话: 
比第i个样小的key,被分配到第ireducer,剩下的被分配到最后一个reducer

这里做一个小小的纠正,应该是: 
小于或者等于第i个样的key,被分配到第ireducer,剩下的被分配到最后一个reducer

下面开始partition 
如果key"AAA"开头,被分配到第“0”reducer 
如果key"ACA"开头,被分配到第“4”reducer 
如果key"ACD"开头,被分配到第“4”reducer 
如果key"ACF"开头,被分配到第“5”reducer

那么, 
如果key"ACZ"开头,被分配到第几个reducer?? 
答案是:被分配到第“6”reducer

同理, 
如果key"CCZ"开头,被分配到第“19”reducer,也就是最后一个reducer


11.3
、为什么不用HashPartitioner 
还需要再说明的一点: 
上面自定义的Partitinoner的作用除了快速找到key对应的reducer,更重要的一点是:这个Partitioner控制了排序的总体有序!

上文中提到的排序是MapReduce的天然特性!这句话有点迷惑性。更准确的说,这个天然特性只保证了:a)
每个map的输出结果是有序的; b)
每个reduce的输入是有序的(参考下面的图)。而1TB的整体有序还需要靠Partitioner的帮助!


Partitioner
控制了相似的key(即前缀相同)落在同一个reducer里,然后mapreduce天然特性再保证每个reducer的输入(在正式执行reduce函数前,有一个排序的动作)是有序的!


这样就理解了为什么不能用HashPartitioner了。因为自定义的Partitioner要保证排序的整体有序大方向。


另外,推荐一篇关于partitioner博文:Hadoop Tutorial Series, Issue
#2: Getting Started With (Customized) Partitioning

再贴《Hadoop.The.Definitive.Guide》中一张图,更有利于理解了: 
 

*** THE END ***


12
map任务输出的文件没有经过排序,但在reducer任务执行之前对输入文件进行了排序。
要保证全局有序,必须指定partitioner.


13
、无论map输入key的类型是int或是string,排序时都是以字符串形式排序。


14
Partition主要作用就是将map的结果发送到相应的reduce。这就对partition有两个要求:
1
)均衡负载,尽量的将工作均匀的分配给不同的reduce
2
)效率,分配速度一定要快。


15
、(重点理确,吃了很大的亏)我们知道,Hadoop streaming框架默认情况下会以'/t'
和空格作为分隔符,将每行第一个'/t’之前的部分作为key,其余内容作为value,如果没有'/t’分隔符,则整行作为key;这个key/tvalue对又作为reduce的输入。hadoop
提供配置供用户自主设置分隔符(
但一行有多个tab时,会分出多个key/value
对来,对默认情况来说) 
      -D stream.map.output.field.separator
:设置map输出中keyvalue的分隔符 
      -D stream.num.map.output.key.fields
 
设置map程序分隔符的位置,该位置之前的部分作为key,之后的部分作为value 
      -D stream.reduce.output.field.separator:设置reduce输出中keyvalue的分隔符 
      -D stream.num.reduce.output.key.fields
:设置reduce程序分隔符的位置
map
任务和reduce
任务输出的文件里,一行代表一个key和对应的value;
(注意:mapreducer的对输入文件采用”/t”和空格来分key/value对,所以不管如何设置map的输出分隔符是怎样的(该分隔符只是在程序里进行分隔key/value,在要key/value对输出到文件时,将该分隔符转为“\t”输出),map的输出文件始终是用”/t”来分key/value对,以匹配reducer对输入文件的要求。)


16
、如果出现找不到jni.hjni_md.h的错误
将以下文件:
\jdk\include\jni.h
\jdk\include\win32\jni_md.h
放到相应的目录

17、用了libhdfs的程序,若直接运行,会出现以下问题。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration
但用以下mapreduce框架运行却没问题
hadoop jar contrib/streaming/hadoop-0.20.2-streaming.jar -input input -output output -mapper /home/whycold/C++excutefile/Mapper -reducer /home/whycold/C++excutefile/Reducer
成功。
注意(记得把$HADOOP_HOME$HADOOP_HOME/lib$HADOOP_HOME/conf添加到CLASSPATH
export CLASSPATH=$HADOOP_HOME/conf:$HADOOP_HOME


18
mapreduce里的输入只能是string,不能是intfloat,但输出可以是这些类型。
例如:
string a;
int b;
可以cin>>a
但不能cin>>b;
可以cout<<a;也可以cout<<b;


19
hadoop可以指定-file
来上传文件和指定-archives来上传文件夹(但须把文件夹打包成 jar
格式)
例如你在mapper程序中要用到ICTCLAS_API
文件里的文件但不想用hdfsAPI
来打开这些文件,则必须打包成jar并上传到hdfs文件系统,输入如下命令
打包成jar的方法:
可以用winrar把文件压缩成zip格式,然后把zip后缀改为jar就可以了(注意:不能压缩成rar格式)
上传jar命令
hadoop dfs -put
 /home/whycold/ICTCLAS_API.jar  /user/whycold/
mapper
程序:
#include <iostream>
#include "ICTCLAS50.h"
using namespace std;

int main() {
 if(!ICTCLAS_Init("ICTCLAS_API.jar"))//
用到ICTCLAS_API文件夹里的文件
 {
     cout<<"
初始化失败!"<<endl;
     return 0;
 }else
 {
  cout<<"
初始化成功"<<endl;
 }

运行mapreducer:
[whycold@master hadoop-0.20.2] hadoop jar contrib/streaming/hadoop-0.20.2-streaming.jar -D mapred.reduce.tasks=0 -archives 'hdfs://master:9000/user/whycold/ICTCLAS_API.jar' -input inputdoc -output outputdoc -mapper /home/whycold/C++excutefile/WordMapper 

(注意:不能-archives 'hdfs://master:9000/user/whycold/ICTCLAS_API.jarICTCLAS_API,会出现找不到文件错误)
输出
packageJobJar: [/home/whycold/hadoop/hadooptmp/hadoop-unjar5212330027352917009/] [] /tmp/streamjob2925490438340494655.jar tmpDir=null 

11/08/12 13:30:21 INFO mapred.FileInputFormat: Total input paths to process : 1 
11/08/12 13:30:21 INFO streaming.StreamJob: getLocalDirs(): [/home/whycold/hadoop/mapred/local] 
11/08/12 13:30:21 INFO streaming.StreamJob: Running job: job_201108121139_0020 
11/08/12 13:30:21 INFO streaming.StreamJob: To kill this job, run: 
11/08/12 13:30:21 INFO streaming.StreamJob: /home/whycold/hadoop/hadoop-0.20.2/bin/../bin/hadoop job  -Dmapred.job.tracker=192.168.1.110:9001 -kill job_201108121139_0020 
11/08/12 13:30:21 INFO streaming.StreamJob: Tracking URL: http://master:50030/jobdetails.jsp?jobid=job_201108121139_0020 
11/08/12 13:30:22 INFO streaming.StreamJob:  map 0%  reduce 0% 

11/08/12 13:30:31 INFO streaming.StreamJob:  map 50%  reduce 0% 
11/08/12 13:30:40 INFO streaming.StreamJob:  map 100%  reduce 0% 
11/08/12 13:30:43 INFO streaming.StreamJob:  map 100%  reduce 100% 
11/08/12 13:30:43 INFO streaming.StreamJob: Job complete: job_201108121139_0020 
11/08/12 13:30:43 INFO streaming.StreamJob: Output: outputdoc 
输出outputdoc/part-0000的内容
[whycold@master hadoop-0.20.2]$ hadoop dfs -cat outputdoc/part-00000 

初始化成功 

 

抱歉!评论已关闭.