Hadoop生態圈之Impala(一)

Apache Impala

       impala 是 cloudera 提供的一款高效率的 sql 查詢工具,提供實時的查詢效果

​       impala 是基於 hive 並使用內存進行計算,兼顧數據倉庫,具有實時,批處理,多併發等優點。

 

Impala 與 Hive 關係

​        impala 是基於 hive 的大數據分析查詢引擎,直接使用 hive 的元數據庫 metadata,意味着 impala 元數據都存儲在 hive 的 metastore 當中,並且 impala 兼容 hive 的絕大多數 sql 語法。所以需要安裝 impala 的話,必須先安裝 hive,保證 hive 安裝成功,並且還需要啓動 hive 的 metastore 服務。

        Hive 元數據包含用 Hive 創建的 database、 table 等元信息。元數據存儲在關係型數據庫中, 如 Derby、 MySQL 等。

        客戶端連接 metastore 服務, metastore 再去連接 MySQL 數據庫來存取元數據。有了 metastore 服務,就可以有多個客戶端同時連接,而且這些客戶端不需要知道 MySQL 數據庫的用戶名和密碼,只需要連接 metastore 服務即可。

        Hive 適合於長時間的批處理查詢分析,而 Impala 適合於實時交互式 SQL 查詢。 可以先使用 hive 進行數據轉換處理,之後使用 Impala 在 Hive 處理後的結果數據集上進行快速的數據分析

 

Impala 與 Hive 異同

​        Impala 與 Hive 都是構建在 Hadoop 之上的數據查詢工具各有不同的側重適應面,但從客戶端使用來看 Impala 與 Hive 有很多的共同之處,如數據表元數據、 ODBC/JDBC 驅動、 SQL 語法、靈活的文件格式、存儲資源池等。

​        但是 Impala 跟 Hive 最大的優化區別在於: 沒有使用 MapReduce 進行並行計算,雖然 MapReduce 是非常好的並行計算框架,但它更多的面向批處理模式,而不是面向交互式的 SQL 執行。與 MapReduce 相比, Impala 把整個查詢分成一執行計劃樹,而不是一連串的 MapReduce 任務,在分發執行計劃後, Impala 使用拉式獲取數據的方式獲取結果,把結果數據組成按執行樹流式傳遞彙集,減少了把中間結果寫入磁盤的步驟,再從磁盤讀取數據的開銷。 Impala 使用服務的方式避免每次執行查詢都需要啓動的開銷,即相比 Hive 沒了 MapReduce 啓動時間。

  • 執行計劃

    • Hive: 依賴於 MapReduce 執行框架,執行計劃分成 map->shuffle->reduce->map->shuffle->reduce…的模型。如果一個 Query 會 被編譯成多輪 MapReduce,則會有更多的寫中間結果。由於 MapReduce 執行框架本身的特點,過多的中間過程會增加整個 Query 的執行時間。

    • Impala: 把執行計劃表現爲一棵完整的執行計劃樹,可以更自然地分發執行計劃到各個 Impalad 執行查詢,而不用像 Hive 那樣把它組合成管道型的 map->reduce 模式,以此保證 Impala 有更好的併發性和避免不必要的中間 sort 與 shuffle。

  • 數據流

    • Hive: 採用推的方式,每一個計算節點計算完成後將數據主動推給後續節點。

    • Impala: 採用拉的方式,後續節點通過 getNext 主動向前面節點要數據,以此方式數據可以流式的返回給客戶端,且只要有 1 條數據被處理完,就可以立即展現出來,而不用等到全部處理完成,更符合 SQL 交互式查詢使用。

  • 內存使用

    • Hive: 在執行過程中如果內存放不下所有數據,則會使用外存,以保證 Query 能順序執行完。每一輪 MapReduce 結束,中間結果也會寫入 HDFS 中,同樣由於 MapReduce 執行架構的特性, shuffle 過程也會有寫本地磁盤的操作。

    • Impala: 在遇到內存放不下數據時,版本 1.0.1 是直接返回錯誤,而不會利用外存,以後版本應該會進行改進。這使用得 Impala 目前處理 Query 會受到一定 的限制,最好還是與 Hive 配合使用。

  • 調度

    • Hive: 任務調度依賴於 Hadoop 的調度策略。

    • Impala: 調度由自己完成,目前只有一種調度器 simple-schedule,它會盡量滿足數據的局部性,掃描數據的進程儘量靠近數據本身所在的物理機器。調度器目前還比較簡單,在 SimpleScheduler::GetBackend 中可以看到,現在還沒有考慮負載,網絡 IO 狀況等因素進行調度。但目前 Impala 已經有對執行過程的性能統計分析,應該以後版本會利用這些統計信息進行調度吧。

  • 容錯

    • Hive: 依賴於 Hadoop 的容錯能力。

    • Impala: 在查詢過程中,沒有容錯邏輯,如果在執行過程中發生故障,則直接返回錯誤(這與 Impala 的設計有關,因爲 Impala 定位於實時查詢,一次查詢失敗, 再查一次就好了,再查一次的成本很低)。

  • 適用面

    • Hive: 複雜的批處理查詢任務,數據轉換任務。

    • Impala: 實時數據分析,因爲不支持 UDF,能處理的問題域有一定的限制, 與 Hive 配合使用,對 Hive 的結果數據集進行實時分析。

 

