华为云用户手册

  • 解决方案 用户的 MRS 集群是1.8.1, CDM 为2.6.0。 报错看CDM封装的Hive SDK无法识别Hive数据源, 但Hive连接器测试连通性是正常的,于是仔细检查Hive的连接器配置的参数。 安全集群MRS Manager用户、用户组和角色配置都正确,发现Hive版本配置的为HIVE_3_X。 由于MRS1.8.1集群hive版本为1.2.1,故应该选择hive_1_X。正确修改连接器配置,重新创建作业正常。
  • 问题描述 用户HDFS为线下自建的,往OBS迁移文件建立好连接器后,测试源端和目的端的连通性都是没问题的。 任务启动时报如下错误: Error: java.io.IOException: org.apache.hadoop.hdfs.BlockMissingException: Could not obtain block: BP-787476470-192.168.152.10-1573351961380:blk_1073742171_1347 file=/user/hive/warehouse/db_hive.db/emp/emp.txt (state=,code=0)
  • 原因分析 初步怀疑是新老集群部分参数修改不兼容导致的,通过查看老集群导出的作业json文件,包含throttlingConfig.concurrentSubJobs参数(并发子作业数,新集群已取消这个配置项)。 让客户在导出的json 文件中将删除以下配置项,重新导入作业到新集群,导入成功。 { "name":"throttlingConfig.concurrentSubJobs", "value":"10" },
  • 原因分析 查看后端日志报:org.postgresql.util.PSQLException: ERROR: relation "表名" does not exist。 怀疑是CDM 集群开启沙箱所导致的,后端对集群取消沙箱,重启CDM 集群后问题依然存在。 查看CDM迁移作业,源端数据库表名全部为小写,但是迁移的表中是包含有大写字母,将所要迁移的表名跟数据库中保持一致,目的端字段就可以映射出来了,问题解决。
  • 解决方案 如果源端网络不稳定,可以使用分片重试能力多次执行作业,可能需要调整作业配置。 如作业配置了分片数,或者源端为分区表,且作业配置了按表分区抽取,则单击更多-分片重试,重跑失败分片(比如配置了100个分片,上次执行到50个分片报错,则单击失败重试后,仅会执行剩余50个分片)。 如且源端非分区表,作业未配置分片数,建议调大作业分片数,再重新执行作业,后续再发生异常通过失败重试断点续传。 如源端为分区表,且未配置按表分区抽取,建议配置按表分区抽取后,重新执行作业,后续再发生异常通过失败重试断点续传。
  • 解决方案 在 DataArts Studio 或者Hue或者spark-beeline上执行drop table将表从metastore中删除,然后作业配置 “不存在时创建”重跑作业。或者删除后自己执行建表语句重建一个Hudi表。 对于MOR表来说,删表需要把ro与rt表也同时删除。否则会出现schema残留的问题。 删除空值后重跑作业。 具体办法: 在作业管理界面选择“更多-失败重试”,尝试重新执行Spark SQL。 通过DataArts Studio执行Spark SQL,设置执行参数或者调整SQL。 调整Spark切片大小: set spark.sql.files.maxPartitionBytes=xxM;默认值为128M,可适当调整为64M或者32M。 如果数据切分不均匀,可以修改SQL配置DISTRIBUTE BY rand(),增加一个shuffle过程,打散数据(需要占用较多资源,资源不多时慎用)。 insert into xx select * from xxx DISTRIBUTE BY rand(); 使用DataArts Studio API方式提交Spark SQL,调大executor内存。 排查是否有其他连接在同时写hudi表,如果有,将连接停止,然后CDM作业失败重试。
  • 原因分析 集群并发数到达上限 联系SRE查看cdm后台日志:/var/log/cdm/local/framework.log,搜索关键字:cluster running task,如果运行的并发数与available的并发数一致,则说明此时并发数已到达集群上限。 集群内存使用达到阈值 联系SRE查看cdm后台日志:/var/log/cdm/local/framework.log,搜索关键字:memory usage exceeds threshold,如果此时集群在不断打此日志,则说明堆内存使用已经超过75%,集群可能有oom的风险。
  • 原因分析 确认MRS集群的JdbcServer是多实例模式还是多租模式。 如果是多实例模式,跳转3。 否则跳转2。 多租户模式下,确认其他租户的作业是否正常。 如果所有租户的作业执行spark sql都有问题,跳转3。 否则,跳转4。 进一步确认:用dlf建个脚本,选择直连连接,执行一条spark sql,看是否报time out的错(甚至可能数据库都list不出来)。如果有以上现象,大概率是MRS集群的jdbc server出了问题。 单租户执行不了spark sql,则多半是队列资源限制,打开yarn,搜索租户的队列,查看Spark2x-JD BCS erver2x的yarn任务,此时可能会搜索不到yarn任务,或者State为ACCEPTED,这两种情况都是资源不足起不了yarn任务的现象。打开yarn的schedule,查看队列资源,关注以下几个参数: Used Resources: 已使用的内存与CPU核数 Max Resources:队列中最大可供使用的内存与CPU核数 Used Application Master Resources: 已使用的AM资源 Max Application Master Resources: 队列中最大可供使用的AM资源 通过对比基本就能确定是哪个资源不足导致yarn任务执行异常。
  • 解决方案 查看Yarn任务,搜索Spark JDBC Server的Yarn任务,找到自己队列下Running Container大于1的任务,查看ApplicationMaster,单击SQL页签,可以看到正在执行的SQL,单击Stages页签,可以看到每条SQL的执行进度。 CDM在作业BOOTING阶段无法查看日志,如果找不到Yarn任务,请联系CDM运维查看后台日志,获取Application ID。日志形如:
  • 问题描述 数据库中存储的是1或0,但没有true和false的数据,但MySQL迁移时读取到的是true或false,提示报错信息:Unable to execute the SQL statement. Cause: ERROR: invalid input syntax for integer: "true" Where: COPY sd_mask_ext, line 1, column mask_type.
  • 解决方案 新建MRS Hive连接时,提示无法下载配置文件,实际是用户权限不足。建议您新建一个业务用户,给对应的权限后重试即可。 如果要创建MRS安全集群的数据连接,不能使用admin用户。因为admin用户是默认的管理页面用户,这个用户无法作为安全集群的认证用户来使用。您可以创建一个新的MRS用户,然后在创建MRS数据连接时,“用户名”和“密码”填写为新建的MRS用户及其密码。 如果CDM集群为2.9.0版本及之后版本,且MRS集群为3.1.0及之后版本,则所创建的用户至少需具备Manager_viewer的角色权限才能在CDM创建连接;如果需要对MRS组件的库、表、列进行操作,还需要参考MRS文档添加对应组件的库、表、列操作权限。 如果CDM集群为2.9.0之前的版本,或MRS集群为3.1.0之前的版本,则所创建的用户需要具备Manager_administrator或System_administrator权限,才能在CDM创建连接。 仅具备Manager_tenant或Manager_auditor权限,无法创建连接。
  • 如何调整抽取并发数 集群最大抽取并发数的设置与CDM集群规格有关,并发数上限建议配置为vCPU核数*2,如表1所示。 表1 集群最大抽取并发数配置建议 规格名称 vCPUs/内存 集群并发数上限参考 cdm.large 8核 16GB 16 cdm.xlarge 16核 32GB 32 cdm.4xlarge 64核 128GB 128 图1 集群最大抽取并发数配置 作业抽取并发数的配置原则如下: 迁移的目的端为文件时,CDM不支持多并发,此时应配置为单进程抽取数据。 表中每行数据大小为1MB以下的可以设置多并发抽取,超过1MB的建议单线程抽取数据。 作业抽取并发数可参考集群最大抽取并发数配置,但不建议超过集群最大抽取并发数上限。 目的端为 DLI 数据源时,抽取并发数建议配置为1,否则可能会导致写入失败。 图2 作业抽取并发数配置
  • 解决方案 优先联系DBA修改表结构,将需要过滤的列配置为索引列,然后重试。 如果由于数据不离散,导致还是失败请参考2~4,通过增大JDBC超时时间解决。 根据作业找到对应的MySQL连接名称,查找连接信息。 图2 连接信息 单击“连接管理”,在“操作”列中,单击“连接”进行编辑。 图3 连接 打开高级属性,在“连接属性”中建议新增“connectTimeout”与“socketTimeout”参数及参数值,单击“保存”。 图4 编辑高级属性
  • 如何调整抽取并发数 集群最大抽取并发数的设置与CDM集群规格有关,并发数上限建议配置为vCPU核数*2,如表1所示。 表1 集群最大抽取并发数配置建议 规格名称 vCPUs/内存 集群并发数上限参考 cdm.large 8核 16GB 16 cdm.xlarge 16核 32GB 32 cdm.4xlarge 64核 128GB 128 图1 集群最大抽取并发数配置 作业抽取并发数的配置原则如下: 迁移的目的端为文件时,CDM不支持多并发,此时应配置为单进程抽取数据。 表中每行数据大小为1MB以下的可以设置多并发抽取,超过1MB的建议单线程抽取数据。 作业抽取并发数可参考集群最大抽取并发数配置,但不建议超过集群最大抽取并发数上限。 目的端为DLI数据源时,抽取并发数建议配置为1,否则可能会导致写入失败。 图2 作业抽取并发数配置
  • 操作步骤 找一台Windows机器作为网关机,该机器同时配置内网和外网IP。通过以下测试来确保网关机器的服务要求: 在该机器上ping内网MySQL地址可以ping通,例如:ping 192.168.1.8。 在另外一台可上网的机器上ping网关机的公网地址可以ping通,例如ping 202.xx.xx.10。 下载端口映射工具IPOP,在网关机上安装IPOP。 运行端口映射工具,选择“端口映射”,如图2所示。 本地地址、本地端口:配置为网关机的公网地址和端口(后续在CDM上创建MySQL连接时输入这个地址和端口)。 映射地址、映射端口:配置为内网MySQL的地址和端口。 图2 配置端口映射 单击“增加”,添加端口映射关系。 单击“开始映射”,这时才会真正开始映射,接收数据包。 至此,就可以在CDM上通过弹性IP读取本地内网MySQL的数据,然后导入到云服务DWS中。 CDM要访问本地数据源,也必须给CDM集群配置EIP。 一般云服务DWS默认也是只允许VPC内部访问,创建CDM集群时,必须将CDM的VPC与DWS配置一致,且推荐在同一个内网和安全组,如果不同,还需要配置允许两个安全组之间的数据访问。 端口映射不仅可以用于迁移内网数据库的数据,还可以迁移例如SFTP服务器上的数据。 Linux机器也可以通过IPTABLE实现端口映射。 内网中的FTP通过端口映射到公网时,需要检查是否启用了PASV模式。这种情况下客户端和服务端建立连接的时候是走的随机端口,所以除了配置21端口映射外,还需要配置PASV模式的端口范围映射,例如vsftp通过配置pasv_min_port和pasv_max_port指定端口范围。
  • 已购买包年包月的CDM套餐包,为什么还会产生按需计费的费用? 请您先确认套餐包和实际的CDM集群是否具有相同区域和规格,如果非相同区域和规格,则无法使用套餐包。CDM集群规格和区域可以通过进入CDM主界面,进入“集群管理”,单击集群列表中的集群名称查看。 如果套餐包和实际的CDM集群具有相同区域和规格,则以下情况也会产生按需费用: 如果您先购买按需计费增量包,再购买套餐包,则在购买套餐包之前已经产生的费用以按需计费结算,购买套餐包之后的费用按套餐包计时。 父主题: 通用类
  • CDM可以跨账户使用吗? CDM不支持跨账户使用,可以通过授权给同一账户 IAM 子用户使用。 IAM用户授权操作步骤如下: 创建用户组并授权 在IAM控制台创建用户组,并授予CDM集群只读权限“CDM ReadOnlyAccess”。 创建用户并加入用户组 在IAM控制台创建用户,并将其加入1中创建的用户组。 用户登录并验证权限 新创建的用户登录控制台,切换至授权区域,验证权限: 在“服务列表”中选择“ 云数据迁移 服务”,进入CDM主界面查看集群,若未提示权限不足,表示“CDM ReadOnlyAccess”已生效。 在“服务列表”中选择除CDM服务外的任一服务,若提示权限不足,表示“CDM ReadOnlyAccess”已生效。 父主题: 通用类
  • 各个数据迁移服务区别 表1 各个数据迁移服务区别 服务名 主要功能 与其他服务的区别 云数据迁移CDM 大数据迁移上云 多种数据源到 数据湖 的迁移 与DRS的区别: 数据库迁移使用DRS;到大数据系统的迁移使用CDM。 对象存储迁移 服务 OMS 对象存储迁移 他云对象存储数据迁移到华为云 华为云各Region间的数据迁移 与CDM的区别: OMS用于他云到华为云的数据迁移;CDM主要用于OBS数据迁移到数据湖或其他大数据系统,以便对数据进行开发、清洗、治理等。 数据复制服务 DRS 支持主流数据库到华为云的入云和出云迁移 数据库在线迁移 数据库实时同步 与CDM的区别: 数据库迁移使用DRS;到大数据系统的迁移使用CDM。 与UGO的区别: DRS支持同构和异构的数据库迁移/同步;UGO用于异构数据库的结构迁移、数据库迁移前评估、语法迁移等。 主机迁移服务 SMS 主机迁移 含物理机到华为云、其他自建或他云虚拟机到华为云 - 数据库和应用迁移 UGO 数据库结构迁移 数据库迁移前评估 语法迁移 与DRS的区别: DRS支持同构和异构的数据库迁移/同步;UGO用于异构数据库的结构迁移、数据库迁移前评估、语法迁移等。 数据快递服务 DES 海量数据,支持TB级到PB级数据上云 使用物理介质 -
  • 什么是数据库和应用迁移(UGO)? 数据库和应用迁移 UGO(Database and Application Migration UGO,简称UGO)是专注于异构数据库结构迁移的专业服务。可将数据库中的DDL、业务程序中封装的数据库SQL一键自动将语法转换为华为云 GaussDB /RDS的SQL语法,通过预迁移评估、结构迁移两大核心功能和自动化语法转换,提前识别可能存在的改造工作、提高转化率、最大化降低用户数据库迁移成本。更多详情请参见数据库和应用迁移。 简言之,UGO用于异构数据库迁移前的数据库评估、结构迁移、语法转化。
  • 什么是云数据迁移服务(CDM)? 云数据迁移(Cloud Data Migration,简称CDM)是一种高效、易用的数据集成服务。CDM围绕大数据迁移上云和 智能数据湖 解决方案,提供了简单易用的迁移能力和多种数据源到数据湖的集成能力,降低了客户数据源迁移和集成的复杂性,有效的提高您数据迁移和集成的效率。更多详情请参见云数据迁移服务。 CDM进行数据迁移时,目标端为数据湖或其他大数据系统;源端可以是数据库也可以是对象存储。 CDM与DRS的区别: 目的端是大数据系统时,推荐使用CDM。 目的端是OLTP数据库或DWS时,推荐使用DRS迁移。 CDM与OMS的区别: OMS用于入云迁移,支持以下源端云服务商:亚马逊云、阿里云、微软云、百度云、青云、七牛云、腾讯云。 CDM主要用于OBS数据迁移到数据湖或其他大数据系统,以便对数据进行开发、清洗、治理等。同时,整桶迁移建议使用OMS。
  • 什么是对象存储迁移服务(OMS)? 对象存储迁移服务(Object Storage Migration Service,简称OMS)是一种线上数据迁移服务,帮助您将其他云服务商 对象存储服务 中的数据在线迁移至华为云的对象存储服务(Object Storage Service,OBS)中。简言之,入云迁移、对象存储迁移。更多详情请参见对象存储迁移服务。 OMS主要功能有以下两个: 线上数据迁移服务:帮助用户把对象存储数据从其他云服务商的公有云轻松、平滑地迁移上云。 跨区域的复制:指的是华为云各个Region之间的数据复制和备份。 目前支持以下他云对象存储数据的入云迁移:亚马逊云、阿里云、微软云、百度云、华为云、金山云、青云、七牛云、腾讯云。 云数据迁移CDM服务也同样支持对象存储数据迁移,两者的区别为: OMS用于他云到华为云的数据迁移。 CDM主要用于OBS数据迁移到数据湖或其他大数据系统,以便对数据进行开发、清洗、治理等。
  • 什么是主机迁移服务(SMS)? 主机迁移服务(Server Migration Service,简称SMS)是一种P2V/V2V迁移服务,可以帮您把X86物理服务器或者私有云、公有云平台上的虚拟机迁移到华为云弹性云服务器上,从而帮助您轻松地把服务器上的应用和数据迁移到华为云。更多详情请参见主机迁移服务。 主机迁移服务 SMS 是一种P2V/V2V迁移服务,可以把X86物理服务器、私有云或公有云平台上的虚拟机迁移到华为E CS 上。
  • Hadoop类型的数据源进行数据迁移时,建议使用的组件版本有哪些? 建议使用的组件版本既可以作为目的端使用,也可以作为源端使用。 表1 建议使用的组件版本 Hadoop类型 组件 说明 MRS/Apache/ FusionInsight HD Hive 暂不支持2.x版本,建议使用的版本: 1.2.X 3.1.X HDFS 建议使用的版本: 2.8.X 3.1.X Hbase 建议使用的版本: 2.1.X 1.3.X 父主题: 功能类
  • 解决方案 如果是作为DataArts Studio服务CDM组件使用: 检查用户是否添加DAYU Administrator或DAYU User角色,参考DataArts Studio权限管理。 是否有对应工作空间的权限,如开发者、访客等,参考DataArts Studio权限列表。 如果是独立CDM服务使用: 检查是否开启IAM细粒度鉴权。 如果未开启,检查用户组是否添加CDM Administrator角色。 如果已开启,请继续执行步骤2继续检查。 检查用户是否添加CDM访问策略,包含自定义策略或预设策略,如CDM FullAccess、CDM ReadOnlyAccess等,参考CDM权限管理。 检查对应企业项目是否添加拒绝访问策略。
  • 如何降低CDM使用成本? 如果是迁移公网的数据上云,可以使用NAT网关服务,实现CDM服务与子网中的其他弹性云服务器共享弹性IP,可以更经济、更方便的通过Internet迁移本地数据中心或第三方云上的数据。 具体操作如下: 假设已经创建好了CDM集群(无需为CDM集群绑定专用弹性IP),记录下CDM集群所在的VPC和子网。 创建NAT网关,注意选择和CDM集群相同的VPC、子网。 创建完NAT网关后,回到NAT网关控制台列表,单击创建好的网关名称,然后选择“添加SNAT规则”。 图1 添加SNAT规则 选择子网和弹性IP,如果没有弹性IP,需要先申请一个。 完成之后,就可以到CDM控制台,通过Internet迁移公网的数据上云了。例如:迁移本地数据中心FTP服务器上的文件到OBS、迁移第三方云上关系型数据库到云服务RDS。 父主题: 通用类
  • 解决方法一:CDM的字段映射界面增加字段 获取源端HBase待迁移的表中所有的字段,列族与列之间用“:”分隔,例如: rowkey:rowkey g:DAY_COUNT g:CATEGORY_ID g:CATEGORY_NAME g:FIND_TIME g:UPLOAD_PEOPLE g:ID g:INFOMATION_ID g:TITLE g:COORDINATE_X g:COORDINATE_Y g:COORDINATE_Z g:CONTENT g:IMAGES g:STATE 在CDM的作业管理界面,找到HBase导出数据到DWS的作业,单击作业后面的“编辑”,进入字段映射界面,如图1所示。 图1 字段映射03 单击添加字段,在弹出框中选择“添加新字段”,如图2所示。 图2 添加字段04 添加完字段后,新增的字段在界面不显示样值,这个不影响字段值的传输,CDM会将字段值直接写入目的端。 这里“添加新字段”的功能,要求源端数据源为:MongoDB、HBase、关系型数据库或Redis,其中Redis必须为Hash数据格式。 全部字段添加完之后,检查源端和目的端的字段映射关系是否正确,如果不正确可以拖拽字段调整字段位置。 单击“下一步”后保存作业。
  • 原因分析 由于HBase/CloudTable无Schema,每条数据的列数不固定,在字段映射界面CDM通过获取样值的方式有较大概率无法获得所有列,此时作业执行完后会造成目的端的数据不全。 这个问题,可以通过以下方法解决: 在CDM的字段映射界面增加字段。 在CDM的作业管理界面直接编辑作业的JSON(修改“fromJobConfig.columns”、“toJobConfig.columnList”这2个参数)。 导出作业的JSON文件到本地,在本地手动修改JSON文件中的参数后(原理同2相同),再导回CDM。 推荐使用方法1,下面以HBase导到DWS为例进行说明。
  • 代码示例 使用Java调用CDM服务的REST API创建、启动、查询、删除CDM作业的代码示例如下: package cdmclient; import java.io.IOException; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class CdmClient { private final static String DOMAIN_NAME="云账号名"; private final static String USER_NAME="云用户名"; private final static String USER_PASSWORD="云用户密码"; private final static String PROJECT_ID="项目ID"; private final static String CLUSTER_ID="CDM集群ID"; private final static String JOB_NAME="作业名称"; private final static String FROM_LINKNAME="源连接名称"; private final static String TO_LINKNAME="目的连接名称"; private final static String IAM_ENDPOINT="IAM的Endpoint"; private final static String CDM_ENDPOINT="CDM的Endpoint"; private CloseableHttpClient httpclient; private String token; public CdmClient() { this.httpclient = createHttpClient(); this.token = login(); } private CloseableHttpClient createHttpClient() { CloseableHttpClient httpclient =HttpClients.createDefault(); return httpclient; } private String login(){ HttpPost httpPost = new HttpPost("https://"+IAM_ENDPOINT+"/v3/auth/tokens"); String json = "{\r\n"+ "\"auth\": {\r\n"+ "\"identity\": {\r\n"+ "\"methods\": [\"password\"],\r\n"+ "\"password\": {\r\n"+ "\"user\": {\r\n"+ "\"name\": \""+USER_NAME+"\",\r\n"+ "\"password\": \""+USER_PASSWORD+"\",\r\n"+ "\"domain\": {\r\n"+ "\"name\": \""+DOMAIN_NAME+"\"\r\n"+ "}\r\n"+ "}\r\n"+ "}\r\n"+ "},\r\n"+ "\"scope\": {\r\n"+ "\"project\": {\r\n"+ "\"name\": \"PROJECT_NAME\"\r\n"+ "}\r\n"+ "}\r\n"+ "}\r\n"+ "}\r\n"; try { StringEntity s = new StringEntity(json); s.setContentEncoding("UTF-8"); s.setContentType("application/json"); httpPost.setEntity(s); CloseableHttpResponse response = httpclient.execute(httpPost); Header tokenHeader = response.getFirstHeader("X-Subject-Token"); String token = tokenHeader.getValue(); System.out.println("Login successful"); return token; } catch (Exception e) { throw new RuntimeException("login failed.", e); } } /*创建作业*/ public void createJob(){ HttpPost httpPost = new HttpPost("https://"+CDM_ENDPOINT+"/cdm/v1.0/"+PROJECT_ID+"/clusters/"+CLUSTER_ID+"/cdm/job"); /**此处JSON信息比较复杂,可以先在作业管理界面上创建一个作业,然后单击作业后的“作业JSON定义”,复制其中的JSON内容,格式化为Java字符串语法,然后粘贴到此处。 *JSON消息体中一般只需要替换连接名、导入和导出的表名、导入导出表的字段列表、源表中用于分区的字段。**/ String json = "{\r\n"+ "\"jobs\": [\r\n"+ "{\r\n"+ "\"from-connector-name\": \"generic-jdbc-connector\",\r\n"+ "\"name\": \""+JOB_NAME+"\",\r\n"+ "\"to-connector-name\": \"generic-jdbc-connector\",\r\n"+ "\"driver-config-values\": {\r\n"+ "\"configs\": [\r\n"+ "{\r\n"+ "\"inputs\": [\r\n"+ "{\r\n"+ "\"name\": \"throttlingConfig.numExtractors\",\r\n"+ "\"value\": \"1\"\r\n"+ "}\r\n"+ "],\r\n"+ "\"validators\": [],\r\n"+ "\"type\": \"JOB\",\r\n"+ "\"id\": 30,\r\n"+ "\"name\": \"throttlingConfig\"\r\n"+ "}\r\n"+ "]\r\n"+ "},\r\n"+ "\"from-link-name\": \""+FROM_LINKNAME+"\",\r\n"+ "\"from-config-values\": {\r\n"+ "\"configs\": [\r\n"+ "{\r\n"+ "\"inputs\": [\r\n"+ "{\r\n"+ "\"name\": \"fromJobConfig.schemaName\",\r\n"+ "\"value\": \"sqoop\"\r\n"+ "},\r\n"+ "{\r\n"+ "\"name\": \"fromJobConfig.tableName\",\r\n"+ "\"value\": \"city1\"\r\n"+ "},\r\n"+ "{\r\n"+ "\"name\": \"fromJobConfig.columnList\",\r\n"+ "\"value\": \"code&name\"\r\n"+ "},\r\n"+ "{\r\n"+ "\"name\": \"fromJobConfig.partitionColumn\",\r\n"+ "\"value\": \"code\"\r\n"+ "}\r\n"+ "],\r\n"+ "\"validators\": [],\r\n"+ "\"type\": \"JOB\",\r\n"+ "\"id\": 7,\r\n"+ "\"name\": \"fromJobConfig\"\r\n"+ "}\r\n"+ "]\r\n"+ "},\r\n"+ "\"to-link-name\": \""+TO_LINKNAME+"\",\r\n"+ "\"to-config-values\": {\r\n"+ "\"configs\": [\r\n"+ "{\r\n"+ "\"inputs\": [\r\n"+ "{\r\n"+ "\"name\": \"toJobConfig.schemaName\",\r\n"+ "\"value\": \"sqoop\"\r\n"+ "},\r\n"+ "{\r\n"+ "\"name\": \"toJobConfig.tableName\",\r\n"+ "\"value\": \"city2\"\r\n"+ "},\r\n"+ "{\r\n"+ "\"name\": \"toJobConfig.columnList\",\r\n"+ "\"value\": \"code&name\"\r\n"+ "}, \r\n"+ "{\r\n"+ "\"name\": \"toJobConfig.shouldClearTable\",\r\n"+ "\"value\": \"true\"\r\n"+ "}\r\n"+ "],\r\n"+ "\"validators\": [],\r\n"+ "\"type\": \"JOB\",\r\n"+ "\"id\": 9,\r\n"+ "\"name\": \"toJobConfig\"\r\n"+ "}\r\n"+ "]\r\n"+ "}\r\n"+ "}\r\n"+ "]\r\n"+ "}\r\n"; try { StringEntity s = new StringEntity(json); s.setContentEncoding("UTF-8"); s.setContentType("application/json"); httpPost.setEntity(s); httpPost.addHeader("X-Auth-Token", this.token); httpPost.addHeader("X-Language", "en-us"); CloseableHttpResponse response = httpclient.execute(httpPost); int status = response.getStatusLine().getStatusCode(); if(status == 200){ System.out.println("Create job successful."); }else{ System.out.println("Create job failed."); HttpEntity entity = response.getEntity(); System.out.println(EntityUtils.toString(entity)); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Create job failed.", e); } } /*启动作业*/ public void startJob(){ HttpPut httpPut = new HttpPut("https://"+CDM_ENDPOINT+"/cdm/v1.0/"+PROJECT_ID+"/clusters/"+CLUSTER_ID+"/cdm/job/"+JOB_NAME+"/start"); String json = ""; try { StringEntity s = new StringEntity(json); s.setContentEncoding("UTF-8"); s.setContentType("application/json"); httpPut.setEntity(s); httpPut.addHeader("X-Auth-Token", this.token); httpPut.addHeader("X-Language", "en-us"); CloseableHttpResponse response = httpclient.execute(httpPut); int status = response.getStatusLine().getStatusCode(); if(status == 200){ System.out.println("Start job successful."); }else{ System.out.println("Start job failed."); HttpEntity entity = response.getEntity(); System.out.println(EntityUtils.toString(entity)); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Start job failed.", e); } } /*循环查询作业运行状态,直到作业运行结束。*/ public void getJobStatus(){ HttpGet httpGet = new HttpGet("https://"+CDM_ENDPOINT+"/cdm/v1.0/"+PROJECT_ID+"/clusters/"+CLUSTER_ID+"/cdm/job/"+JOB_NAME+"/status"); try { httpGet.addHeader("X-Auth-Token", this.token); httpGet.addHeader("X-Language", "en-us"); boolean flag = true; while(flag){ CloseableHttpResponse response = httpclient.execute(httpGet); int status = response.getStatusLine().getStatusCode(); if(status == 200){ HttpEntity entity = response.getEntity(); String msg = EntityUtils.toString(entity); if(msg.contains("\"status\":\"SUCCEEDED\"")){ System.out.println("Job succeeded"); break; }else if (msg.contains("\"status\":\"FAILED\"")){ System.out.println("Job failed."); break; }else{ Thread.sleep(1000); } }else{ System.out.println("Get job status failed."); HttpEntity entity = response.getEntity(); System.out.println(EntityUtils.toString(entity)); break; } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Get job status failed.", e); } } /*删除作业*/ public void deleteJob(){ HttpDelete httpDelte = new HttpDelete("https://"+CDM_ENDPOINT+"/cdm/v1.0/"+PROJECT_ID+"/clusters/"+CLUSTER_ID+"/cdm/job/"+JOB_NAME); try { httpDelte.addHeader("X-Auth-Token", this.token); httpDelte.addHeader("X-Language", "en-us"); CloseableHttpResponse response = httpclient.execute(httpDelte); int status = response.getStatusLine().getStatusCode(); if(status == 200){ System.out.println("Delete job successful."); }else{ System.out.println("Delete job failed."); HttpEntity entity = response.getEntity(); System.out.println(EntityUtils.toString(entity)); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Delete job failed.", e); } } /*关闭*/ public void close(){ try { httpclient.close(); } catch (IOException e) { throw new RuntimeException("Close failed.", e); } } public static void main(String[] args){ CdmClient cdmClient = new CdmClient(); cdmClient.createJob(); cdmClient.startJob(); cdmClient.getJobStatus(); cdmClient.deleteJob(); cdmClient.close(); } }
  • 解决方案 CDM虽然不支持直接在不同集群间迁移作业,但是通过批量导出、批量导入作业的功能,可以间接实现集群间的作业迁移,方法如下: 将CDM集群1中的所有作业批量导出,将作业的JSON文件保存到本地。 由于安全原因,CDM导出作业时没有导出连接密码,连接密码全部使用“Add password here”替换。 在本地编辑JSON文件,将“Add password here”替换为对应连接的正确密码。 将编辑好的JSON文件批量导入到CDM集群2,实现集群1和集群2之间的作业同步。
  • 套餐包到期未续订或按需资源欠费时,我的数据会保留吗? 云服务进入宽限期/保留期后,华为云将会通过邮件、短信等方式向您发送提醒,提醒您续订或充值。保留期到期仍未续订或充值,存储在云服务中的数据将被删除、云服务资源将被释放。 宽限期:指客户的包周期资源到期未续订或按需资源欠费时,华为云提供给客户进行续费与充值的时间,宽限期内客户可正常访问及使用云服务。 保留期:指宽限期到期后客户的包周期资源仍未续订或按需资源仍未缴清欠款,将进入保留期。保留期内客户不能访问及使用云服务,但对客户存储在云服务中的数据仍予以保留。 华为云宽限期和保留期时长设定请参考宽限期保留期。 父主题: 通用类
共100000条