Cloudera 安装完成后的其他设定以及spark程序运行时出现的问题

前情提要:目前正在学习大数据方面的知识,于是在4台VM上搭建环境,使用的是Cloudera Parcels安装法,所以Hadoop,spark和Yarn是用CDH自动安装的。

安装环境的各个版本及对应的官方Documentation
centos:6.8
Cloudera EnterPrise 5.9.x : http://www.cloudera.com/documentation/enterprise/latest.html
Spark(1.6.0) : http://spark.apache.org/docs/1.6.0/
Scala (2.10.4) : http://docs.scala-lang.org/zh-cn/overviews/
java version: 1.8.0_111(若是在parcells安装时选择了自动安装jdk,那就别自己再安装jdk了)
jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
hadoop 2.6.0-cdh5.9.0
jdk安裝方法:搜索 “centos6 安裝JDK”即可,也可以參考“https://shazi.info/centos-6-%E5%AE%89%E8%A3%9D-java-jdk-1-7-0/
安裝JDK一定要注意设定 JAVA_HOME。
Intelligent Idea : https://www.jetbrains.com/help/idea/2016.3/meet-intellij-idea.html?utm_content=2016.3&utm_medium=help_link&utm_source=from_product&utm_campaign=IC

一 Cloudera 5.9.X安装完成之后的设定

1. 增加Host 名称

在每一台电脑都增加所有 VM 的 IP 跟 Host名称,如下:

vi /etc/hosts

然后增加下面的内容
<code>
140.138.77.22 cglab22
140.138.77.23 cglab23
140.138.77.24 cglab24
140.138.77.25 cglab25 </code>

2. 建立 SSH 免密码登入,概念是 master VM 产生一个 public key 然后丢给所有slave vm认证,让master可以无密码ssh登入其他台 VM。步骤如下:

cglab22( master ):

ssh localhost //目的是建立 ~/.ssh文件夹
ssh-keygen -t rsa //建立public key
cat ./id_rsa.pub >> ./authorized_keys //概念上类似认证,做了就可以免密码ssh登入
scp ~/.ssh/id_rsa.pub cglab25:~/.ssh //将master的public key传给slave,过程中需要密码
cglab23…( slave ):
ssh localhost //目的是建立 ~/.ssh文件夹
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys //概念上类似认证,做了就可以免密码ssh登入
rm ~/.ssh/id_rsa.pub //可以刪掉了

注意:这个一定要删掉,因为上面这个过程只是完成了从master vm到slave vm的ssh免密登录,而没有完成从slave vm到master vm。对于其他的每个slave vm,都要重复上面的这些步骤,而如果没有“ rm ~/.ssh/id_rsa.pub ”这一步,就会覆盖掉之前的设定。

对剩余的slave vm也做相同的步骤
全部完成cglab22、ssh cglab23…之间就可以直接用ssh互相连接,不需要密碼。
参考:http://www.dashen100.com/question/1014

3.设置防火墙( iptables ),步骤如下:

sudo vi /etc/sysconfig/iptables

<code>-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -s 140.138.77.23 -j ACCEPT // 这边是新增的IP,slave vm IP
-A INPUT -i eth0 -p tcp -s 140.138.77.24 -j ACCEPT // 这边是新增的IP,slave vm IP
-A INPUT -i eth0 -p tcp -s 140.138.77.25 -j ACCEPT // 这边是新增的IP,slave vm IP
-A INPUT -i eth0 -p tcp -s 140.138.150.169 -j ACCEPT //允许查看remote vm 的本地电脑的IP(就是自己的电脑的IP)
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
</code>

sudo service iptables restart //再启动防火墙

4. 关掉 SELinux

<code>sudo vi /etc/sysconfig/selinux
SELINUX=disabled</code>

5. reboot //重启

二 Spark程序运行时出现的问题

在cloudera环境配置好之后,第一次运行spark程序出现了许多问题,以下是几个困扰我最久的问题:

1. set master url的问题

我是用Intelligent Idea来写spark程序,在本地端运行时记得要在初始化spark的时候设置master url.
Example:
<code>
val conf = new SparkConf().setAppName("TensorTucker")
.setMaster("Local[*]")
val sc = new SparkContext( conf )
TensorTucker.setSparkContext( sc )
</code>

2.jackson.databind的问题

这个问题的名字很长,由于是很久之前的错误,已经没有出错信息了。如果有人碰到,仔细看出错信息,如果里面有关键字jackson.databind,也许我的回答会有帮助。

我把错误信息放到stackflow上搜索,得到的答案是这是jackson的版本问题。因为我的CDH是属于比较新的版本,所以需要新的jackson jar包来支持运行。由于我采用的是parcels安装,所以jackson的目录是:

/opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/jars

下面是此目录中jackson jar包示例

jackson jar示例

可以发现里面有许多以jackson开头的jar包,我下载完jackson-core-2.4.4.jar之后放到上面那个目录,然后由于jackson-core-2.4.4.jar对类似于jackson-annotations.jar等其他jar包的版本也有要求,所以我总共在上述目录添加了一下这几个jar包,后面是对应的版本。
jackson-module-scala_2.10-2.4.4.jar
jackson-annotations-2.4.4.jar
jackson-core.jar 2.4.4
jackson-annotations 2.4.4
jackson-databind 2.4.4
paranamer 2.6
jsr305 2.0.1
还修改了 coudera/parcels/CDH/lib/spark/conf/classpath.txt 中与上述jar包对应的版本
然后在程序中重新引入jackson的jar包。
Link:https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305/2.0.1

