2016年8月15日

Apache Zeppelin 測試記錄

Zeppelin 是 Big Data 資料分析的筆記本,以網頁為介面,筆記本可以共用、分享、共筆,支援 scala, java, shell script, markdown, SparkSQL 等語法,可以直接在網頁筆記本上面,製作筆記、執行並即時取得結果,在資料分析後,可以將結果直接以圖表方式展現出來,甚至還可以自訂自己的語法。

目前 Zeppelin git 的版本是 0.6,還沒有正式 release,脫離 incubator 的階段,成為一個成熟的產品。

Zeppelin Installation

安裝一些必要的套件

rpm -ivh jdk-8u72-linux-x64.rpm
yum install git nodejs npm libfontconfig

# install maven
wget http://www.eu.apache.org/dist/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.tar.gz
sudo tar -zxf apache-maven-3.3.3-bin.tar.gz -C /usr/local/
sudo ln -s /usr/local/apache-maven-3.3.3/bin/mvn /usr/local/bin/mvn

直接由 git 取得 zeppelin 的 source code,然後進行編譯。

git clone https://github.com/apache/incubator-zeppelin

mv incubator-zeppelin zeppelin
mv zeppelin /usr/local/

cd /usr/local/zeppelin

mvn install -DskipTests

zeppelin-web 在建構過程中會出錯

首先要修改 zeppelin-web/pom.xml,把以下這個區塊的 plugin 註解掉:

<plugin>
        <groupId>com.github.eirslett</groupId>
....
</plugin>
cd zeppelin-web
mvn clean

npm install
./bower --allow-root install
./grunt build

mvn install -DskipTests

cd ..

mvn install -DskipTests

mvn package -Pspark-1.5 -Dhadoop.version=2.2.0 -Phadoop-2.2 -DskipTests

編譯後的結果會看到

