一、背景
有關ES的詳細介紹參考:https://www.cnblogs.com/cjsblog/p/9439331.html
公司有些比如使用算法訓練的模型數據等需要快速的檢索性能,最終選擇使用ES來存儲,然後使用別名來區分每一批次的最新數據,對外(web接口)只需暴露別名即可。
二、常規實現
- ES數據全量數據攝入(Overwrite模式)
覆蓋方式或許是公司最常用的方式,每天T+1或者T+0去更新數據,然後切換索引和別名,以下是具體的實現方式。
1)使用Hadoop導入add jar /xxx/scripts/jars/elasticsearch-hadoop-6.6.1.jar; CREATE TEMPORARY TABLE IF NOT EXISTS dm_user_xx_df_temp(user_id bigint, is_paid_in_youke int,payment_cnt bigint) STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES('es.resource' = '${index}/result','es.index.auto.create' = 'true','es.nodes' = '${ip}','es.port' = '${port}'); INSERT OVERWRITE TABLE dm_user_xx_df_temp select user_id,is_paid_in_youke,payment_cnt from dm.dm_user_test_df where pt ='2019-09-29';
2)使用SparkSql方式導入
add jar hdfs://xxx/elasticsearch-spark-20_2.10-6.1.3.jar;
CREATE TEMPORARY TABLE dm_xxxx_df_temp(user_id bigint, is_paid_in_youke int,payment_cnt bigint)
USING org.elasticsearch.spark.sql
OPTIONS (resource '${index}/result', nodes '${ip}', port '${port}');
INSERT OVERWRITE TABLE dm_xxxx_df_temp
select user_id,is_paid_in_youke,payment_cnt
from dm.dm_user_xxx_df where pt ='${day}' limit 5;
- ES數據增量數據攝入 (Append模式)
增量的很簡單,無論OVERWRITE/Append對臨時表的直接操作都是追加,如果插入多次會出現數據重複,所以根據需要在使用上要去重處理。
三、工具平臺化處理
該功能是通用的,在公司的數據處理中大多還是集成在平臺之中,只需要必須的參數設置就能非常簡單的 配置一個Hive2Es的任務。其實真正的overwrite處理包含以下幾部:
- 如果存在同名索引要先刪掉
- 執行上述hive2es的sql代碼
- 刪除除了當前索引之外的其他索引
- 更新別名
這裏需要補充說明下,自定義的索引比如index_test, 後臺會處理成index_test_1108(小時分鐘),索引的別名:index_test_alias。 也即是說讓當前別名總是指向最新的索引。
結合到平臺的處理我認爲需要做到以下幾點:
- 配置方式儘可能的簡便
- 日誌儘可能詳細暴露出哪一步出現問題
- 不要在抽數的時候做計算
四、遇到的問題
- CDH版本的Hadoop集羣在運行使用Hadoop方式抽數到ES的時候報包找不到的問題。
Showing 4096 bytes of 93518 total. Click here for the full log.
OldReducer(ReduceTask.java:445)
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:393)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1875)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:168)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.httpclient.protocol.ProtocolSocketFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 22 more
這個問題在另外一套使用原生的Hadoop安裝的沒有出現此問題,而在線上使用CDH版本 **Cloudera Express 6.2.0 ** 使用Hadoop3.0的則會出現這樣的問題,暫時使用sparksql的方式解決。
五、總結
本文簡述了Hive數據導入到ES的一般處理方式,同時包含增量和覆蓋方式的處理,同時介紹了結合平臺處理需要注意的問題。其中ES的操作還是參照ES REST API去操作,簡單明瞭,希望你也能有所收穫!
參考:
https://www.cnblogs.com/liqiu/p/5687310.html
https://note4code.com/2016/06/17/hive-向-elasticsearch-導出數據/