3.修改了intelligent idea Setting->Build,Execution..->Compiler->Build process heap size(从700改到1500),这可能会对解决java out of space的问题有帮助。同时在程序运行时进行如下设定,也对解决java out of space的问题有帮助。

--driver-memory 8G
--num-executors 2
--executor-cores 3
--executor-memory 8G

4.关于从本地上传文件到hdfs的问题。

安装CDH时会自动在hdfs中创建一个身份 hdfs,路径是/user/hdfs(这里的 user = root ),所以在hdfs中已经有一个身份和对应路径了。

然后我自己又在hdfs中创建了一个新的身份是 root ( 这个root其实是我的vm--cglab22的登录身份 ), 路径是/user/root 。

所以如果在使用 hdfs dfs -ls的時候不指定具体的路径,使用 hdfs dfs -ls 这种类似的命令就会默认查询当前vm身份下的路径,即默认查询/user/root 路径。所以要查询不同身份的文件,应该要指定具体的路径。

总结起来就是,首先在hdfs中创建一个身份root(root就是我登录VM的身份

hdfs dfs -mkdir /user/root

然后给这个hdfs 的root身份一个对应的权限,如果是登录vm 是root,则是root权限,如果是user或xiaoming,则是user或xiaoming的权限。

hdfs dfs -chown:hadoop /user/root

参考资料:
https://docs.hortonworks.com/HDPDocuments/Ambari-2.1.2.0/bk_ambari_views_guide/content/_setup_HDFS_user_directory.html

5.以yarn-cluster模式运行程序时遇到的问题(注意要在Cloudera WebUI 中找到YARN,然后在YARN里找到Resource ManagerWeb UI ,然后找对应程序的log,不仅要看master vm的log,也要看datanode的log),如下图:
从这里点进去看程序运行情况

1)SparkContext did not initialize after waiting for 100000 ms 问题

问题截图

这个属于spark initial的问题,很简单,是因为我在spark-submit的时候没有加上--class Test(即在给程序打包时没有指定main class ,所以在运行时需要加,若在打包时已经指定了main class,则不需要加)。比如下面这个写法,一定要加上主函数名那一项。
<code>
/opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/lib/spark/bin/spark-submit
--class test \ //(主函数名)
--master yarn \ //(运行模式)
--deploy-mode cluster
--driver-memory 8G \
--num-executors 2
--executor-cores 3
--executor-memory 8G
/usr/Code/Test/out/artifacts/Pi_jar/Pi.jar/ 10
</code>

2) ERROR yarn.ApplicationMaster: User class threw exception: java.lang.UnsupportedClassVersionError: MyFixedLengthInputFormat : Unsupported major.minor version 52.0

log

这个问题属于程序编译的jdk版本与程序运行环境的版本不一致,我的情况是程序编译时jdk1.8.0-111,而运行环境却是1.7,运行环境的配置可以在spark UI中找到,如下图:

运行环境

所以我把intelligent Idea的jdk改到了1.7。改动的地方如下图:

改动方法

参考stackflow上的回答:http://stackoverflow.com/questions/10382929/how-to-fix-java-lang-unsupportedclassversionerror-unsupported-major-minor-versi

3)在cluster上运行程序时,log上的错误信息:INFO yarn.ApplicationMaster: Unregistering ApplicationMaster with FAILED (diag message: User class threw exception: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="/user/root/test1":hdfs:hadoop:drwxr-xr-x

又是hdfs 中文件的权限问题,我以hdfs身份创建的test1,test2,其所属权限属于hdfs,所以程序运行时root没有权限对这两个文件进行写操作,所以应以root身份创建文件。

6 关于add host 和delete host

(1)如果在一个cluster中,需要添加或删除一个host,可以去cloudera官网找对应教程,值得注意的是,若是要将一个host彻底从一个cluster中移除掉,个人经验是按照 remove host的教程来做,因为delete host 之后cluster中还是会出现一些跟这个删除掉的host有关的错误信息。

(2)add new host 也是去看cloudera的官方文档,记得一定要安装与现有CDH一样的版本。add new host的时候,验证新host与旧host的关系时,可能出现swap与Transparent Hugepage Compaction的问题
解决方法如下
https://www.cloudera.com/documentation/enterprise/5-3-x/topics/cdh_admin_performance.html

版本问题的话,缺什么装什么好了。
(3)若先delete了一个host ,比如cglab25,然后又add这个host,需要重新设置ssh免密登录,这个时候会出现:warning:remote host identification has changed,是因为cglab22-23里的认证信息是原来的cglab25,重新装系统之后要删掉其他VM原来的认证资讯,然后才能ssh操作。
command line如下:

ssh-keygen -R <host>

(4)add new host的时候,验证新host与旧host的关系时,可能出现swap与Transparent Hugepage Compaction的问题
解决方法如下:
https://www.cloudera.com/documentation/enterprise/5-3-x/topics/cdh_admin_performance.html

7 若CDH Manager中出现类似 Blocks missing 或 replicated的问题,

参考答案为:
http://community.cloudera.com/t5/Storage-Random-Access-HDFS/How-to-fix-missing-and-underreplicated-blocks/td-p/20020

推荐阅读更多精彩内容