2015年由于对公司请的外部的大数据讲师的水平实在不敢恭维,所以就准备搭个环境熟悉一下环境,进步研究一下源代码。所以在本机搭了几个虚拟机,分别对应namenode,datanode(3),secondarynamenode。当时部署的时候使用的是1.0的稳定版本,但是各种坑。耐着性子一点点调试下,也就顺手记在一个word文档里。最近忽然有写博客的念头,就先把手头上有的东西先发上来。
1. 如果不先用hadoop namenode -format格式化HDFS的话,如果后面启动所有的服务(start-all.sh),HDFS就启动不起来,表现为:
a. 如果用netstat –a查看,没有50070的监听端口
b. 如果直接访问http://localhost:50070,会出现白页面
2. 我使用的是Ubuntu,默认SSH server是没有安装的。而且如果是用sudo apt-get install openssh-server. 会出现下面的错误:
E: Package openssh-server has no installation candidate解决的方法是需要把ubuntu的软件库update。用命令sudo apt-get update. 然后sudo apt-get upgrade. 当运行sudo apt-get update, 因为连接的是美国的服务器,会非常缓慢,解决的办法是用是网易的代理地址。具体做法如下(参考地址:http://blog.csdn.net/txdb/article/details/17766255):
a. sudo gedit /etc/apt/sources.list
b. 增加下面这些条目(限于篇幅,放到附件里)
c. 运行sudo apt-get update和sudo apt-get upgrade
d. 运行sudo apt-get intall openssh-server和sudo apt-get install openssh-client.一般情况下,client不需要安装,默认已经存在
3. 使用which ssh 命令看看SSH指向那个启动文件,然后使用ssh start来启动SSH。如果SSH启动正常,使用ps –e|grep ssh查看,会有两个服务正常启动:
1040 ? 00:00:00 sshd
626 ? 00:00:00 ssh-agent
4. Hadoop的一些基本命令(注意:在hadoop2.0,这些命令仍然可以运行,但是建议用新的命令)
a. 在HDFS系统里创建一个文件夹
hadoop fs –mkdir /user/hadoop/input
b. 将本地的一个文件上传到HDFS系统上去
hadoop fs –put /home/Johnson/helloworld.txt /user/hadoop/input
c. 查看HDFS上某个路径下的文件
hadoop fs –ls /user/Hadoop/input
d. 执行hadoop的example,比如wordcount
hadoop jar Hadoop-examples-1.2.1.jar wordcount /user/Hadoop/input/helloworld.txt
5. 在Eclipse里配置Hadoop的时候,在设置Hadoop Location时,会碰到两个问题
a. "Map/Reduce location status updater".org/codehaus/jackson/map/JsonMappingException解决办法:将lib/jackson-core-asl-1.8.8.jar ,lib/jackson-mapper-asl-1.8.8.jar, lib/commons-configuration-1.6.jar,lib/commons-lang-2.4.jar, lib/commons-httpclient-3.0.1.jar这些jar包解压,解压出来的class放到已经编译好的Hadoop的Eclipse插件的jar包里(可以用解压工具打开jar包,直接拖进去)。例如:hadoop-eclipse-plugin-1.2.1.jar的classes。
b.Call to 192.168.176.253/192.168.176.253:9001 failed on connection exception: java.net.ConnectException: Connection refused: no further information
core-site.xml、mapred-site.xml、hdfs-site.xml中配置的value有用到localhost或者机器名字的,比如johnson-master,都换成本机ip
6. 在启动Hadoop时,可能会遇到下面错误:
ERROR org.apache.hadoop.dfs.DataNode: java.io.IOException: Incompatible namespaceIDs in /app/hadoop/tmp/dfs/data: namenode namespaceID = 308967713; datanode namespaceID = 113030094
首先这是Hadoop的一个bug(https://issues.apache.org/jira/browse/HDFS-107)。有两个solution可以解决:
a. Start from scratch
1) Stop the full cluster, i.e. both MapReduce and HDFS layers
2) Delete the data directory on the problematic DataNode: the directory is specified by dfs.data.dir in conf/hdfs-site.xml; if you followed this tutorial, the relevant directory is /app/hadoop/tmp/dfs/data
3) Reformat the NameNode. WARNING: all HDFS data is lost during this process
4) Restart the cluster
b. Manually update the namespaceID of problematic DataNodes
1) Stop the problematic DataNode(s)
2) Edit the value of namespaceID in ${dfs.data.dir}/current/VERSION to match the corresponding value of the current NameNode in ${dfs.name.dir}/current/VERSION
3) Restart the fixed DataNode
7. 下面的错误信息经常会在log文件看到,这个可能跟Hadoop自身的一个bug有关:https://issues.apache.org/jira/browse/HDFS-3157
WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Unexpected error trying to delete block blk_2903555284838653156_1003. BlockInfo not found in volumeMap
java.io.IOException: Error in deleting blocks.
at org.apache.hadoop.hdfs.server.datanode.FSDataset.invalidate(FSDataset.java:2061)
8. 在Windows平台的Eclipse里查看DFS 下的tmp目录下的system目录时,还有运行某些操作是出现权限异常
org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security .AccessControlException: Permission denied: user=jili, access=WRITE, inode="johnson": johnson:supergroup:rwxr-xr-x
注意:帐号jili是我在Win7上的域用户的帐号,而johnson是在Ubuntu上部署和操作Hadoop的帐号。解决方案有三种(details,see http://www.huqiwen.com/2013/07/18/hdfs-permission-denied/):
a. 在系统的环境变量或java JVM变量里面添加HADOOP_USER_NAME,这个值具体等于多少看自己的情况,以后会运行HADOOP上的Linux的用户名。(修改完重启eclipse,不然可能不生效)
b. 将当前系统的帐号修改为hadoop
c. 使用HDFS的命令行接口修改相应目录的权限,hadoop fs -chmod 777 /user,后面的/user是要上传文件的路径,不同的情况可能不一样,比如要上传的文件路径为hdfs://namenode/user/xxx.doc,则这样的修改可以,如果要上传的文件路径为hdfs://namenode/java/xxx.doc,则要修改的为hadoop fs -chmod 777 /java或者hadoop fs -chmod 777 /,java的那个需要先在HDFS里面建立Java目录,后面的这个是为根目录调整权限
9. 如果是下面的异常:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable,原因是:
“The reason you saw that warning is the native Hadoop library $HADOOP_HOME/lib/native/libhadoop.so.1.0.0 was actually compiled on 32 bit.”
意思就是Hadoop 的native是在32 bit环境下编译的,在64bit环境下运行会有问题,所以需要下载hadoop 2.2.0 的源码在64bit环境下重新编译
10. 当运行一个客户端class,出现找不到当前的class,比如:15/02/08 17:35:54 INFO mapred.JobClient: Task Id : attempt_201502050645_0011_m_000000_0, Status : FAILEDjava.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.examples.WordCount$TokenizerMapper
原因是因为job.setJarByClass使用了WordCount.class的类加载器来寻找包含该类的Jar包,然后设置该Jar包为作业所用的Jar包。但是我们的作业Jar包是在程序运行时才打包的,而WordCount.class的类加载器是AppClassLoader,运行后我们无法改变它的搜索路径,所以使用setJarByClass是无法设置作业Jar包的。
将本工程导出的jar包放到工程根目录下面,比如我的Eclipse工程的根目录是E:\Installation\eclipse4.3\workspace\hadoop,hadoop是project的名字,并在提交程序前添加下面的设置:
conf.set("mapred.jar", "xxx.jar"); //其中,xxx.jar是你导出的jar文件名,注意第一个参数不要拼写错了
11. Eclipse里运行某个客户端class的时候,会报异常:
15/02/08 20:42:24 ERROR security.UserGroupInformation: PriviledgedActionException as:johnson cause:org.apache.hadoop.mapreduce.lib.input.InvalidInputException: Input path does not exist: file:/usr/hadoop/wordcount.txt
Exception in thread "main" org.apache.hadoop.mapreduce.lib.input.InvalidInputException: Input path does not exist: file:/usr/hadoop/wordcount.txt
注意:当前的Hadoop服务器的master节点的ip是192.168.176.128(Ubuntu VM ip),而Eclipse运行在Win7下。所以从上面异常能看出,如果通过file:/usr/Hadoop/wordcount.txt,肯定会失败。期望的是hdfs://192.168.176.128:9000/usr/Hadoop/wordcount.txt.
两个solution:
a. 在class里加入下面的代码:
conf.set("fs.default.name", "hdfs://192.168.176.128:9000");
b. 在Eclipse的run configuration里配置参数,比如在Program arguments里指定:
hdfs://192.168.176.128:9000/usr/hadoop/wordcount.txt hdfs://192.168.176.128:9000/usr/hadoop/output/wordcount7
12. 如果是在Windows平台上加载Linux虚拟机的方式来安装Hadoop,就会存在先把需要的软件下载到windows上,然后再拷贝到Linux的情况,单用命令行去mount非常不方便,配置samba是个有效的方式。
1) 默认samba已经安装在Ubuntu上,打开"终端窗口",输入"sudo mkdir /home/share"-->回车-->共享目录share新建成功
2)输入"sudo chmod 777 /home/share"-->回车,这样用户就对共享目录有了写权限
3) 打开"终端窗口",输入"sudo gedit /etc/samba/smb.conf"-->回车-->打开了配置文件smb.conf
4) 修改配置文件smb.conf,输入"security = user"(maxlog参数下面)。在最后输入如下语句:
[myshare]
comment=my share folder
path=/home/johnson/share
browseable=yes
writable=yes
5) 打开"终端窗口",输入"sudo useradd smbuser"-->回车-->用户创建成功。然后输入"sudo smbpasswd -a smbuser"-->回车-->输入两次密码-->回车-->密码设置成功,这个用户属于smb组。最后输入"sudo service smbd restart"重启samba服务-->回车-->服务重启成功
6) 如果客户端是windows系统,在"运行"窗口中输入"\\192.168.1.4"-->回车-->双击打开myshare-->回车-->输入用户名和密码-->回车-->访问成功
13. 配置Hbase,Hive或者其它的组件,需要了解所有组件相互兼容的版本。参考:http://www.aboutyun.com/blog-61-62.html以及Hadoop的官网
14. Hive 集群配置 http://www.linuxidc.com/Linux/2013-07/87952.htm