
# MRS Hive组件接入集群
在大数据分析场景中，Hive擅长海量数据的批处理，而Elasticsearch则是实时搜索与分析的利器，但在实际业务中，如何打破两者之间的数据孤岛，实现数据加工与实时检索的高效流转是架构设计的关键。通过ES-Hadoop工具可以将MRS Hive的大数据处理能力与CSS Elasticsearch的实时检索能力无缝结合，直接在Hive中通过"外表"形式读写Elasticsearch数据，既保留了Hadoop生态的操作习惯，又获得了秒级搜索响应性能。
#### 方案介绍
ES-Hadoop是一个连接Hadoop体系与Elasticsearch的库，它允许MapReduce、Hive、Spark等工具直接读写Elasticsearch索引。
在MRS Hive接入场景中，ES-Hadoop充当了"协议转换层"。当您在Hive中执行SQL查询语句时，ES-Hadoop会将Hive的执行计划转换为Elasticsearch的REST请求。
图1MRS Hive组件接入Elasticsearch集群   
![](https://support.huaweicloud.com/usermanual-css/figure/zh-cn_image_0000002517107088.png "点击放大")
更多ES-Hadoop与Hive的介绍请参见官方文档[Apache Hive integration](https://www.elastic.co/docs/reference/elasticsearch-hadoop/apache-hive-integration)。
#### 准备工作
- 确保CSS集群和MRS集群在同一个区域、可用区、虚拟私有云和子网，使CSS和MRS之间网络互通。
- 下载ES-Hadoop软件包，并解压zip包获取"elasticsearch-hadoop-x.x.x.jar"文件。建议ES-Hadoop版本与CSS集群保持一致，例如Elasticsearch 7.6.2对应使用ES-Hadoop 7.6.2。 下载地址：<https://www.elastic.co/downloads/hadoop>
  
- 下载HttpClient依赖包"commons-httpclient-x.x.jar"，建议3.1及以上版本。 下载地址：<https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient>
  
- 获取CSS集群的内网访问地址。
 
#### 接入集群
1. 校验MRS和CSS的网络连通性。
   1. 获取Elasticsearch集群的内网访问地址。
   
   2. 在MRS集群节点上通过Curl命令行检查网络连通性，需要确保MRS集群的每个节点都能连通Elasticsearch集群。登录MRS集群节点的操作步骤请参见[登录集群节点](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0083.html)。
      - 非安全模式的集群
        ```
        curl -X GET http://<host>:<port>
        ```
        
      
      - 安全模式+HTTP协议的集群
        ```
        curl -X GET http://<host>:<port> -u <user>:<password>
        ```
        
      
      - 安全模式+HTTPS协议的集群
        ```
        curl -X GET https://<host>:<port> -u <user>:<password> -ik
        ```
        
      
      
      表1变量说明 
      | 变量名      | 说明                                                                                                                                                                                                         |
      |:---|:---|
      | host     | 集群中各节点的IP地址，当集群包含多个节点时，会存在多个IP地址，可以任选其中一个发送。                                                                                                                                                               |
      | port     | 集群节点的访问端口号，一般为9200。                                                                                                                                                                                        |
      | user     | 访问集群的用户名。                                                                                                                                                                                                  |
      | password | 用户名对应的密码。 当密码中存在特殊字符时，请将用户名和密码加上单引号进行强引用，例如"curl -u 'user':'password!' "http://\<host\>:\<port\>""。 |
         
      
    
2. 依赖包上传至HDFS托管。确保Hive所有的计算节点都能访问到ES-Hadoop的驱动。
   1. 将下载的"elasticsearch-hadoop-x.x.x.jar"和"commons-httpclient-x.x.jar"上传至MRS客户端。安装MRS客户端的操作指导请参见[安装客户端（3.x及之后版本）](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)。
   
   2. 在MRS客户端创建HDFS目录，并将JAR包存入HDFS。
      ```
      hadoop fs -mkdir /tmp/hadoop-es
      hadoop fs -put elasticsearch-hadoop-x.x.x.jar /tmp/hadoop-es
      hadoop fs -put commons-httpclient-x.x.jar /tmp/hadoop-es
      ```
      
    
3. （可选）转换与分发安全证书。当接入安全模式+HTTPS协议的Elasticsearch集群时，需要解决Java环境对Elasticsearch自签名证书的信任问题。
   1. 获取安全证书（CloudSearchService.cer）。
      1. 登录[云搜索服务管理控制台](https://console.huaweicloud.com/elasticsearch/)。
      
      2. 在左侧导航栏，选择"集群管理 \> Elasticsearch"。
      
      3. 在集群列表，单击目标集群名称，进入集群详情页。
      
      4. 选择"概览"页签，在"网络信息"下方，单击"HTTPS访问"的"下载证书"获取安全证书。
         图2下载安全证书   
         ![](https://support.huaweicloud.com/usermanual-css/images/zh-cn_image_0000002412660693.png) 
       
   
   2. 转换安全证书的格式。将下载的安全证书上传到客户端机器上，使用keytool工具将".cer"证书转换成Java可以读取的".jks"证书格式。
      - 在Linux系统中，执行如下命令转换证书。
        ```
        keytool -import -alias newname -keystore ./truststore.jks -file ./CloudSearchService.cer
        ```
        
      
      - 在Windows系统中，执行如下命令转换证书。
        ```
        keytool -import -alias newname -keystore .\truststore.jks -file .\CloudSearchService.cer
        ```
        
      
      
      其中，*newname*是由用户自定义的证书名称。
      该命令执行后，会提示设置证书密码，并确认密码。请保存该密码，后续接入集群会使用。
      
   
   3. 全量分发安全证书。使用scp命令将".jks"证书文件发送到MRS集群所有节点的相同路径，如"/tmp"。同时，要确保**omm** 用户有权限读取该文件，设置权限的参考命令如下：
      ```
      chown -R omm truststore.jks
      ```
      
    
4. Hive会话初始化。在当前Hive进程中加载ES-Hadoop驱动。
   1. 从MRS客户端登录到Hive客户端，操作指导请参见[Hive客户端使用实践](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_0952.html)。
   
   2. 在Hive客户端，输入beeline或hive进入到执行界面，执行如下命令：
      ```
      add jar hdfs:///tmp/hadoop-es/commons-httpclient-3.1.jar;
      add jar hdfs:///tmp/hadoop-es/elasticsearch-hadoop-x.x.x.jar;
      ```
      该命令只对当前会话有效。
      
    
5. 创建Hive外表并关联Elasticsearch索引。建立Hive表结构与Elasticsearch索引字段的映射关系。
   - 连接非安全模式的集群
     ```
     CREATE EXTERNAL table IF NOT EXISTS student( 
        id BIGINT,
        name STRING,
        addr STRING 
     )  
     STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' 
     TBLPROPERTIES(  
         'es.nodes' = 'xxx.xxx.xxx.xxx:9200',
         'es.port' = '9200',
         'es.net.ssl' = 'false', 
         'es.nodes.wan.only' = 'false', 
         'es.nodes.discovery'='true',
         'es.input.use.sliced.partitions'='false',
         'es.resource' = 'student/_doc'
     );
     ```
     
   
   - 连接安全模式+HTTP协议的集群
     ```
     CREATE EXTERNAL table IF NOT EXISTS student( 
        id BIGINT,
        name STRING,
        addr STRING 
     )  
     STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' 
     TBLPROPERTIES(  
         'es.nodes' = 'xxx.xxx.xxx.xxx:9200',
         'es.port' = '9200',
         'es.net.ssl' = 'false', 
         'es.nodes.wan.only' = 'false', 
         'es.nodes.discovery'='true',
         'es.input.use.sliced.partitions'='false',
         'es.nodes.client.only'='true',
         'es.resource' = 'student/_doc',
         'es.net.http.auth.user' = 'username', 
         'es.net.http.auth.pass' = 'password'
     );
     ```
     
   
   - 连接安全模式+HTTPS协议的集群
     ```
     CREATE EXTERNAL table IF NOT EXISTS student( 
        id BIGINT,
        name STRING,
        addr STRING 
     )  
     STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' 
     TBLPROPERTIES(  
         'es.nodes' = 'https://xxx.xxx.xxx.xxx:9200',
         'es.port' = '9200',
         'es.net.ssl' = 'true', 
         'es.net.ssl.truststore.location' = 'certFilePath',
         'es.net.ssl.truststore.pass' = 'certPassword',
         'es.nodes.wan.only' = 'false', 
         'es.nodes.discovery'='true',
         'es.nodes.client.only'='true',
         'es.input.use.sliced.partitions'='false',
         'es.resource' = 'student/_doc',
         'es.net.http.auth.user' = 'username', 
         'es.net.http.auth.pass' = 'password'
     );
     ```
     
   
   
   表2ES-Hadoop参数说明 
   | 参数                             | 默认值       | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   |:---|:---|:---|
   | es.nodes                       | localhost | Elasticsearch集群的访问地址。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
   | es.port                        | 9200      | Elasticsearch集群的访问端口号，一般为"9200"。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | es.nodes.wan.only              | false     | 是否进行节点嗅探。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | es.nodes.discovery             | true      | 是否启用节点发现。保持默认值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | es.input.use.sliced.partitions | true      | 是否使用slice分区。 取值范围： - true：使用。  - false：不使用。   设置为true时，可能会导致索引在预读阶段的时间明显变长，有时会远超查询数据所耗费的时间。建议设置为false，以提高查询效率。 |
   | es.resource                    | NA        | 指定目标索引及类型。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | es.net.http.auth.user          | NA        | 访问集群的用户名，只有启用了安全模式才需要配置此值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | es.net.http.auth.pass          | NA        | 用户名所对应的密码，只有启用了安全模式才需要配置此值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | es.net.ssl                     | false     | 是否启用SSL。 取值范围： - true：启用SSL，需要配置安全证书信息。  - false：不启用SSL。                                                                                                                                                                                 |
   | es.net.ssl.truststore.location | NA        | ".jks"证书文件的路径，如"file:///tmp/truststore.jks"。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | es.nodes.client.only           | false     | 是否配置了独立的Client节点的IP地址给es.nodes（即创建Elasticsearch集群时是否"启用Client节点"）。 取值范围： - true：配置了独立的Client节点。  - false：未配置独立的Client节点。                                                                                                                                               |
   | es.net.ssl.truststore.pass     | NA        | ".jks"证书文件的密码。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
      
   更多ES-Hadoop配置项说明请参见[官方配置说明](https://www.elastic.co/guide/en/elasticsearch/hadoop/current/configuration.html)。
   
6. 结果验证。
   1. 在Hive客户端写入数据：
      ```
      INSERT INTO TABLE student VALUES (1, "Lucy", "address1"), (2, "Lily", "address2");
      ```
      
   
   2. 在Hive客户端查询数据。
      ```
      select * from student;
      ```
      查询结果如下：
      ```
      +-------------+---------------+---------------+
      | student.id  | student.name  | student.addr  |
      +-------------+---------------+---------------+
      | 1           | Lucy          | address1      |
      | 2           | Lily          | address2      |
      +-------------+---------------+---------------+
      2 rows selected (0.116 seconds)
      ```
      
   
   3. 在Kibana页面，搜索数据，确认数据已落盘。
      1. 在Elasticsearch集群列表，选择目标集群，单击操作列的"Kibana"，登录Kibana。
      
      2. 在Kibana左侧导航栏选择"Dev Tools"，进入操作页面。 控制台左侧是命令输入框，其右侧的三角形图标为执行按钮，右侧区域则显示执行结果。
         
      
      3. 执行查询命令，查看查询结果。
         ```
         GET /student/_search
         ```
         图3kibana查询结果   
         ![](https://support.huaweicloud.com/usermanual-css/figure/zh-cn_image_0000002549065207.png "点击放大") 
       
    
 
