在hive classpath中添加elasticsearch-hadoop.jar,以下方法任一種均可:
1、啟動hiveserver2 前,在hive-site.xml文件中更改hive.aux.jars.path屬性值
<property> <name>hive.reloadable.aux.jars.path</name> <value>/path/elasticsearch-hadoop.jar</value> <description>A comma separated list (with no spaces) of the jar files</description> </property>
2、啟動hiveserver2 時,指定hive.reloadable.aux.jars.path屬性值
nohup hive --service hiveserver2 --hiveconf hive.reloadable.aux.jars.path=/path/elasticsearch-hadoop.jar &
3、啟動hiveserver2 后,在hive 命令行中執行add jar /path/elasticsearch-hadoop.jar; 命令。
實測,以上三種方法,前兩種方法中jar包的路徑必須是本地路徑,第三種方法中的路徑既可以是本地路徑,也可以是hdfs路徑。
配置
hive在建表時,創建external表,並使用tblproperties指定一些es相關的屬性
create external table artists (...)
stored by 'org.elasticsearch.hadoop.hive.EsStorageHandler'
tblproperties('es.nodes' = 'linux-node9:9200', 'es.resource' = 'artists/_doc', 'es.index.auto.create' = 'false', 'es.index.read.missing.as.empty' = 'false');
org.elasticsearch.hadoop.hive.EsStorageHandler 是elasticsearch-hadoop.jar中的類,所以從這里就可以看出,確實是需要elasticsearch-hadoop.jar,而該jar在$HIVE_HOME/lib 下是沒有的,所以需要外部添加。從該jar的groupId可以看出,jar包維護者是ES公司,所以不可能預裝在hive安裝包中。
es.nodes指定es集群地址
es.resource指定關聯的index及其type
es.index.auto.create表示在表插入數據的時候,如果索引還沒有建,是否自動創建索引。強烈建議不要自動創建索引,因為自動創建索引時會自動映射字段類型,而hive字段類型和es字段類型不是一一對應的,如果自動映射字段類型的話,在hive查詢表數據的時候很可能會報類型轉換錯誤。
es.index.read.missing.as.empty表示當索引不存在時,在hive查詢表數據時是否報錯。為true則不報錯,為false時會報錯。
映射
默認情況下,elasticsearch-hadoop 使用hive表的字段名和類型映射es中的數據。但有些情況下,在hive中可以使用的名稱在es中不能使用,比如一些es的關鍵字。對於這種情況,可以在建hive表時指定es.mapping.names屬性,值是以逗號分隔的映射名稱列表,映射格式是hive字段名稱:es字段名稱。如下:
create external table artists (...)
stored by 'org.elasticsearch.hadoop.hive.EsStorageHandler'
tblproperties('es.nodes' = 'linux-node9:9200', 'es.resource' = 'artists/_doc', 'es.mapping.names' = 'date:@timestamp , url:url_123 ');
上例中,hive外部表artists的date列、url列分別對應es中artists索引的@timestamp字段、url_123字段。
hive不區分大小寫,但是es區分。為了避免列名大小寫對不上造成的信息丟失,elasticsearch-hadoop會將hive列名稱全轉為小寫。
寫數據到es
操作這個hive外部表就可對es中對應索引進行操作。
create external table artists (
id bigint,
name string,
links struct<url:string, picture:string>)
stored by 'org.elasticsearch.hadoop.hive.EsStorageHandler'
tblproperties('es.resource' = 'artists/_doc');
從另一個hive表source查詢數據並將結果集插入到es中
insert overwrite table artists select null, s.name, named_struct('url', s.url, 'picture', s.picture) from source s;
假如要指定es 文檔的id,則可以用tblproperties(es.mapping.id)屬性。例如,假如想用hive表的id作為es文檔的id,則可以這樣建表:
create external table artists (
id bigint,
...)
stored by 'org.elasticsearch.hadoop.hive.EsStorageHandler'
tblproperties('es.mapping.id' = 'id', ...);
把現有的json寫到es中
對於輸入數據是json的情況,es-hadoop允許直接索引而不應用任何轉換,數據按原樣直接發送給es。在這種情況下,需要使用tblproperties(es.input.json)屬性,es-hadoop期望輸出表只包含一個字段,字段類型是string/varchar(如果json數據是字符串表示的話)或者是binary(如果json數據是byte[]的話),字段值就是json數據。建表語句如下:
create external table json (data string)
stored by 'org.elasticsearch.hadoop.hive.EsStorageHandler'
tblproperties('es.resource' = '...', 'es.input.json` = 'yes');
從es讀取
在建表時可以指定從es讀的查詢語句,這樣表的數據就是查詢結果。如下:
create external table artists (
id bigint,
name string
)
stored by 'org.elasticsearch.hadoop.hive.EsStorageHandler'
tblproperties('es.resource' = 'artists/_doc', 'es.query' = '?q=me*');
es.query的值即是查詢語句。
類型轉換
Hive type | Elasticsearch type |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在es中創建索引時,需根據以上表格指定映射類型。
需要知道的是,如果一個hive表在建表時關聯了es,則表數據其實是放在es數據目錄中的,而且該hive 表不能被truncate,會報Cannot truncate non-native table artists 錯誤,但是可以被drop。表drop之后,es中索引不會受影響,數據也不會被刪除,只有建表時location指定的目錄會被刪除,如果沒有使用location 關鍵字,則會刪除hive.metastore.warehouse.dir 指定的目錄中的數據庫名目錄中的表名目錄。如果再按照原來表定義語句重建表,則查詢該表還是可以正常查出數據的,就好像表沒有被drop 過一樣。
疑問三:表或索引字段的新增、刪除如何影響對方?
不會影響對方。
關聯es的hive表,在建好后是不能添加或者刪除字段的,會報ALTER TABLE cannot be used for a non-native table artists 錯誤。
es索引可以新增字段,但是這個字段永遠不會有值,因為關聯es的hive表新增不了字段,故es索引中這個字段不會有有效值插入。
es索引不能刪除字段。