Impala 架構

 

  • Impalad

    • 與 DataNode 運行在同一節點上, 由 Impalad 進程表示,它接收客戶端的查詢請求(接收查詢請求的 Impalad 爲 Coordinator, Coordinator 通過 JNI 調用 java 前端解釋 SQL 查詢語句,生成查詢計劃樹,再通過調度器把執行計劃分發給具有相應數據的其它 Impalad 進行執行), 讀寫數據, 並行執行查詢,並把結果通過網絡流式的傳送回給 Coordinator,由 Coordinator 返回給客戶端。同時 Impalad 也與 State Store 保持連接,用於確定哪個 Impalad 是健康和可以接受新的工作。

    • 在 Impalad 中啓動三個 ThriftServer:eeswax_server (連接客戶端),hs2_server (借用 Hive 元數據), be_server (Impalad 內部使用)和一個 ImpalaServer 服務。

  • Impala State Store

    • 跟蹤集羣中的 Impalad 的健康狀態及位置信息, 由 statestored 進程表示,它通過創建多個線程來處理 Impalad 的註冊訂閱和與各 Impalad 保持心跳連接,各 Impalad 都會緩存一份 State Store 中的信息,當 State Store 離線後(Impalad 發現 State Store 處於離線時,會進入 recovery 模式,反覆註冊,當 State Store 重新加入集羣后,自動恢復正常,更新緩存數據)因爲 Impalad 有 State Store 的緩存仍然可以工作,但會因爲有些 Impalad 失效了,而已緩存數據無法更新,導致把執行計劃分配給了失效的 Impalad,導致查詢失敗。

  • CLI

    • 提供給用戶查詢使用的命令行工具(Impala Shell 使用 python 實現),同時 Impala 還提供了 Hue, JDBC, ODBC 使用接口

  • Catalogd

    • 作爲 metadata 訪問網關,從 Hive Metastore 等外部 catalog 中獲取元數據信息,放到 impala 自己的 catalog 結構中。 impalad 執行 ddl 命令時通過 catalogd 由其代爲執行,該更新則由 statestored 廣播。

Impala 查詢處理過程

​        Impalad 分爲 Java 前端與 C++處理後端,接受客戶端連接的 Impalad 即作爲這次查詢的 Coordinator, Coordinator 通過 JNI 調用 Java 前端對用戶的查詢 SQL 進行分析生成執行計劃樹

​        Java 前端產生的執行計劃樹以 Thrift 數據格式返回給 C++後端(Coordinator) (執行計劃分爲多個階段,每一個階段叫做一個 PlanFragment,每一個 PlanFragment 在執行時可以由多個 Impalad 實例並行執行(有些 PlanFragment 只能由一個 Impalad 實例執行,如聚合操作),整個執行計劃爲一執行計劃樹)。

​        Coordinator 根據執行計劃,數據存儲信息(Impala 通過 libhdfs 與 HDFS 進行交 互。通過 hdfsGetHosts 方法獲得文件數據塊所在節點的位置信息),通過調度器(現在只 有 simple-scheduler, 使用 round-robin 算法) Coordinator::Exec 對生成的執行計劃 樹分配給相應的後端執行器 Impalad 執行(查詢會使用 LLVM 進行代碼生成,編譯,執行),通過調用 GetNext()方法獲取計算結果。

       ​ 如果是 insert 語句,則將計算結果通過 libhdfs 寫回 HDFS 當所有輸入數據被消耗光,執行結束,之後註銷此次查詢服務。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章