PY => Ubuntu-Hadoop-YARN-HDFS-Hive-Spark安装配置

更新于 2019-11-05  约 28 分钟

环境条件

Java 8
Python 3.7
Scala 2.12.10
Spark 2.4.4
hadoop 2.7.7
hive 2.3.6
mysql 5.7
mysql-connector-java-5.1.48.jar

R 3.1+(可以不安装)

安装Java

先验传送门:https://segmentfault.com/a/11...

安装Python

用Ubuntu自带Python3.7

安装Scala

下载:https://downloads.lightbend.c...
解压:

tar -zxvf 下载好的Scala

配置:

vi ~/.bashrc
    export SCALA_HOME=/home/lin/spark/scala-2.12.10
    export PATH=${SCALA_HOME}/bin:$PATH
保存退出

激活配置:

source ~/.bashrc

安装Hadoop

提前说明: 若不使用HDFS 和 YARN,整个 Hadoop安装可忽略,可以直接安装spark。
下载:https://archive.apache.org/dist/hadoop/common/
详细地址: https://archive.apache.org/di...
解压:

tar -zxvf 下载好的 hadoop

配置hadoop:

vi ~/.bashrc
    export HADOOP_HOME=/home/lin/hadoop/hadoop-2.7.7
    export PATH=${HADOOP_HOME}/bin:$PATH

激活配置:

source ~/.bashrc

HDFS配置:

进入解压后的 etc/hadoop (注意这不是根目录的etc, 而是解压后的hadoop目录下的etc)

echo $JAVA_HOME        # 复制打印出的路径

vi hadoop-env.sh:  (找到 export JAVA_HOME 这行,并替换为如下)
    export JAVA_HOME=/home/lin/spark/jdk1.8.0_181  
    
vi core-site.xml:  (hdfs后面为 主机名:端口号)  (主机名就是终端显示的 @后面的~~~)
    <property>
      <name>fs.default.name</name>
      <value>hdfs://lin:8020</value>       
    </property>
    
vi hdfs-site.xml: (同样在 <configuration> 之间加入) (/home/lin/hdfs是我已经有的目录)
    <property>
      <name>dfs.namenode.name.dir</name>
      <value>/home/lin/hdfs/dfs/name</value>
    </property>

    <property>
      <name>dfs.datanode.data.dir</name>
      <value>/home/lin/hdfs/dfs/data</value>
    </property>

格式化HDFS:

hadoop namenode -format
# 然后去刚才上面配置的这个路径里面是否有新东西出现: /home/lin/hdfs

开启HDFS (先进入 sbin目录下, sbin 和 etc bin是同级的, 这里说的都是hadoop里的目录):

./start-dfs.sh

# 一路yes, 若让你输入密码, 则输入对应服务器的密码。(我这里都是本机)
# 若提示权限错误,继续往下看(支线)
    sudo passwd root              # 激活ubuntu的root用户,并设置密码
    vi /etc/ssh/sshd_config:
        PermitRootLogin yes       # 任意位置添加这个(此选项之前可能是存在的注释后再添加)
    service ssh restart 

查看HDFS里面根目录 / 的内容:

hadoop fs -ls /

向HDFS里面根目录 / 中 传入文件:

echo test > test.txt     # 首先,随便建立一个文件

hadoop fs -put test.txt /     # 向HDFS里面根目录 / 中 传入文件

hadoop fs -ls /          # 再次查看,就发现有 test.txt 文件了。

从HDFS里面根目录 / 中 读取文件test.txt:

hadoop fs -text /test.txt

从Hadoop WebUI 中查看刚才的文件是否存在:

http://192.168.0.108:50070/           # 50070是默认端口

点击右侧下拉框 "Utilities"  ->  "Browser the file system "
清晰可见, 我们的test.txt 躺在那里~

YARN配置

还是etc/hadoop这个目录:

cp mapred-site.xml.template mapred-site.xml

vi mapred-site.xml:
    <property>
      <name>mapreduce.framework.name</name>
      <value>yarn</value>
    </property>
    
vi yarn-site.xml:
    <property>
      <name>yarn.nodemanager.services</name>
      <value>mapreduce_shuffle</value>
    </property>     

启动 YARN: (还是 sbin目录下)

./start-yarn.sh

# 同样,若有密码,输入机器的密码即可

从Hadoop WebUI 中查看YARN:

http://192.168.0.108:8088/

安装MySQL

下面要用MySQL, 所以单独提一下MySQL 的 安装与配置:
其实MySQL是不需要单独说的, (但我装的时候出现了和以往的不同经历), 所以还是说一下吧:

apt-get install mysql-server-5.7

安装容易, 不同版本的MySQL配置有些鸡肋 (我用的是 Ubuntu19):

