
# 使用HDFS Colocation存储Hive表
#### 操作场景
在企业数据仓库场景中，多张业务表经常需要进行关联查询（如订单表与用户表关联），如果这些表的数据分布在不同的DataNode上，关联查询时需要跨节点传输大量数据，导致网络开销大、查询性能低。如何在数据写入阶段就预先规划数据分布，使相关联的表数据存储在相同的节点上，从而减少关联查询时的数据传输开销？HDFS Colocation（同分布）功能正是为解决这一问题而设计的。HDFS Colocation是HDFS提供的数据分布控制功能，通过将存在关联关系的表数据存放在相同的存储节点上，使后续的多表关联查询无需跨节点传输数据，从而大幅提升关联查询性能。本文介绍如何使用HDFS Colocation功能存储Hive表。
Hive支持HDFS的Colocation功能，即在创建Hive表时，设置表文件分布的locator信息，当使用**insert**语句向该表中插入数据时会将该表的数据文件存放在相同的存储节点上（不支持其他数据导入方式），从而使后续的多表关联的数据计算更加方便和高效。
支持HDFS的Colocation功能的Hive表格式只有TextFile和RCFile。
- **HDFS Colocation（同分布）**：HDFS提供的数据分布控制功能，允许用户指定多个文件或表的数据存储在相同的DataNode上，从而减少跨节点数据传输开销，提升关联查询性能。
- **Group**：Colocation功能中的分组概念，用于将多个locator组合在一起。一个Group包含一个或多个locator，属于同一Group的数据会被调度到相同的存储节点上。
- **Locator**：Colocation功能中的定位器概念，用于标识数据存储位置。一个locator对应一个具体的存储位置，多个locator组合在一个Group中，决定数据的分布策略。
 
#### 前提条件
- 已安装Hive客户端。了解如何安装客户端，请参考[安装客户端（3.x及之后版本）](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)。
- 当前用户已具有创建Hive表的权限。如果集群启用了Kerberos认证，需配置具有对应权限的角色。
 
#### 操作步骤
1. 使用客户端安装用户登录客户端所在节点。
2. 执行以下命令，切换到客户端安装目录，如：/opt/client。 
   ```
   cd /opt/client
   ```
   
   
3. 执行以下命令配置环境变量。 
   ```
   source bigdata_env
   ```
   
   
4. 如果集群已启用Kerberos认证（安全模式），执行以下命令认证用户。 
   ```
   kinit MRS用户名
   ```
   
   
5. 通过HDFS接口创建Group，定义数据分布策略。 
   ```
   hdfs colocationadmin -createGroup -groupId <groupid> -locatorIds <locatorid1>,<locatorid2>,<locatorid3>
   ```
   - \<groupid\>：创建的Group名称，用于标识数据分布组。
   
   - \<locatorid1\>,\<locatorid2\>,\<locatorid3\>：Locator ID列表，用逗号分隔。该示例语句创建的Group包含三个locator，用户可以根据实际需要定义locator的数量。每个locator对应一个存储位置，属于同一Group的数据会被调度到相同的存储节点上。
   
   
   
   
6. 执行以下命令进入Hive客户端： 
   ```
   beeline
   ```
   
   
7. Hive使用Colocation存储表。 
   假设table_name1和table_name2是相关联的两张表，执行以下命令创建表：
   创建表*table_name1*：
   ```
   CREATE TABLE <[db_name.]table_name1>[(col_name data_type , ...)] [ROW FORMAT <row_format>]  [STORED AS <file_format>] TBLPROPERTIES("groupId"=" <group> ","locatorId"="<locator1>");
   ```
   创建表*table_name2*：
   ```
   CREATE TABLE <[db_name.]table_name2> [(col_name data_type , ...)] [ROW FORMAT <row_format>]  [STORED AS <file_format>] TBLPROPERTIES("groupId"=" <group> ","locatorId"="<locator1>");
   ```
   参数说明：
   - \[db_name.\]table_name：表名，可指定数据库名，若不指定则使用当前数据库。
   
   - col_name data_type：列名和数据类型定义。
   
   - ROW FORMAT \<row_format\>：【可选】行格式定义，用于指定字段分隔符等。
   
   - STORED AS \<file_format\>：【可选】表文件格式，Colocation功能仅支持TextFile和RCFile两种格式。
   
   - TBLPROPERTIES("groupId"="\<group\>","locatorId"="\<locator1\>")：表属性配置，指定该表使用的Group和Locator。两张表必须使用相同的groupId和locatorId，才能实现数据同分布。
   
   
   当使用**insert**语句分别向table_name1和table_name2插入数据后，table_name1和table_name2的数据文件就会分布在HDFS的相同存储位置上，从而方便两表进行关联操作。
   
   
**验证操作：**
在beeline客户端执行以下命令验证Colocation配置是否生效：
1. 使用INSERT语句向两张表插入数据。
2. 在HDFS客户端执行以下命令查看文件分布：
   ```
   hdfs fsck <文件路径> -locations
   ```
   如果两张表的数据文件位于相同的DataNode上，则表示Colocation配置成功。
   
 
#### 常见问题
- **Colocation功能支持哪些表格式**
  HDFS Colocation功能通过HDFS的Colocation接口实现数据同分布，目前仅支持TextFile和RCFile两种表格式，不支持ORC、Parquet等其他格式。
  创建表时请在STORED AS子句中指定TextFile或RCFile格式。如需使用其他格式，请联系技术支持确认是否支持。
  
- **数据导入后未实现同分布**
  Colocation功能仅支持通过INSERT语句插入数据实现同分布。如果使用其他方式导入数据，数据可能不会按照Colocation策略分布。
  请使用INSERT语句向表中插入数据。如需批量导入数据，可先将数据加载到临时表，再通过INSERT INTO SELECT语句从临时表导入目标表。
  
- **创建Group失败**
  创建Group失败的常见原因包括：当前用户没有执行hdfs colocationadmin命令的权限、groupId已存在、或locatorIds参数格式错误。
  请确认当前用户具有HDFS管理权限。检查groupId是否已存在，如已存在请使用其他名称。确认locatorIds参数格式正确，多个locatorId之间使用逗号分隔且无空格。
  
 
#### 相关文档
- 了解如何安装MRS集群客户端，请参考[安装客户端（3.x及之后版本）](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)。
- 了解Hive SQL相关语法说明，请参考[Hive常见SQL语法说明](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_300258.html)。
- 了解Hive常见日志，请参考[Hive日志介绍](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_0976.html)。
 
