
# 关于OBS并行导出
#### 概述
DWS数据库支持通过OBS外表并行导出数据：通过OBS外表设置的导出模式、导出数据格式等信息来指定导出的数据文件，利用多DN并行的方式，将数据从DWS数据库导出到外部，存放在OBS对象存储服务器上，从而提高整体导出性能。
- CN只负责任务的规划及下发，数据导出工作由DN负责，并释放CN资源，使其有能力处理外部请求。
- 每个DN都参与数据导出，使各个设备的计算能力及网络带宽得到充分利用。
- 支持多个OBS服务并发导出，导出的桶和对象的路径必须不同并且不能为空。
- 选择OBS服务器与集群节点处于联网状态，导出速率会受网络带宽影响。
- 支持数据文件格式：TEXT、CSV、ORC、PARQUET。单行数据大小需\<1GB。
- 在执行OBS导入导出时，为了确保数据导入或导出的正确性，需要在相同的兼容模式下操作。 例如：在MySQL兼容模式下导入（导出）的数据，同样需要在MySQL兼容模式下才能正确导出（导入）。
  
 
目前，导出数据有两种方式：
- 方式一：无需用户创建server，使用默认server创建外表，支持TXT、CSV格式的数据，参见[导出CSV、TXT数据到OBS](https://support.huaweicloud.com/migration-dws/dws_15_0067.html#ZH-CN_TOPIC_0000002220143924)。
- 方式二：需用户创建server，使用该server创建外表，支持ORC、PARQUET格式的数据，参见[导出ORC和PARQUET数据到OBS](https://support.huaweicloud.com/migration-dws/dws_15_0072.html#ZH-CN_TOPIC_0000002255063657)。其中PARQUET格式的数据仅9.1.0及以上版本支持。
![](https://support.huaweicloud.com/migration-dws/public_sys-resources/notice_3.0-zh-cn.png)
- OBS导入导出数据时，不支持中文路径。
- OBS导入导出数据时，暂不支持跨Region进行OBS数据导入导出，必须确保OBS和DWS集群在同一个Region中。
- 在执行OBS导入导出时，为了确保数据导入或导出的正确性，需要在相同的兼容模式下操作。 例如：在MySQL兼容模式下导入（导出）的数据，同样需要在MySQL兼容模式下才能正确导出（导入）。
  
 
#### 相关概念
- **数据源文件**：存储有数据的TEXT、CSV、ORC、PARQUET文件。
- **OBS**：对象存储服务，是一种可存储文档、图片、影音视频等非结构化数据的云存储服务。从DWS并行导出数据时，数据对象放置在OBS服务器上。
- **桶（Bucket）** ：对OBS中的一个存储空间的形象称呼，是存储对象的容器。
  - 对象存储是一种非常扁平化的存储方式，桶中存储的对象都在同一个逻辑层级，去除了文件系统中的多层级树形目录结构。
  
  - 在OBS中，桶名必须是全局唯一的且不能修改，即用户创建的桶不能与自己已创建的其他桶名称相同，也不能与其他用户创建的桶名称相同。每个桶在创建时都会生成默认的桶ACL（Access Control List），桶ACL列表的每项包含了对被授权用户授予什么样的权限，如读取权限、写入权限、完全控制权限等。用户只有对桶有相应的权限，才可以对桶进行操作，如创建、删除、显示、设置桶ACL等。
  
  - 一个用户最多可创建100个桶，但每个桶中存放的总数据容量和对象/文件数量没有限制。
   
- **对象** ：是存储在OBS中的基本数据单位。用户上传的数据以对象的形式存储在OBS的桶中。对象的属性包括名称Key，Metadata，Data。
  通常，将对象等同于文件进行管理，但是由于OBS是一种对象存储服务，并没有文件系统中的文件和文件夹概念。为了使用户更方便进行管理数据，OBS提供了一种方式模拟文件夹。通过在对象的名称中增加"/"，如tpcds1000/stock.csv，tpcds1000可以等同于文件夹，stock.csv就可以等同于文件名，而对象名称（key）仍然是tpcds1000/stock.csv、对象的内容就是stock.csv数据文件的内容。
  
- **Key**：对象的名称（键），为经过UTF-8编码的长度大于0且不超过1024的字符序列，一个桶里的每个对象必须拥有唯一的对象键值。用户可使用桶名+对象名来存储和获取对应的对象。
- **Metadata** ：对象元数据，用来描述对象的信息。元数据又可分为系统元数据和用户元数据。这些元数据以键值对（Key-value）的形式随http头域一起上传到OBS系统。
  - 系统元数据由OBS系统产生，在处理对象数据时使用。系统元数据包括：Date、Content-length、last-modify、Content-MD5等。
  
  - 用户元数据由用户上传对象时指定，是用户自己对对象的一些描述信息。
   
- **Data**：对象的数据内容，OBS对于数据的内容是无感知的，即认为对象内的数据为无状态的二进制数据。
- **外表**：用于识别数据源文件中的数据。外表中保存了数据源文件的位置、文件格式、存放位置、编码格式、数据间的分隔符等信息。
 
#### 相关原理
下面从以下两类表介绍从集群导出数据到OBS的原理。
- Hash分布表：在建表语句中指定了DISTRIBUTE BY HASH (Column_Name)的表。 对于Hash分布表而言，在存储表数据时，采用的是散列（Hash）方式的存储原理，如[图1]所示，图中以将表（T2）导出到OBS为例。
  在存储表数据时，将表（T2）中指定的Hash字段（col2）进行Hash运算后，生成相应的Hash值（value），根据DN与Hash值的映射关系，将该元组分发到相应的DN上进行存储。
  在导出数据到OBS时，每一个存储了导出表的（T2）数据的DN会直接向OBS导出属于自己的数据文件。多个节点将并行导出原始数据。
  图1Hash分布原理   
  ![](https://support.huaweicloud.com/migration-dws/figure/zh-cn_image_0000002256307377.png "点击放大") 
- Replication表：在建表语句中指定了DISTRIBUTE BY REPLICATION的表。 Replication表在DWS集群的每个节点上都会存储一份完整的表数据。因此，在导出数据到OBS时，DWS只会随机选择一个DN节点向OBS导出数据。
  
 
#### 导出文件的命名规则
DWS向OBS导出数据的文件命名规则如下：
- 从DN节点导出数据时，以segment的格式存储在OBS服务中，文件命名规则为"**表名称_节点名称_segment.n** "。这里的"n"是从0开始按照自然数0、1、2、3递增。
  例如，表t1在datanode3里面的数据导出成文件"t1_datanode3_segment.0"、"t1_datanode3_segment.1"等等，以此类推。
  对于来自不同集群或不同数据库的数据，建议用户可以将数据导出到不同的OBS桶或者同一个OBS桶的不同路径下。
  
- 每个segment可以存储的最大数据为1GB，并且不能切断元组。如果segment超过1GB，超过1GB的数据会作为第二个segment进行存储。 例如：
  datanode3节点将表（t1）导出到OBS时，一个segment里面已经存储了100条元组，大小是1023MB，如果再插入一条5MB的元组，大小就变成1028MB了，此时会以1023MB生成一个"t1_datanode3_segment.0"保存到OBS服务中，新插入的第101条元组作为下一个"t1_datanode3_segment.1"保存到OBS服务中。
  
- 导出Hash分布表时，每个DataNode节点生成的segment数量和集群的DataNode节点数无关，而是取决于每个DataNode节点上存储的数据量。按照Hash方式存储在各个DataNode节点上的数据分布不一定均匀。 例如，一个有6个DataNode节点的集群，DataNode1到DataNode6分别有1.5GB、0.7GB、0.6GB、0.8GB、0.4GB、0.5GB的数据，则导出时会生成7个OBS segment文件，其中DataNode1会生成1GB和0.5GB两个segment文件。
  
 
#### 导出流程
图2并行导出流程   
![](https://support.huaweicloud.com/migration-dws/figure/zh-cn_image_0000002221267732.png "点击放大")
表1流程说明 
| 流程       | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 子任务 |
|:---|:---|:---|
| 规划导出数据   | 创建OBS桶，并在桶中创建导出后的数据文件的存放目录。 详细请参见[规划导出数据](https://support.huaweicloud.com/migration-dws/dws_15_0068.html#ZH-CN_TOPIC_0000002255063653)。                                                                                                                                                                              | -   |
| 创建OBS外表。 | 创建外表用于帮助OBS指定的待导出数据文件。外表中保存了数据源文件导出后的位置、文件格式、编码格式、数据间的分隔符等信息。 详细内容请参见[创建OBS外表](https://support.huaweicloud.com/migration-dws/dws_15_0069.html#ZH-CN_TOPIC_0000002219984064)。                                                                                                                                         | -   |
| 执行导出数据。  | 在创建好外表后，通过INSERT语句，将数据快速、高效地导出到数据文件中。 详细内容请参见[执行导出](https://support.huaweicloud.com/migration-dws/dws_15_0070.html#ZH-CN_TOPIC_0000002254983765)。  | -   |
   