vi /etc/mysql/mysql.conf.d/mysqld.cnf:
    bind-address     0.0.0.0               # 找到修改一下即可

修改密码+远程连接权限 (默认无密码):

mysql                # 啥参数也不用加, 直接就能进去
use mysql
update mysql.user set authentication_string=password("123") where user="root";
update user set plugin="mysql_native_password";
flush privileges;

select host from user;
update user set host ='%' where user ='root';
flush privileges;

重启服务:

systemctl restart mysql

服务端连接测试:

mysql -uroot -p
# 密码 123

远程连接测试 (Navicat):

成功

安装Hive

下载: https://archive.apache.org/di...

解压:

tar -zxvf apache-hive-2.3.6-bin.tar.gz

配置Hive:

vi ~/.bashrc
    export HIVE_HOME=/home/lin/hive/apache-hive-2.3.6-bin
    export PATH=${HIVE_HOME}/bin:$PATH

激活配置:

source ~/.bashrc

Hive其他相关配置(同理进入hive解压目录的 conf目录中):

cp hive-env.sh.template hive-env.sh
vi hive-env.sh:
    HADOOP_HOME=/home/lin/hadoop/hadoop-2.7.7

Hive-MySQL相关配置(同是在 conf目录下):

vi hive-site.xml:  (特别注意后两个 <property> 里面的内容, 自己修改一下用户名和密码)
    <configuration>
        <property>
            <name>javax.jdo.option.ConnectionURL</name>
            <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=false</value>
        </property>
        <property>
            <name>javax.jdo.option.ConnectionDriverName</name>
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property>
            <name>javax.jdo.option.ConnectionUserName</name>
            <value>root</value>
        </property>
        <property>
            <name>javax.jdo.option.ConnectionPassword</name>
            <value>123</value>
        </property>
    </configuration>

下载 jdbc-mysql驱动,并放入Hive中,操作如下 (因为我们上面hive-site.xml 用的是mysql):

  1. 首先下载: http://central.maven.org/mave...
  2. 将此jar文件放入 hive的lib目录中(和 conf同级):
  3. 将此jar文件再copy一份放入 spark的 jar目录下(为了后续jupyter直连MySQL(不通过Hive)使用)

初始化(先确保之前的HDFS和MySQL已经启动):

schematool -dbType mysql -initSchema

# 注意事项1: 这个用命令初始化的 步骤是 Hive 2.+ 才需要做的
# 注意事项2: 初始化一次即可, 多次初始化,会使得MySQL有重复的键. 报错.

开启 metastore 服务:

nohup hive --service metastore &

检测是否初始化(去MySQL表中查看):

use hive
show tables;       
# 若有数据,则说明初始化成功

启动hive:

hive

建库, 建表测试 (注意,千万不要用 user这种关键字当作表名等):

HIVE中输入:  
    create database mydatabase;
    use mydatabase;
    create table person (name string);
    
MySQL中查看Hive表的相关信息: 
    select * from TBLS;                 # 查看所有表结构信息
    select * from COLUMNS_V2;           # 查看所有列的信息

向Hive导入文件:

vi hive_data.txt: (写入如下两行)
    tom catch jerry
    every one can learn AI
    
load data local inpath '/home/lin/data/hive_data.txt' into table person;

查询:

select * from person;

PySpark客户端配置连接代码:

import findspark
findspark.init()

from pyspark.sql import SparkSession    

spark = SparkSession.builder\
    .appName("Spark Hive Example")\
    .master("local[*]")\
    .config("hive.metastore.uris", "thrift://localhost:9083")\
    .enableHiveSupport()\
    .getOrCreate()
    
spark.sql("use mydatabase").show()
spark.sql('show tables').show()

安装Spark

下载:spark-2.4.4-bin-hadoop2.7.tgz
粗糙传送门:https://spark.apache.org/downloads.html
详细传送门:http://ftp.riken.jp/net/apache/spark/spark-2.4.4/spark-2.4.4-bin-hadoop2.7.tgz

解压:

tar -zxvf 下载好的spark-bin-hadoop

配置spark:

vi ~/.bashrc
    export SPARK_HOME=home/lin/spark/spark-2.4.4-bin-hadoop2.7
    export PATH=${SPARK_HOME}/bin:$PATH

激活配置:

source ~/.bashrc

最后一步(Python环境可能出错)

pyspark脚本默认调用的是 "python" 这个名, 而ubuntu默认只有"python" 和 "python3"。
所以我们需要做如下软连接,来使得可以输入python, 直接寻找python3.7命令(不要用alias)

ln -s /usr/bin/python3.7 /usr/bin/python

测试

服务端直接输入命令:

pyspark

或远程浏览器输入:

http://192.xx.xx.xx:4040/jobs

远程使用Jupyter连接

Jupyter Notebook 这种方式是代替 pyspark 的 console执行方式的。

安装 Jupyter Notebook:

pip3 install jupyter   
# 若新环境,需要安pip:  apt-get install python3-pip

具体有两种连接方式:
第一种: 配置环境变量(会与 pyspark 的 console 有冲突,这个不建议,略)
第二种: 使用第三方模块 findspark

pip 安装 findspark

pip install findspark                          (Linux服务端)

启动 Jupyter Notebook 服务(--ip必须指定 0.0.0.0),(--allow-root若不加上可能会报错)

jupyter notebook --allow-root --ip 0.0.0.0     (Linux服务端)

下面说的是Jupyter Notebook 客户端(Windows10)
下面两行代码必须放在每个py脚本的第一行

import findspark
findspark.init()

然后才可正常写其他代码

from pyspark import SparkConf, SparkContext

sc = SparkContext(
    master='local[*]',   # 下面会讲这个参数
    appName='myPyspark', # 随便起名
) 
# 这句话,就把 spark启动起来了,然后才可以通过浏览器访问了。 4040
# 如果你 python魔法玩的6,那么提到上下文,你应该会自动想到 with语句 (__enter__,__exit__)
# 不写参数,本地运行,这样也是可以的,  sc = SparkContext() 

raw_data = [1,2,3]
rdd_data = sc.parallelize(raw_data)  # python列表类型 转 spark的RDD
print(rdd_data)
raw_data = rdd_data.collect()        # spark的RDD 转回到 python列表类型
print(raw_data)

sc.stop()    # 关闭spark, 同理,浏览器也就访问不到了。

解释 SparkContext 的 master参数:

  1. "local" : 表示只用一个线程,本地运行。
  2. "local[*]" : 表示用(cpu的个数)个线程,本地运行。
  3. "local[n]" : 表示用n个线程,本地运行。
  4. "spark://ip:host" : 连其他集群

回顾环境问题 并 解释 "本地" 的概念:

  1. 在 Linux 中 安装了 Spark全套环境。
  2. 在 Linux 中 安装了 Jupyter, 并启动了 Jupyter Notebook 服务。
  3. 在 Win10 中 远程连接 Linux中的 "Jupyter Notebook"服务 写业务代码(相当于客户端连接)

所以, 之前所说的 "本地", 这个词归根结底是相对于 Linux来说的,我们写代码一直操作的是Linux。

通常使用spark-submit

首先:我们自己编写一个包含各种 pyspark-API 的 xx.py 脚本
如果:你用了我上面推荐的 Jupyter Notebook,你会发现文件是.ipynb格式,可以轻松转.py
image.png
最后提交py脚本:

spark-submit --master local[*] --name myspark /xx/xx/myspark.py

# 你会发现 --master 和 --name  就是上面我们代码中配置的选项,对号入座写入即可。
# /xx/xx/myspark.py 就是 py脚本的绝对路径。 喂给spark,让他去执行。即可。

Standalone部署Spark

介绍:

Standalone部署需要同时启动:
    master端
    slave 端 
按着下面配置,最后一条  ./start-all.sh 即可同时启动。

查看 JAVA_HOME环境变量。

echo $JAVA_HOME 

# 记住结果,复制出来

进入conf目录,做一些配置(conf和spark中的bin目录同级):

cp spark-env.sh.template spark-env.sh
vi spark-env.sh:(里面写)
    JAVA_HOME=上面的结果 

cp slaves.template slaves
vi slaves: (localhost改成本机机器名)
    lin

上面配置完毕后,进入sbin目录(和上面的conf在一个目录中)

./start-all.sh          # 启动

# 若提示权限错误,继续往下看(支线)
sudo passwd root              # 激活ubuntu的root用户,并设置密码
vi /etc/ssh/sshd_config:
    PermitRootLogin yes       # 任意位置添加这个(此选项之前可能是存在的注释后再添加)
service ssh restart

启动没报错,会给你弹出一条绝对路径的日志文件 xxx

cat xxx         # 即可看见启动状态 ,各种日志信息

其中有几条信息:
    Successfully started service 'WorkerUI' on port 8082  (浏览器访问 8082端口)
    Successfully registered with master spark://lin:7077  (代码上下文访问)
其中,有些信息可能未打印出来: 建议浏览器中:( 8080-8082 )端口都可以尝试一下。        

输入命令,查看启动状态:

jps             # 若同时有 worker 和 master 说明启动成功

测试:

pyspark --master spark://lin:7077

# WebUI 的 Worker端,就可看见有 一个Job被添加了进来

YARN部署Spark

配置:

echo $HADOOP_HOME 
    # 我的是 /home/lin/hadoop/hadoop-2.7.7
    
进入spark解压包的路径的 conf 目录中:
vi spark-env.sh:   ( etc/hadoop前面就是刚才 echo出来的,  etc/hadoop大家都是一样的)
    HADOOP_CONF_DIR=/home/lin/hadoop/hadoop-2.7.7/etc/hadoop

启动spark:

spark-submit --master yarn --name myspark  script/myspark.py
# 注意 --master 的值改成了 yarn , 其他不变。

或者你可以:
     pyspark --master yarn     
看到启动成功,说明配置成功

Spark历史服务配置

痛点:有时我们的spark上下文 stop后,WebUI就不可访问了。
若有未完成,或者历史信息, 也就看不到了。
这时我们配置 history 服务就可在 context stop后,仍可查看 未完成job。

预新建一个HDFS目录myhistory (根路径下),下面用得到:

hadoop fs -mkdir /myhistory        

首先,进入 spark解压包的 conf目录下:

cp spark-defaults.conf.template spark-defaults.conf

vi spark-defaults.conf: (解开如下注释, lin本机名称, 放在HDFS的根路径下的myhistory)
    spark.eventLog.enabled           true
    spark.eventLog.dir               hdfs://lin:8020/myhistory
    
vi spark-env.sh:  (我们之前 把template 复制过一次,所以这次直接编辑即可)
    SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://lin:8020/myhistory"

启动(进入 spark解压包的 sbin目录下):

./start-history-server.sh

# cat 输入的信息(日志文件)。 即可查看是否启动成功
# WebUI默认是 :http://192.168.0.108:18080/

测试:

浏览器中访问History WebUI: http://192.168.0.108:18080/
发现啥也没有: 这是正常的,因为我们还没运行 spark context主程序脚本。
---------------------------------------------------------------------
运行spark-context主程序脚本:
spark-submit script/myspark.py
    # 这个脚本是随便写的,没什么意义。 不过里面有个我们常用的一个注意事项!!!
    # 我的这个脚本的 context 用完,被我 stop了
    # 所以我们访问不到它的运行状态的 Spark Context 的 WebUI
    
    # 但是我们刚才辛辛苦苦配置Spark history 服务,并启动了它。
    # 所以 context的信息,被写入了我们刚才配置的 Spark history 中
    # 所以 我们再次访问 Spark history WebUI 即可看到有内容被写入进来。
---------------------------------------------------------------------
再次访问History WebUI: http://192.168.0.108:18080/
你就会发现,里面有内容了(spark history服务已经为我们干活了)~~~~   

免密码登录

环境Ubuntu(CentOS应该也可,很少用)
免密码登录设置:

cd ~
ssh-keygen -t rsa -P ""
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

注意几种情况:

你如果是root用户,那么你需要切换到 /root/ 执行上面的命令
如果是普通用户, 那么你需要切换到 /home/xxx/ 执行上面的命令

这个要特别注意一下,有时候用 sudo -s ,路径是没有自动切换的。
需要我们自己手动切换一下 "家" 路径

自定义脚本启动服务

下面内容仅供个人方便, shell不熟,用py脚本了, 你随意。
vi start.py: (此脚本用于启动上面配置的 HDFS,YARN,SparkHistory 和 Jupyter Notebook)

import os
import subprocess as sub

###### 启动  HDFS + YARN ###############
hadoop_path = os.environ['HADOOP_HOME']
hadoop_sbin = os.path.join(hadoop_path, 'sbin')

os.chdir(hadoop_sbin)
sub.run('./start-dfs.sh')
sub.run('./start-yarn.sh')

###### 启动 SparkHistory ##############
spark_path = os.environ['SPARK_HOME']
spark_sbin = os.path.join(spark_path, 'sbin')
os.chdir(spark_sbin)
sub.run('./start-history-server.sh')

###### 启动  Jupyter Notebook ###############
# home_path = os.environ['HOME']
home_path = '/home/lin'

os.chdir(home_path)
sub.run('jupyter notebook --allow-root --ip 0.0.0.0'.split())

之后每次重启,就不用进入每个目录去启动了。直接一条命令:

sudo python start.py
nohup hive --service metastore &

查看本脚本启动相关的WebUI:

HDFS:            http://192.168.0.108:50070/
YARN:            http://192.168.0.108:8088/
SparkHistory:    http://192.168.0.108:18080/

另附其他 WebUI:

spark:           http://192.168.0.108:4040/

standalone启动指定的端口(如果你使用的 standalone方式,而不是local,可能用到如下端口):

pyspark --master spark://lin:7077
阅读 567更新于 2019-11-05

推荐阅读
目录