[INFO] Reactor Summary:
[INFO]
[INFO] Zeppelin .......................................... SUCCESS [23.566s]
[INFO] Zeppelin: Interpreter ............................. SUCCESS [21.797s]
[INFO] Zeppelin: Zengine ................................. SUCCESS [9.997s]
[INFO] Zeppelin: Display system apis ..................... SUCCESS [5.388s]
[INFO] Zeppelin: Spark dependencies ...................... SUCCESS [33.753s]
[INFO] Zeppelin: Spark ................................... SUCCESS [10.863s]
[INFO] Zeppelin: Markdown interpreter .................... SUCCESS [4.452s]
[INFO] Zeppelin: Angular interpreter ..................... SUCCESS [3.246s]
[INFO] Zeppelin: Shell interpreter ....................... SUCCESS [3.275s]
[INFO] Zeppelin: Hive interpreter ........................ SUCCESS [6.779s]
[INFO] Zeppelin: HBase interpreter ....................... SUCCESS [6.773s]
[INFO] Zeppelin: Apache Phoenix Interpreter .............. SUCCESS [8.796s]
[INFO] Zeppelin: PostgreSQL interpreter .................. SUCCESS [4.135s]
[INFO] Zeppelin: JDBC interpreter ........................ SUCCESS [4.550s]
[INFO] Zeppelin: Tajo interpreter ........................ SUCCESS [4.240s]
[INFO] Zeppelin: Flink ................................... SUCCESS [7.043s]
[INFO] Zeppelin: Apache Ignite interpreter ............... SUCCESS [4.051s]
[INFO] Zeppelin: Kylin interpreter ....................... SUCCESS [3.608s]
[INFO] Zeppelin: Lens interpreter ........................ SUCCESS [5.966s]
[INFO] Zeppelin: Cassandra ............................... SUCCESS [19.541s]
[INFO] Zeppelin: Elasticsearch interpreter ............... SUCCESS [4.712s]
[INFO] Zeppelin: Alluxio interpreter ..................... SUCCESS [4.832s]
[INFO] Zeppelin: web Application ......................... SUCCESS [2.911s]
[INFO] Zeppelin: Server .................................. SUCCESS [47.256s]
[INFO] Zeppelin: Packaging distribution .................. SUCCESS [2.663s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4:15.422s
[INFO] Finished at: Tue Mar 08 16:25:02 CST 2016
[INFO] Final Memory: 101M/289M
[INFO] ------------------------------------------------------------------------

調整 zeppelin 的設定

cp /usr/local/zeppelin/conf/zeppelin-env.sh.template /usr/local/zeppelin/conf/zeppelin-env.sh
cp /usr/local/zeppelin/conf/zeppelin-site.xml.template /usr/local/zeppelin/conf/zeppelin-site.xml

chmod 755 /usr/local/zeppelin/conf/zeppelin-site.xml

為了避免跟後面的 ambari 網頁介面的 port 衝突,我們修改 zeppelin 的 port 設定

vi /usr/local/zeppelin/conf/zeppelin-site.xml
# 將 zeppelin.server.port 改為 8000

<property>
  <name>zeppelin.server.port</name>
  <value>8000</value>
  <description>Server port.</description>
</property>

為了讓 java 可以直接使用 TCP IPv4,必須 disable CentOS 的 ipv6。

vi /etc/sysctl.conf
增加一行
net.ipv6.conf.all.disable_ipv6 = 1

vi /etc/sysconfig/network
增加一行
NETWORKING_IPV6=no

vi /etc/sysconfig/network-scripts/ifcfg-eth0
vi /etc/sysconfig/network-scripts/ifcfg-eth1
檢查要有此行
IPV6INIT="no"

echo 'options ipv6 disable=1' > /etc/modprobe.d/disable-ipv6.conf
service ip6tables stop; chkconfig ip6tables off

reboot

停掉 CentOS 7 的預設 firewall

systemctl stop firewalld
systemctl disable firewalld

啟動 zeppelin

/usr/local/zeppelin/bin/zeppelin-daemon.sh start

Log dir doesn't exist, create /usr/local/zeppelin/logs
Pid dir doesn't exist, create /usr/local/zeppelin/run
Zeppelin start                                             [  OK  ]

停止 zeppelin

/usr/local/zeppelin/bin/zeppelin-daemon.sh stop

Zeppelin 的主畫面如下,如果在右上角,看到的不是 "Connected",這就表示還需要安裝 Spark, Hadoop 等套件,要繼續往下安裝 Ambari,才能正常使用 Zeppelin。

Ambari for CentOS 7

如果直接連結 Zeppelin 網頁 http://192.168.1.24:8000/ ,會看到中間的內容是空白的,而且右上角的連線資訊是 "Disconnected",只有安裝 Zeppelin 還不夠。

我們還需要安裝 HDFS,Spark 等等後端的工具,但一個一個安裝非常地辛苦,有個簡便的安裝套件 ambari 可以使用,Apache Ambari 是用來管理並維護 Hadoop cluster 環境,他也提供了一個簡易的網頁介面,可以直接安裝 Hadoop Cluster 環境。

參考 如何使用Ambari部署HDP 以及 Ambari Installation in RHEL/CentOS/Oracle Linux 7 的說明,我們就能將 ambari 在 CentOS 7 設定好。因為只是一開始的測試用途,我並沒有安裝很多台機器,只安裝了一台,跟 Zeppelin 放在一起。

wget -nv http://public-repo-1.hortonworks.com/ambari/centos7/2.x/updates/2.1.0/ambari.repo -O /etc/yum.repos.d/ambari.repo

yum repolist

yum install ambari-server

# server 設定, 需要檢查 /etc/hosts 裡面有沒有 domain name 的對應設定,要將 hostname: zeppelin 對應到實際的 IP
vi /etc/hosts
192.168.1.24    zeppelin

ambari-server setup

# 啟動 ambari
ambari-server start

安裝並啟動 ambari-server 還不夠,我們還需要安裝 ambari-agent。

yum install ambari-agent

# 測試機器的 hostname 是 zeppelin
ambari-agent reset zeppelin

ambari-agent start

再來就是利用網頁 http://192.168.1.24:8080/ 以帳號:admin 密碼: admin,點擊主頁面上的“Launch Install Wizard”按鈕後,進入安裝程序。

我只填寫了一個節點: zeppelin,選擇服務是 HDFS,Zookeeper,Spark,Kafka,YARN,基本上都沒有調整什麼預設的設定,就可以安裝完成。


用Ambari跟Zeppelin來玩Apache Spark 提供了一個安裝 Zeppelin 的簡便方法,就是透過 Ambari service for Apache Zeppelin notebook 的協助,直接在 Ambari 安裝 Zeppelin,相信這個方法遇到的問題會少一點。以下紀錄一下他的做法,但我們還沒有實際測試過。

#下載zeppelin到Ambari
[sudouser@server1]$ VERSION=`hdp-select status hadoop-client | sed 's/hadoop-client - \([0-9]\.[0-9]\).*/\1/'`
[sudouser@server1]$ sudo git clone https://github.com/hortonworks-gallery/ambari-zeppelin-service.git   /var/lib/ambari-server/resources/stacks/HDP/$VERSION/services/ZEPPELIN

#重開ambari
[sudouser@server1]$ sudo su -
[root@server1]$ ambari-server restart

# 從開好之後從左邊最下面"Actions"選單"Add Service"
# 多了zeppelin的選項可以選,選擇之後一直Next就行了

Zeppelin json 異常

在測試 Zeppelin Tutorial 裡面的 Spark 功能的時候,一直遇到錯誤訊息。後來發現是這個原因:Apache Zeppelin & Spark 解析Json異常

處理方法,就是將 Zeppelin 使用的 Jackson jar 檔的版本都由 2.5 換成 2.4,然後重新啟動 Zeppelin 就可以了。

ls -al /usr/local/zeppelin/zeppelin-server/target/lib/jackson*
-rw-r--r-- 1 root root   39815  3月  8 16:24 jackson-annotations-2.5.0.jar
-rw-r--r-- 1 root root  229998  3月  8 16:24 jackson-core-2.5.3.jar
-rw-r--r-- 1 root root 1143162  3月  8 16:24 jackson-databind-2.5.3.jar

# 找到這些 2.4 版的 jackson jar,然後替換掉這些檔案
-rw-r--r-- 1 root root   38597 11月 25  2014 jackson-annotations-2.4.4.jar
-rw-r--r-- 1 root root  225302  3月  9 14:17 jackson-core-2.4.4.jar
-rw-r--r-- 1 root root 1076926  3月  9 14:17 jackson-databind-2.4.4.jar

Zeppelin Tutorial

參考 Zeppelin Tutorial 的說明,我們先建立一個新的 Notebook: test。

%sh 是直接執行 shell command

%sh
echo $PATH

接下來,先取得測試需要用的資料 bank-full.csv

%sh
rm /root/bank.zip
rm -rf /root/data
cd ~
wget http://archive.ics.uci.edu/ml/machine-learning-databases/00222/bank.zip
mkdir data
unzip bank.zip -d data
#rm bank.zip

因為 Zeppelin 預設是執行 scala 程式,所以我們可以直接呼叫 Spark 的 程式,下面的程式會將 csv 讀取進來,然後以 map 的方式對應到 Bank 這個物件上,再轉換成 DataFrame,產生 Temp Table。

val sqlContext = new org.apache.spark.sql.SQLContext(sc)

val bankText = sc.textFile(s"/root/data/bank-full.csv")

case class Bank(age:Integer, job:String, marital : String, education : String, balance : Integer)

// split each line, filter out header (starts with "age"), and map it into Bank case class

val bank = bankText.map(s=>s.split(";")).filter(s=>s(0)!="\"age\"").map(
    s=>Bank(s(0).toInt, 
            s(1).replaceAll("\"", ""),
            s(2).replaceAll("\"", ""),
            s(3).replaceAll("\"", ""),
            s(5).replaceAll("\"", "").toInt
        )
)

// convert to DataFrame and create temporal table
bank.toDF().registerTempTable("bank")

接下來可以用 %sql 產生圖表

%sql
select age, count(1) value
from bank
where age<30
group by age
order by age

也可以讓 sql 讀取外部的參數,這個功能在 Zeppelin 稱為 Dynamic Form

%sql
select age, count(1) value
from bank
where age<${maxAge=30}
group by age
order by age

Dynamic Form 也可以做成 select 下拉選單的方式,調整參數。

%sql
select age, count(1)
from bank
where marital="${marital=single,single|divorced|married}"
group by age order by age

References

Spark交互式分析平台Apache Zeppelin的安裝

incubator-zeppelin/README.md

Apache Zeppelin安裝及介紹

How-to: Install Apache Zeppelin on CDH

【數據可視化】Zeppelin JDBC 數據可視化(WEB方式)