1. 程式人生 > >spark JAVA 開發環境搭建及遠程調試

spark JAVA 開發環境搭建及遠程調試

soft 匯總 bubuko tab 2.7 cati builder hadoop2.7 本地

spark JAVA 開發環境搭建及遠程調試

以後要在項目中使用Spark 用戶昵稱文本做一下聚類分析,找出一些違規的昵稱信息。以前折騰過Hadoop,於是看了下Spark官網的文檔以及 github 上 官方提供的examples,看完了之後決定動手跑一個文本聚類的demo,於是有了下文。

1. 環境介紹

本地開發環境是:IDEA2018、JDK8、windows 10。遠程服務器 Ubuntu 16.04.3 LTS上安裝了spark-2.3.1-bin-hadoop2.7

看spark官網介紹,有兩種形式(不是Spark Application Execution Mode)來啟動spark

  1. Running the Examples and Shell

    比如說./bin/pyspark --master local[2]啟動的是一個交互式的命令行界面,可以在4040端口查看作業。

  2. Launching on a Cluster

    spark 集群,有多種部署選項:Standalone。另外還有:YARN,Mesos(將集群中的資源將由資源管理器來管理)。

    對於Standalone,./sbin/start-master.sh 啟動Master,通過8080端口就能看到:集群的情況。

技術分享圖片

再通過./sbin/start-slave.sh spark://panda-e550:7077 啟動slave:Alive Workers 就是啟動的slave。

技術分享圖片

執行jps:看到Master和Worker:

~/spark-2.3.1-bin-hadoop2.7$ jps
45437 Master
50429 Worker

下面介紹一下在本地windows10 環境下寫Spark程序,然後連接到遠程的這臺Ubuntu機器上的Spark上進行調試。

2. 一個簡單的開發環境

創建Maven工程,根據官網提供的Spark Examples 來演示聚類算法(JavaBisectingKMeansExample )的運行過程,並介紹如何配置Spark調試環境。

2.1添加maven 依賴:

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.11</artifactId>
    <version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-mllib -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-mllib_2.11</artifactId>
    <version>2.3.1</version>
    <!--<scope>runtime</scope>-->
</dependency>

2.2 編寫代碼:

package net.hapjin.spark;

import org.apache.spark.ml.clustering.BisectingKMeans;
import org.apache.spark.ml.clustering.BisectingKMeansModel;
import org.apache.spark.ml.linalg.Vector;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;

public class JavaBisectingKMeansExample {
    public static void main(String[] args) {
//        SparkSession spark = SparkSession.builder().appName("JavaBisectingKMeansExample").getOrCreate();
        SparkSession spark = SparkSession.builder().appName("JavaBisectingKMeansExample").master("spark://xx.xx.129.170:7077").getOrCreate();
//        Dataset<Row> dataset = spark.read().format("libsvm").load(".\\data\\sample_kmeans_data.txt");
        Dataset<Row> dataset =     spark.read().format("libsvm").load("hdfs://172.25.129.170:9000/user/panda/sample_kmeans_data.txt");
//        Dataset<Row> dataset = spark.read().format("libsvm").load("file:///E:/git/myown/test/spark/example/data/sample_kmeans_data.txt");
        // Trains a bisecting k-means model.
        BisectingKMeans bkm = new BisectingKMeans().setK(2).setSeed(1);
        BisectingKMeansModel model = bkm.fit(dataset);

        // Evaluate clustering.
        double cost = model.computeCost(dataset);
        System.out.println("Within Set Sum of Squared Errors = " + cost);
        // Shows the result.
        System.out.println("Cluster Centers: ");
        Vector[] centers = model.clusterCenters();
        for (Vector center : centers) {
            System.out.println(center);
        }
        // $example off$
        spark.stop();
    }
}

2.3 配置遠程調試環境

在IDEA中,"Run"-->"Edit Configurations"-->"Template"--->"Remote",點擊 "+"號:

技術分享圖片

報錯:

Could not locate executable null\bin\winutils.exe

去這個github下載對應的Hadoop版本的winutils.exe。

技術分享圖片

配置windows10環境變量:HADOOP_HOME,並將該環境變量添加到 Path 環境變量下%HADOOP_HOME%\bin

再次Debug調試,成功進入斷點:(如果報拒絕連接的錯誤,修改一下 conf/spark-env.sh 指定SPARK_LOCAL_IP為機器的IP地址,然後再 修改 /etc/hosts 文件 將主機名與機器IP地址相對應即可)

技術分享圖片

但是到後面執行讀取文件時,明明文件就在windows的該路徑下,但是就是報錯:

Caused by: java.io.FileNotFoundException: File file:/E:/git/myown/test/spark/example/data/sample_kmeans_data.txt does not exist

嘗試了好幾個路徑寫法,比如這篇stackoverflow,都未果。

//        Dataset<Row> dataset = spark.read().format("libsvm").load(".\\data\\sample_kmeans_data.txt");
        Dataset<Row> dataset = spark.read().format("libsvm").load("file:///E:\\git\\myown\\test\\spark\\example\\data\\sample_kmeans_data.txt");
//        Dataset<Row> dataset = spark.read().format("libsvm").load("file:///E:/git/myown/test/spark/example/data/sample_kmeans_data.txt");

看裏面的解釋:

SparkContext.textFile internally calls org.apache.hadoop.mapred.FileInputFormat.getSplits, which in turn uses org.apache.hadoop.fs.getDefaultUri if schema is absent. This method reads "fs.defaultFS" parameter of Hadoop conf. If you set HADOOP_CONF_DIR environment variable, the parameter is usually set as "hdfs://..."; otherwise "file://".

因為我本地Windows10沒有安裝Hadoop,只是上面提到的下載winutils.exe時,簡單地配置了個 HADOOP_HOME環境變量。所以我也不知道這種遠程調試中讀取本地windows系統上的文件是否可行了。

看來,我只能在遠程服務器上再安裝個Hadoop了,然後把文件上傳到HDFS上。於是,下載Hadoop-2.7.7,解壓安裝(按照官網 偽分布式模式配置安裝),並啟動HDFS:

  $ sbin/start-dfs.sh

jps查看當前服務器上的進程:

panda@panda-e550:~/data/spark$ jps
2435 Master
10181 SecondaryNameNode
11543 Jps
9849 NameNode
3321 Worker
9997 DataNode

其中Master是Spark master;Worker是spark worker;NameNode、DataNode、SecondaryNameNode是Hadoop HDFS的相關進程。把文件上傳到HDFS上:

panda@panda-e550:~/software/hadoop-2.7.7$ ./bin/hdfs dfs -ls /user/panda
Found 2 items
-rw-r--r-- 1 panda supergroup 70 2018-10-30 17:54 /user/panda/people.json
-rw-r--r-- 1 panda supergroup 120 2018-10-30 18:09 /user/panda/sample_kmeans_data.txt

修改一下代碼中文件的路徑:(還是隱藏一下具體的ip吧)

        Dataset<Row> dataset = spark.read().format("libsvm").load("hdfs://xx.xx.129.170:9000/user/panda/sample_kmeans_data.txt");

繼續右擊debug,又報錯:

failed on connection exception: java.net.ConnectException: Connection refused: no further information; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused

按照提示的鏈接看:應該是下面這個問題。

  1. If the error message says the remote service is on "127.0.0.1" or "localhost" that means the configuration file is telling the client that the service is on the local server. If your client is trying to talk to a remote system, then your configuration is broken.
  2. Check that there isn‘t an entry for your hostname mapped to 127.0.0.1 or 127.0.1.1 in /etc/hosts (Ubuntu is notorious for this)

cat /etc/hosts 部分內容如下:

127.0.0.1 localhost

172.25.129.170 panda-e550

再看看 hdfs上的配置文件:cat etc/hadoop/core-site.xml

<configuration>
        <property>
                <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
        </property>
</configuration>

在遠程服務器上:

panda@panda-e550:~/software/hadoop-2.7.7$ netstat -anp | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 9849/java
tcp 0 0 127.0.0.1:43162 127.0.0.1:9000 ESTABLISHED 9997/java
tcp 0 0 127.0.0.1:43360 127.0.0.1:9000 TIME_WAIT -
tcp 0 0 127.0.0.1:9000 127.0.0.1:43162 ESTABLISHED 9849/java

因此,出現ConnectException的原因就很明顯了。因此,服務器Hadoop HDFS 9000端口綁定在到環回地址上。那我在windows10上的機器上的IDEA的代碼程序裏面指定:hdfs://172.25.129.170:9000/user/panda/sample_kmeans_data.txt肯定是不行的了。畢竟windows10開發環境機器的ip地址,肯定和安裝Hadoop的遠程服務器的ip地址是不同的。

由於core-site.xml配置的是hdfs://localhost:9000,按理說,把 localhost 改成 ip 地址應該是可以的。但是我采用另一種方案,修改 /etc/hosts中的文件:把原來的127.0.0.1對應的localhost註釋掉,修改成機器的ip地址,如下:

panda@panda-e550:~/software/hadoop-2.7.7$ cat /etc/hosts
# comment this line and add new line for hadoop hdfs
#127.0.0.1      localhost
172.25.129.170 localhost

然後再重啟一下 HDFS進程。此時:

panda@panda-e550:~/software/hadoop-2.7.7$ netstat -anp | grep 9000
tcp 0 0 172.25.129.170:9000 0.0.0.0:* LISTEN 13126/java
tcp 0 0 172.25.129.170:50522 172.25.129.170:9000 ESTABLISHED 13276/java
tcp 0 0 172.25.129.170:50616 172.25.129.170:9000 TIME_WAIT -
tcp 0 0 172.25.129.170:9000 172.25.129.170:50522 ESTABLISHED 13126/java

在windows10 機器的cmd命令行上telnet 一下:發現能成功連接上。因此可以放心debug了。

C:\Users\Administrator.000>telnet 172.25.129.170 9000

最終,整個遠程調試完整跑通:

技術分享圖片

程序輸出:

Within Set Sum of Squared Errors = 0.11999999999994547
Cluster Centers:
[0.1,0.1,0.1]

匯總一下: 啟動spark master 和 slave命令。

./sbin/start-master.sh

./sbin/start-slave.sh spark://panda-e550:7077

http://172.25.129.170:8080/ 查看spark管理界面

啟動hdfs命令(偽分布式)

./sbin/start-dfs.sh

在知乎上看到一個問題:如何更有效地學習開源項目的代碼?,放到這裏供大家參考一下。

原文:https://www.cnblogs.com/hapjin/p/9879002.html

spark JAVA 開發環境搭建及遠程調試