高可用Hadoop平台-集成Hive HAProxy


1.概述

  這篇博客是接着《高可用Hadoop平台》系列講,本篇博客是為后面用 Hive 來做數據統計做准備的,介紹如何在 Hadoop HA 平台下集成高可用的 Hive 工具,下面我打算分以下流程來贅述:

  1. 環境准備
  2. 集成並配置 Hive 工具
  3. 使用 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&amp;characterEncoding=UTF-8&amp;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.結束語

  這篇博客就和大家分享到這里,若在研究的過程當中有什么問題,可以加群進行討論或發送郵件給我,我會盡我所能為您解答,與君共勉!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM