1. 程式人生 > >Impala負載均衡方案——zookeeper

Impala負載均衡方案——zookeeper

由來

之前根據Impala官方的文件嘗試使用haproxy實現impalad節點的負載均衡,但是這種方案存在一些弊端,例如haproxy本身也是單點的,雖然可以通過keeplived實現haproxy的高可用,但是這樣的配置難免有點太重了,實現impala負載均衡的同時還需要多部署兩個元件,增大了系統運維的複雜度。在大資料生態圈中zookeeper是一個必不可少的自身具有高可用保證的元件,本文探討如何使用zookeeper實現impalad的負載均衡。

HS2方案

眾所周知,hiveserver2中可以整合zookeeper實現高可用,畢竟hiveserver2也可以視為無狀態的服務,如果配置了zookeeper則在程序啟動的時候向zk註冊,可以同時註冊多個hiveserver2服務,在jdbc連線的時候hive-jdbc可以識別獲取服務的配置,然後再向這個服務發起連線,hiveserver2註冊時會指定一個zookeeper的註冊的根目錄,每一個節點在註冊的時候在該節點下寫入一個節點,節點名為:

serverUri=db-87.photo.163.org:21050;version=1.2.1;sequence=0000000013

serverUri由hive.server2.thrift.bind.host和hive.server2.thrift.port配置決定的,version等於當前hiveserver2的版本號,sequence保持一個全域性遞增的序列號。

每一個節點的內容如下:

db-87.photo.163.org:21050
cZxid = 0x2500018ab0
ctime = Wed Dec 28 11:22:33 CST 2016
mZxid = 0x2500018ab0
mtime = Wed Dec 28 11:22:33 CST 2016
pZxid = 0x2500018ab0
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x358997ea0460d74
dataLength = 25
numChildren = 0

節點裡面儲存了註冊時的一些資訊,最主要的是第一行服務的IP和埠,這樣在jdbc建立連線的時候客戶端會隨機選擇一個服務節點並且用其資訊替換掉jdbc url中原始的主機和埠資訊,然後再嘗試使用替換之後的url建立連線,如果建立失敗則將其加入到error列表中,繼續隨機獲取下一個節點,直到建立連線成功或者全部服務節點都不可用。

ZK方案

既然hiveserver2原生的帶有這種特性,而impala又可以相容hive-jdbc客戶端,那麼理所當然impala也可以使用這種方案實現負載均衡,現在的問題是impalad在啟動的時候並不會向zookeeper註冊,雖然客戶端提供了該機制,沒有服務端的配合也不可能work,此時,我們的方案是通過不侵入impala程式碼的方式獨立的啟動一個註冊和監控程序,它的作用是為impalad節點註冊,但是由於hiveserver2向zk註冊時建立的是EPHEMERAL型別的臨時節點,所以當session關閉時這個節點也會自動被刪除,這樣客戶端就不能獲取到該服務資訊,因此這個註冊程序必須和impalad程序擁有共同的生命週期(至少不能比impalad的生命週期長)。

我們的做法是建立一個獨立的程序,可以在impalad指令碼啟動的時候隨著impalad程序一塊啟動,該程序啟動時向配置的zookeeper註冊一個節點和改服務的資訊,然後週期的檢查impalad是否存在(目前的方法是通過檢視/proc/pid目錄檢視),如果impalad程序不存在則退出,zookeeper上註冊的臨時節點也隨之被刪除。

該程序直接呼叫hiveserver2的註冊和刪除方法,但是由於HiveServer2中存在的方法都是private的,因此需要使用反射程序變數的設定和函式呼叫。

最後,hiveserver2依賴的配置資訊:

需要註冊到zookeeper的根節點
HIVE_SERVER2_ZOOKEEPER_NAMESPACE("hive.server2.zookeeper.namespace", "hiveserver2",
        "The parent node in ZooKeeper used by HiveServer2 when supporting dynamic service discovery."),

註冊的埠號
HIVE_SERVER2_THRIFT_PORT("hive.server2.thrift.port", 10000,
        "Port number of HiveServer2 Thrift interface when hive.server2.transport.mode is 'binary'."),

註冊的機器IP,如果不指定預設是本機的hostname
HIVE_SERVER2_THRIFT_BIND_HOST("hive.server2.thrift.bind.host", "",
        "Bind host on which to run the HiveServer2 Thrift service."),          

註冊的zookeeper地址,可以使多個地址通過‘,’分割
HIVE_ZOOKEEPER_QUORUM("hive.zookeeper.quorum", "",
        "List of ZooKeeper servers to talk to. This is needed for: \n" +
        "1. Read/write locks - when hive.lock.manager is set to \n" +
        "org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveLockManager, \n" +
        "2. When HiveServer2 supports service discovery via Zookeeper.\n" +
        "3. For delegation token storage if zookeeper store is used, if\n" +
        "hive.cluster.delegation.token.store.zookeeper.connectString is not set"),

註冊的zookeeper的埠號
HIVE_ZOOKEEPER_CLIENT_PORT("hive.zookeeper.client.port", "2181",
        "The port of ZooKeeper servers to talk to.\n" +
        "If the list of Zookeeper servers specified in hive.zookeeper.quorum\n" +
        "does not contain port numbers, this value is used.")

可以通過將這些配置資訊儲存在一個hive-site.xml檔案下,並且在程序啟動時指定該檔案在程序的classpath下,或者在啟動引數中指定–hiveconf設定這些引數,這樣可以脫離配置檔案進行啟動。

程式碼地址:點這裡
使用例項:

java -cp .:target/impala-tools-0.0.1.jar:./tools/lib/* com.netease.impala.service.RegisterImpalaTools -pid 12345 --hiveconf hive.server2.zookeeper.namespace=impala-dev --hiveconf hive.server2.thrift.port=16124 --hiveconf hive.server2.thrift.bind.host=db-87.photo.163.org --hiveconf hive.zookeeper.quorum=classb-bigdata4.server.163.org --hiveconf hive.zookeeper.client.port=2181

註冊之後可以直接在beeline上建立jdbc連線,使用例項:

!connect jdbc:hive2://classb-bigdata4.server.163.org:2181/default;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=impala-dev;principal=impala/[email protected];

最後需要注意的是不太的impalad對外部客戶端提供的principal可能不相同,例如每一個機器使用的principal是impala/[email protected],這樣的話無論對於那種方式的代理都是不可以的,因此需要修改服務端的–principal配置,一般使用上文介紹的合併keytab的方式,將兩個keytab合併成一個,使得同一個keytab可以使用不同的principal認證,對外提供相同的一個principal,impalad內部通訊則使用impala/[email protected]的principal。

總結

本文介紹並且實現了另外一種基於zookeeper的方式實現impalad節點高可用的方案,該方案不需要依賴繁重的haproxy+keeplived繁重的組建以來,並且利用原生jdbc的特性實現impalad的負載均衡和高可用,但是這種方案也存在一定的缺陷,例如獨立的監控程序誰來保證,如果該程序down了那麼它所監控的impalad也不能對外提供服務了(因為zookeeper上該服務對應的節點會被刪除),如何保證該程序的生命週期比它所監控的impalad程序更久是該方案面臨的最大問題。

不過這個監控程序畢竟是非常輕量級的,相對於impalad它down的機率還是比較小的,即使它掛掉了而impalad仍然存在,也只是意味著在這個監控程序重啟之前該impalad不能對外提供服務,如果在多個impalad能夠同時提供服務的叢集中,這種影響是可以接受的。

最後,使用該工具只能講hs2的介面註冊到zk,並且通過beeline或者hive-jdbc訪問,但是對於直接使用thrift介面還是比較麻煩的,接下來還需要尋找如何將hs2介面轉成thrift介面的方式。

//更新…
上文描述了一種使用zookeeper元件實現impalad高可用+負載均衡的方案,這樣使得impala在使用的時候更加向hiveserver2,但是在編寫客戶端程式的時候,作為一個數據平臺,往往需要代理多個使用者執行任務,hive可以通過在url中新增hive.server2.proxy.user引數指定被代理使用者,當然使用該引數的時候需要保證當前認證的UsergroupInformation是一個超級使用者(可代理的使用者),這樣可以使用一個超級使用者的kerberos賬號代理人以使用者執行查詢。

impala同樣也提供這樣的機制,但是比較蛋疼的是impala代理引數和hive不一樣,變成了impala.doas.user,這樣就使得我們不能直接使用hive的引數請求impala做代理使用者執行,那麼是否可以直接在url後面新增impala的引數讓impalad識別被代理使用者呢?答案是不可以的,因為hive-jdbc裡面對於url的引數都會新增”set hivevar”這樣的字首,所以服務端收到的引數並不是客戶端傳過去的樣子了。

private void openSession() throws SQLException {
    TOpenSessionReq openReq = new TOpenSessionReq();

    Map<String, String> openConf = new HashMap<String, String>();
    // for remote JDBC client, try to set the conf var using 'set foo=bar'
    for (Entry<String, String> hiveConf : connParams.getHiveConfs().entrySet()) {
      openConf.put("set:hiveconf:" + hiveConf.getKey(),hiveConf.getValue());
    }
    // For remote JDBC client, try to set the hive var using 'set hivevar:key=value'
    for (Entry<String, String> hiveVar :connParams.getHiveVars().entrySet()) {
      openConf.put("set:hivevar:" + hiveVar.getKey(), hiveVar.getValue());
    }
    // switch the database
    openConf.put("use:database", connParams.getDbName());

    // set the session configuration
    Map<String, String> sessVars = connParams.getSessionVars();
    if (sessVars.containsKey(HiveAuthFactory.HS2_PROXY_USER)) {
      openConf.put(HiveAuthFactory.HS2_PROXY_USER,
          sessVars.get(HiveAuthFactory.HS2_PROXY_USER));
    }
    ....
  }

所以就不能直接用hive-jdbc連線impalad實現代理了,於是只能仿照hive jdbc的建立connection的邏輯自己實現了一個類似的程式,輸入同樣是類似hive的url,引數同樣參考hive proxy引數而不是impala引數,在建立connection的時候再轉換成impala引數。

程式碼連線:這裡

這裡除了建立connection的例項之外,還是先了一個可使用的類似於beeline的客戶端的,它的輸入url既可以是直連某一個impalad的形式,也可以是zookeeper形式,既可以以當前kerberos執行,也可以代理其他使用者執行。

相關推薦

Impala負載均衡方案——zookeeper

由來 之前根據Impala官方的文件嘗試使用haproxy實現impalad節點的負載均衡,但是這種方案存在一些弊端,例如haproxy本身也是單點的,雖然可以通過keeplived實現haproxy的高可用,但是這樣的配置難免有點太重了,實現impala負載

Impala負載均衡方案

概述 Impala分為是三個元件,statestored/catalogd和impalad,其中statestored和catalogd是單點的,沒有高可用的需求,因為這兩個例項是無狀態的,本身不儲存任何資料,例如catalogd的資料儲存在第三方資料庫(例如

負載均衡方案(摘抄)

負載均衡 反向代理 1、負載均衡之DNS域名解析DNS(Domain Name System)是因特網的一項服務,它作為域名和IP地址相互映射的一個分布式數據庫,能夠使人更方便的訪問互聯網。人們在通過瀏覽器訪問網站時只需要記住網站的域名即可,而不需要記住那些不太容易理解的IP地址。在DNS系統中有

負載均衡方案(摘抄)

負載均衡 ip dns 反向代理 負載均衡之DNS域名解析 DNS(Domain Name System)是因特網的一項服務,它作為域名和IP地址相互映射的一個分布式數據庫,能夠使人更方便的訪問互聯網。人們在通過瀏覽器訪問網站時只需要記住網站的域名即可,而不需要記住那些不太容易理解的IP地

基於滴滴雲DC2+Nginx搭建負載均衡方案

Nginx是一款輕量級、高效能的Web伺服器,專為高流量應用場景而設計。 本文主要介紹它的健康檢查和負載均衡機制。健康檢查和負載均衡是相輔相成,健康檢查能夠及時標記出服務異常的後端RS,使得資料面負載到可用的RS上,提高系統的可靠性和高可用。 Nginx支援豐富的第三方模組,這裡示例

Redis快取叢集及叢集負載均衡方案設計

快取模組設計 採用分散式快取: 說明: (1)Web伺服器端只負責呼叫介面獲取/更新資料,不必關心業務資料處理; (2)介面負責具體的資料處理,包括快取資料的寫入/更新; (3)快取叢集用於快取伺服器宕機後,資料仍然高可用。 快取寫入規則

大資料時代下的SQL Server第三方負載均衡方案----Moebius測試

一.本文所涉及的內容(Contents) 二.背景(Contexts)   前幾天在SQL Server MVP宋大俠(宋沄劍)的一篇文章"資料庫叢集技術漫談”中看到了格瑞趨勢在SQL Server上的負載均衡產品Moebius,搞資料庫的都知道:在Oracle上有RAC,MySQL也有對應的方案(可

Windows下高可靠性網路負載均衡方案NLB+ARR

序言 在上一篇配置iis負載均衡中我們使用啦微軟的ARR,我在那篇文章也中提到了網站的高可用性,但是ARR只能做請求入口的訊息分發服務,這樣如果我們的訊息分發伺服器給down掉啦,那麼做再多的應用服務叢集也都枉然。 這篇文章我主要針對解決這一問題來做分析,引入NLB,相對於ARR來說,ARR算是應用級別的

Windows下應用級別的IIS負載均衡方案 Application Request Route

序言 隨著公司業務的發展,後臺業務就變的越來越多,然而伺服器的故障又像月經一樣,時不時的洶湧而至,讓我們防不勝防。那麼後臺的高可用,以及伺服器的處理能力就要做一個橫向擴充套件的方案,以使後臺業務持續的穩定可用,平復人心。 由於我們的後臺業務,清一色都是.net應用程式,加上總監的一致推薦,我們的負載均衡其

Haproxy + keepalived 高可用負載均衡解決方案

haproxy + keepalived文檔作者:amunlinux文檔版本:Version 1.1修改記錄:2017-04-22系統環境:CentOS 6.8 64 bitIP 信息列表: 名稱 IP -----------------------------------VIP 192.1

Nginx負載均衡4種方案

nginx配置 another 服務器 nginx負載均衡 address 第一個 session 添加 後端 1、輪詢 輪詢即Round Robin,根據Nginx配置文件中的順序,依次把客戶端的Web請求分發到不同的後端服務器。 配置的例子如下:http{ up

負載均衡集群中的session解決方案

集群 負載均衡 解決方案 前言在我們給Web站點使用負載均衡之後,必須面臨的一個重要問題就是Session的處理辦法,無論是PHP、Python、Ruby還是Java,只要使用服務器保存Session,在做負載均衡時都需要考慮Session的問題。分享目錄:問題在哪裏?如何處理?會話保持(案例:N

「mysql優化專題」高可用性、負載均衡的mysql集群解決方案(12)

格式 return 建議 處理方式 sage 主機 等待 status 深度 一、為什麽需要mysql集群? 一個龐大的分布式系統的性能瓶頸中,最脆弱的就是連接。連接有兩個,一個是客戶端與後端的連接,另一個是後端與數據庫的連接。簡單如圖下兩個藍色框框(其實,這張圖是我在悟空

域名到站點的負載均衡技術一覽(主要是探討一臺Nginx抵禦大並發的解決方案)(轉)

零成本 參考 硬件 名詞 virt 很好 web 常見 .com 繼上一篇文章Http://www.cnblogs.com/EasonJim/p/7807794.html中說到的,Nginx雖然很強大,但是面對大並發時,一臺Nginx總是有限的。即使後端有多臺Nginx組成

apache分別基於三種方案實現tomcat的代理、負載均衡及會話綁定

tomcat apacheapache分別基於mod_proxy_ajp, mod_proxy_http, mod_jk三種方案實現代理、負載均衡、會話綁定及Tomcat session cluster1、nginx, haproxy, apache(mod_proxy_ajp, mod_proxy_http

負載均衡架構方案

gpo 輪詢 cal beat nginx big-ip 架構 linu linux集群 負載均衡器 1、硬件負載均衡 F5 BIG-IP Citrix NetScaler Array 2、軟件負載均衡 LVS Nginx及HAProxy 3、高可用軟件 Hear

架構設計:負載均衡層設計方案負載均衡技術總結篇

error_log 基於 地址映射 高可用 lvs-dr模式 緩解 映射 node yum 前言 1、概述 通過前面文章的介紹,並不能覆蓋負載均衡層的所有技術,但是可以作為一個引子,告訴各位讀者一個學習和使用負載均衡技術的思路。雖然後面我們將轉向“業務層”和“業務通信”層的

企業級開源四層負載均衡解決方案--LVS 高清無密 百度網盤

簡介 進行 規劃 詳細介紹 存在 keepaliv get 服務器 應用 企業級開源四層負載均衡解決方案--LVS 本課程將在Linux環境下,學習配置使用LVS,對Web集群和MySQL集群進行負載均衡,並結合利用Keepalived實現負載均衡器的高可用,實現對後端Re

zookeeper HA 實現負載均衡

在網上看到太多千篇一律的zookeeper相關的文章,都是定義,沒有一個是有完整程式碼的,這對自己學習zk十分困難,其實要用zk實現主備切換、負載均衡其實沒有自己想象的那麼難,只需要瞭解zk的基本特性即可。在這裡貼上自己寫的程式碼與自己的理解,大家多多指教! 一、

Zookeeper實現負載均衡原理

先玩個正常的,好玩的socket程式設計: 服務端: package com.toov5.zkDubbo; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import org.I