1.概述
這篇部落格是接著《高可用Hadoop平臺》系列講,本篇部落格是為後面用 Hive 來做資料統計做準備的,介紹如何在 Hadoop HA 平臺下整合高可用的 Hive 工具,下面我打算分以下流程來贅述:
- 環境準備
- 整合並配置 Hive 工具
- 使用 Java API 開發 Hive 程式碼
下面開始進行環境準備。
2.環境準備
Hive版本:《Hive-0.14》
HAProxy版本:《HAProxy-1.5.11》
注:前提是 Hadoop 的叢集已經搭建完成,若還沒用完成叢集搭建,可以參考《配置高可用的Hadoop平臺》
需要安裝的工具,我們已經準備好了,接下來給出 Hive 搭建的結構圖,如下圖所示:
這裡由於叢集資源有限,所以將 HAProxy1 配置在 NNA 節點,HAProxy2 配置在 NNS 節點,Hive1,Hive2,Hive3分別配置在 DN1,DN2,DN3 節點。如下表所示:
伺服器 | 角色 |
NNA | HAProxy1 |
NNS | HAProxy2 |
DN1 | Hive1 |
DN2 | Hive2 |
DN3 | Hive3 |
我們將下載好的 Hive 安裝包和 HAProxy 安裝包用 scp 命令,參考上表格分別分發到對應的節點。
注:hive 指定的 HDFS 必須是相同的,否則,統計的資料來源不同,那麼統計是沒有意義的。
3.整合並配置 Hive 工具
HAProxy 是一款提供高可用性、負載均衡以及基於 TCP(第四層)和 HTTP(第七層)應用的代理軟體,HAProxy 是完全免費的、藉助 HAProxy 可以快速並且可靠的提供基於TCP 和 HTTP 應用的代理解決方案。HAProxy 在這裡的作用起一個代理功能,讓 Hive Server 負載均衡;這裡我們分別在 NNA 和 NNS 節點都搭建 HAProxy ,是為了防止一個 HAProxy 代理容易引發單點問題。考慮到高可用性,這裡我們多用一個節點來承擔類似於 HDFS HA 方案中的 standby 角色。
3.1系統環境
首先,在 NNA 和 NNS 節點搭建 HAProxy 工具,這裡我們需要先檢查下系統環境,因為 HAProxy 工具包需要編譯安裝。這裡我們安裝必要的依賴組建,命令如下所示:
# 安裝 gcc 元件 [hadoop@nna]$ sudo yum -y install gcc* # 安裝 SSL [hadoop@nna]$ sudo yum -y install openssl-devel pcre-devel
然後,解壓並進入到 haproxy 目錄檔案中,命令如下:
[hadoop@nna]$ tar -zxvf haproxy-1.5.11.tar.gz && cd haproxy-1.5.11
接著,我們開始編譯安裝 haproxy 元件,命令如下所示:
[hadoop@nna]$ make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1 [hadoop@nna]$ make install
安裝完成後,我們輸入如下命令,看是否安裝成功。
[hadoop@nna]$./haproxy -vv
若現實如下資訊,即表示安裝成功。內容如下:
HA-Proxy version 1.5.11 2015/01/31 Copyright 2000-2015 Willy Tarreau <w@1wt.eu> Build options : TARGET = linux26 CPU = generic CC = gcc CFLAGS = -O2 -g -fno-strict-aliasing OPTIONS = Default settings : maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200 Encrypted password support via crypt(3): yes Built without zlib support (USE_ZLIB not set) Compression algorithms supported : identity Built without OpenSSL support (USE_OPENSSL not set) Built without PCRE support (using libc's regex instead) Built with transparent proxy support using: IP_TRANSPARENT IP_FREEBIND Available polling systems : epoll : pref=300, test result OK poll : pref=200, test result OK select : pref=150, test result OK Total: 3 (3 usable), will use epoll.
3.2配置 HAProxy
在 haproxy 目錄下,我們新建一個 config.cfg 的配置檔案,填寫如下內容:
global daemon nbproc 1 defaults mode tcp #mode { tcp|http|health },tcp 表示4層,http表示7層,health僅作為健康檢查使用 retries 2 #嘗試2次失敗則從叢集摘除 option redispatch #如果失效則強制轉換其他伺服器 option abortonclose #連線數過大自動關閉 maxconn 1024 #最大連線數 timeout connect 1d #連線超時時間,重要,hive查詢資料能返回結果的保證 timeout client 1d #同上 timeout server 1d #同上 timeout check 2000 #健康檢查時間 log 127.0.0.1 local0 err #[err warning info debug] listen admin_stats #定義管理介面 bind 0.0.0.0:1090 #管理介面訪問IP和埠 mode http #管理介面所使用的協議 maxconn 10 #最大連線數 stats refresh 30s #30秒自動重新整理 stats uri / #訪問url stats realm Hive\ Haproxy #驗證視窗提示 stats auth admin:123456 #401驗證使用者名稱密碼 listen hive #hive後端定義 bind 0.0.0.0:10001 #ha作為proxy所繫結的IP和埠 mode tcp #以4層方式代理,重要 balance leastconn #排程演算法 'leastconn' 最少連線數分配,或者 'roundrobin',輪詢分配 maxconn 1024 #最大連線數 server hive_1 10.211.55.18:10000 check inter 180000 rise 1 fall 2 server hive_2 10.211.55.15:10000 check inter 180000 rise 1 fall 2 server hive_3 10.211.55.17:10000 check inter 180000 rise 1 fall 2 #釋義:server 主機代名(你自己能看懂就行),IP:埠 每180000毫秒檢查一次。也就是三分鐘。 #hive每有10000埠的請求就會建立一個log,設定短了,/tmp下面會有無數個log檔案,刪不完。
接著,我們在 NNS 也做相同的操作,搭建 HAProxy。
3.3搭建 Hive
在 DN1 節點上,我們先配置 Hive 的環境變數,配置內容如下:
export HIVE_HOME=/home/hadoop/hive-0.14.0-bin export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZK_HOME/bin:$HIVE_HOME/bin
接著,我們配置3個重要檔案。
-
hive-env.sh
# Set HADOOP_HOME to point to a specific hadoop install directory HADOOP_HOME=/home/hadoop/hadoop-2.6.0
-
hive-log4j.properties
# Define some default values that can be overridden by system properties hive.log.threshold=ALL hive.root.logger=INFO,DRFA hive.log.dir=/home/hadoop/logs/hive hive.log.file=hive.log
-
hive-site.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <name>datanucleus.fixedDatastore</name> <value>false</value> </property> <property> <name>hive.metastore.execute.setugi</name> <value>true</value> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>/home/hive/warehouse</value> <description>location of default database for the warehouse </description> </property> <!-- metadata database connection configuration --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://10.211.55.26:3306/hive?useUnicode=true&characterEncoding=UTF-8&createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> <description>username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>root</value> <description>password to use against metastore database</description> </property> </configuration>
注:由於我這裡配置的 Hive 後設資料倉庫地址是 Mysql ,所以我們在啟動 Hive 之前,得將 Mysql 的驅動包放到 Hive 目錄的 lib 資料夾下。
然後,在 DN2 和 DN3 節點做相同的操作。
3.4啟動服務
- 啟動 hive 服務
這裡,我們先啟動 Hive 的第三方服務,命令如下所示:
[hadoop@dn1]$hive --service hiveserver &
注:DN1,DN2 和 DN3 節點都需要啟動該服務。
- 啟動代理服務 haproxy
在 hive 的服務成功啟動後,我們在到 NNA 和 NNS 節點分別啟動 HAProxy 代理服務,命令如下所示:
[hadoop@nna haproxy-1.5.11]$ ./haproxy -f config.cfg
到這裡,如果沒有出錯,整個高可用的 Hive 工具就搭建完成了。
3.5異常
若是我們在搭建的過程中遇到異常怎麼辦?首先,我們來逐個排查,我們先啟動 hive 服務,若是在啟動中報錯,或是一直卡在啟動中,我可以到 hive 的啟動日誌中檢視具體原因,根據丟擲的異常,我們做對應的處理就可以了;其次,在啟動 haproxy 服務時,若是出現異常,我們根據它報錯的資訊,做對應的處理即可。要冷靜,莫慌!
- 常見異常:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Access denied for user 'root'@'dn1' to database 'metastore'
- 解決辦法:
這是因為mysql資料庫使用者root 的許可權不足,賦予許可權
grant all on metastore.* to 'root'@'dn1' identified by 'root';
flush privileges;
4.Java API使用
搭建好平臺後,我們得驗證平臺是否可用,下面,我們用 Java API 來驗證其 HA 是否可用。下面是寫得一個測試程式碼,用來測試平臺是否可用,程式碼表達的意圖是:建立表,然後顯示錶結構。程式碼如下所示:
/** * */ package cn.hdfs.hive.example; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** * @author dengjie * @date 2015年3月26日 * @description 提供一個JDBC訪問hive的原型,若用在實際業務中,可擴充該類。 */ public class HiveVisit { static { // 註冊jdbc驅動 try { Class.forName("org.apache.hadoop.hive.jdbc.HiveDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // 設定 NNA 和 NNS 的連線資訊 private static String[] url = new String[] { "jdbc:hive://10.211.55.29:10001/default", "jdbc:hive://10.211.55.26:10001/default" }; public static void main(String[] args) throws Exception { System.setProperty("hadoop.home.dir", "/Users/dengjie/HDFS/hadoop-2.5.1"); Connection conn = null; for (int i = 0; i < url.length; i++) { try { // 建立連線 conn = DriverManager.getConnection(url[i], "", ""); if (!conn.isClosed()) {// 連線成功,即返回連線物件 break; } } catch (Exception ex) { ex.printStackTrace(); } } Statement st = conn.createStatement(); String tableName = "stu"; // 刪除表 st.executeQuery("drop table " + tableName); // 建立表 ResultSet rs = st.executeQuery("create table " + tableName + "(" + "id string," + "name string," + "sex string" + ")" + "row format delimited " + "fields terminated by ',' " + "stored as textfile"); // 顯示所有的表 String sql = "show tables"; System.out.println("running:" + sql); rs = st.executeQuery(sql); if (rs.next()) { System.out.println(rs.getString(1)); } // 得到表資訊 sql = "describe " + tableName; System.out.println("running:" + sql); rs = st.executeQuery(sql); while (rs.next()) { System.out.println(rs.getString(1) + "\t" + rs.getString(2)); } // 關閉資源 rs.close(); st.close(); conn.close(); } }
結果展示,內容如下:
running:show tables
stu
running:describe stu
id string
name string
sex string
5.總結
- 在啟動 haproxy 代理服務之前,切記 hive 服務是否正常啟動。
- 在啟動 hive 服務是,確保 hadoop 叢集執行正常。
6.結束語
這篇部落格就和大家分享到這裡,若在研究的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!