
# 使用Spark SQL操作Hudi表
#### 操作场景
在MRS集群中，Hudi集成在Spark中，为数据处理提供了强大的支持。通过这种集成，用户不仅能够利用Spark SQL创建Hudi表，还能高效地执行对Hudi表的增、删、改、查等操作。Hudi表的设计特别适合于需要频繁更新和查询的场景，如实时数据分析、数据仓库更新等，它能够确保数据的一致性和高效性，同时支持增量数据处理，大大提高了数据处理的灵活性和性能。
具体来说，通过Spark SQL操作Hudi表的过程包括但不限于以下几个方面：
- 创建Hudi表：用户可以使用Spark SQL的DDL（数据定义语言）语句来定义和创建Hudi表，指定表的结构、存储格式、索引类型等参数。
- 插入数据：支持批量插入和追加数据，Hudi的写入优化技术能够确保高效的数据写入，同时减少数据冗余。
- 更新和删除数据：Hudi支持基于主键的记录级更新和删除操作，这在传统的大数据处理框架中是难以实现的。通过Spark SQL，用户可以轻松执行这些操作，确保数据的准确性和时效性。
- 查询数据：Hudi表支持高效的查询操作，包括点查询、范围查询和聚合查询等。通过优化的索引机制，Hudi能够快速定位和检索数据，提高查询性能。
 
#### 前提条件
如果集群已开启Kerberos认证，需在Manager界面创建人机用户并关联到hadoop和hive用户组，主组为hadoop，具体操作请参考[创建MRS集群用户](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0345.html)。
#### 约束与限制
本章节适用于MRS 3.5.0-LTS及之后版本。
#### 操作步骤
1. 下载并安装Hudi客户端，具体请参考[安装MRS客户端](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_2127.html)章节。
   
   Hudi集成在Spark组件中，从Manager页面下载集群完整客户端或者Spark组件的客户端即可，例如客户端安装目录为："/opt/client"。
   
   
2. 使用**root** 用户登录客户端安装节点，执行如下命令：
   
   进入客户端目录：
   ```
   cd /opt/hadoopclient
   ```
   执行以下命令加载环境变量：
   ```
   source bigdata_env
   ```
   ```
   source Hudi/component_env
   ```
   如果集群已开启Kerberos认证，执行安全认证：
   ```
   kinit 创建的业务用户
   ```
   新创建的用户首次认证时需要修改密码，更改密码后重新执行kinit认证。
   
   
3. 执行以下命令启动spark-sql。 
   ```
   spark-sql --master yarn
   ```
   
   
4. 执行如下SQL操作Hudi表： 
   - 创建一个COW类型Hudi表：
     ```
     create table if not exists hudi_table2 (
         id int,
         name string,
         price double
     ) using hudi
     options (
         -- 指定Hudi表类型：COW写时复制表
         type = 'cow',
         -- 数据唯一主键，用于更新/删除数据
         primaryKey = 'id',
         -- 预合并字段，同主键多条数据按该字段值大小取最新记录
         preCombineField = 'price'
     );
     ```
     - type：该参数用于指定Hudi表的类型，可选cow、mor。如果选择mor表，则默认使用bucket索引，需要通过参数hoodie.bucket.index.num.buckets="xx"指定桶数。
     
     - primaryKey：该参数用于指定Hudi表的主键字段，多字段主键使用逗号分隔，建表后不可变更。
     
     - preCombineField：指定冲突合并字段，批量写入存在同一主键多条记录时，按此字段数值降序保留最新数据，一般推荐使用时间戳字段。
      
   
   - 插入数据：
     ```
     -- 向Hudi表插入第一条测试数据
     insert into hudi_table2 select 1,'1',1.0;
     -- 向Hudi表插入第二条测试数据
     insert into hudi_table2 select 2,'1',1.0;
     ```
     
   
   - 更新数据：
     ```
     -- 根据主键id更新指定记录，修改name字段值
     update hudi_table2 set name ='3' where id =1;
     ```
     
   
   - 删除数据：
     ```
     -- 根据主键id删除单条数据
     delete from hudi_table2 where id =2;
     ```
     
   
   - 查询数据：
     ```
     select * from hudi_table2;
     ```
     
   
   
   
   
验证操作是否生效：
执行命令查询表数据，确认仅存在id为1的记录且name字段值为"3"，表示更新操作成功、删除操作成功。
#### 常见问题
- **如何选择COW和MOR表类型？**
  COW（Copy On Write，写时复制）表在写入时合并更新，读取性能高但写入延迟较大；MOR（Merge On Read，读时合并）表在写入时仅追加日志，写入速度快但读取时需合并数据。对读取性能要求高、写入频率低的场景建议选择COW，对写入吞吐量要求高、可接受一定读取延迟的场景建议选择MOR。
  
- **执行spark-sql命令时报错如何处理？**
  请检查是否已正确加载环境变量；如果集群开启了Kerberos认证，是否已执行kinit完成安全认证；客户端是否已正确安装且安装路径无误。
  
 
#### 相关文档
- 使用Spark Shell方式创建Hudi表，请参考[使用Spark Shell创建Hudi表](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_24033.html)。
- 更多Hudi SQL语法请参考[Hudi SQL语法参考](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_24261.html)。
 
