华为云用户手册

  • 操作步骤 收集SQL中涉及到的所有表的统计信息。在数据库中,统计信息是规划器生成计划的源数据。没有收集统计信息或者统计信息陈旧往往会造成执行计划严重劣化,从而导致性能问题。从经验数据来看,10%左右性能问题是因为没有收集统计信息。具体请参见更新统计信息。 通过查看执行计划来查找原因。如果SQL长时间运行未结束,通过EXPLAIN命令查看执行计划,进行初步定位。如果SQL可以运行出来,则推荐使用EXPLAIN ANALYZE或EXPLAIN PERFORMANCE查看执行计划及实际运行情况,以便更准确地定位问题原因。有关执行计划的详细介绍请参见SQL执行计划介绍。 审视和修改表定义。 针对EXPLAIN或EXPLAIN PERFORMANCE信息,定位SQL慢的具体原因以及改进措施,具体参见典型SQL调优点。 通常情况下,有些SQL语句可以通过查询重写转换成等价的,或特定场景下等价的语句。重写后的语句比原语句更简单,且可以简化某些执行步骤达到提升性能的目的。查询重写方法在各个数据库中基本是通用的。经验总结:SQL语句改写规则介绍了几种常用的通过改写SQL进行调优的方法。
  • 告警场景 目前支持对以下7种导致性能问题的场景上报告警。 多列/单列统计信息未收集 如果存在单列或者多列统计信息未收集,则上报相关告警。调优方法可以参考更新统计信息和统计信息调优。 需要特别注意的是,对于基于OBS外表的查询,如果未收集统计信息也会上报统计信息未收集的告警,但是由于OBS外表的analyze的性能比较差,因此,需要用户对这种场景下告警是否通过analyze收集统计信息,以获取更优的性能,和查询本身的复杂度做权衡。 告警信息示例: 整表的统计信息未收集: Statistic Not Collect: schema_test.t1 单列统计信息未收集: Statistic Not Collect: schema_test.t2(c1,c2) 多列统计信息未收集: Statistic Not Collect: schema_test.t3((c1,c2)) 单列和多列统计信息未收集: Statistic Not Collect: schema_test.t4(c1,c2) schema_test.t4((c1,c2)) SQL不下推 对于不下推的SQL,尽可能详细上报导致不下推的原因。调优方法可以参考案例语句下推调优。 对于函数导致的不下推,告警导致不下推的函数名信息; 对于不支持下推的语法,会告警对应语法不支持下推,例如:含有With Recursive,Distinct On,row表达式,返回值为record类型的,会告警相应语法不支持下推等等。 告警信息示例: SQL is not plan-shipping, reason : "With Recursive" can not be shipped" SQL is not plan-shipping, reason : "Function now() can not be shipped" SQL is not plan-shipping, reason : "Function string_agg() can not be shipped" HashJoin中大表做内表 如果在表连接过程中使用了HashJoin(可以在GS_WLM_SESSION_HISTORY视图的query_plan字段中查看到),且连接的内表行数是外表行数的10倍或以上;同时内表在每个DN上的平均行数大于10万行,且发生了下盘,则上报相关告警。调优方法可以参考使用Plan Hint进行调优。 告警信息示例: PlanNode[7] Large Table is INNER in HashJoin “Vector Hash Aggregate” 大表等值连接使用Nestloop 如果在表连接过程中使用了nestloop(可以在GS_WLM_SESSION_HISTORY视图的query_plan字段中查看到),并且两个表中较大表的行数平均每个DN上的行数大于10万行、表的连接中存在等值连接,则上报相关告警。调优方法可以参考使用Plan Hint进行调优。 告警信息示例: PlanNode[5] Large Table with Equal-Condition use Nestloop"Nested Loop" 大表Broadcast 如果在Broadcast算子中,平均每DN的行数大于10万行,则告警大表broadcast。调优方法可以参考使用Plan Hint进行调优。 告警信息示例: PlanNode[5] Large Table in Broadcast "Streaming(type: BROADCAST dop: 1/2)" 数据倾斜 某表在各DN上的分布,存在某DN上的行数是另一DN上行数的10倍或以上,且有DN中的行数大于10万行,则上报相关告警。调优方法可以参考案例数据倾斜调优。 告警信息示例: PlanNode[6] DataSkew:"Seq Scan", min_dn_tuples:0, max_dn_tuples:524288 估算不准 如果优化器的估算行数和实际行数中的较大值平均每DN行数大于10万行,并且估算行数和实际行数中较大值是较小值的10倍或以上,则上报相关告警。调优方法可以参考使用Plan Hint进行调优。 告警信息示例: PlanNode[5] Inaccurate Estimation-Rows: "Hash Join" A-Rows:0, E-Rows:52488
  • 规格约束 告警字符串长度上限为2048。如果告警信息超过这个长度(例如存在大量未收集统计信息的超长表名,列名等信息)则不告警,只上报warning: WARNING, "Planner issue report is truncated, the rest of planner issues will be skipped" 如果query存在limit节点(即查询语句中包含limit),则不会上报limit节点以下的Operator级别的告警。 对于“数据倾斜”和“估算不准”两种类型告警,在某一个plan树结构下,只上报下层节点的告警,上层节点不再重复告警。这主要是因为这两种类型的告警可能是因为底层触发上层的。例如,如果在scan节点已经存在数据倾斜,那么在上层的hashagg等其他算子很可能也出现数据倾斜。
  • 检查隐式转换的性能问题 在某些场景下,数据类型的隐式转换可能会导致潜在的性能问题。请看如下的场景: SET enable_fast_query_shipping = off; CREATE TABLE t1(c1 VARCHAR, c2 VARCHAR); CREATE INDEX on t1(c1); EXPLAIN verbose SELECT * FROM t1 WHERE c1 = 10; 上述查询的执行计划如下: c1的数据类型是varchar,当查询的过滤条件为c1 = 10时,优化器默认将c1隐式转换为bigint类型,导致两个后果: 不能进行DN裁剪,计划下发到所有DN上执行。 计划中不能使用Index Scan方式扫描数据。 这会引起潜在的性能问题。 当知道了问题原因后,可以做针对性的SQL改写。对于上面的场景,只要将过滤条件中的常量显示转换为varchar类型,结果如下: EXPLAIN verbose SELECT * FROM t1 WHERE c1 = 10::varchar; 为了提前识别隐式类型转换可能带来的性能影响,GaussDB提供了一个guc option:check_implicit_conversions。打开该参数后,对于查询中出现的隐式类型转换的索引列,在路径生成阶段进行检查,如果发现索引列没有生成候选的索引扫描路径,则会通过报错的形式提示给用户。举例如下: SET check_implicit_conversions = on; SELECT * FROM t1 WHERE c1 = 10; ERROR: There is no optional index path for index column: "t1"."c1". Please check for potential performance problem. 参数check_implicit_conversions只用于检查隐式类型转换引起的潜在性能问题,在正式生产环境中请关闭该参数(该参数默认关闭)。 在将check_implicit_conversions打开时,必须同时关闭enable_fast_query_shipping参数,否则由于后一个参数的作用,无法查看对隐式类型转换修复的结果。 一个表的候选路径可能包括seq scan和index scan等多个可能的数据扫描方式,最终执行计划使用的表扫描方式是由执行计划的代价来决定的,因此即使生成了索引扫描的候选路径,也可能生成的最终执行计划中使用其它扫描方式。 父主题: SQL调优指南
  • 选择数据类型 高效数据类型,主要包括以下三方面: 尽量使用执行效率比较高的数据类型 一般来说整型数据运算(包括=、>、<、≧、≦、≠等常规的比较运算,以及group by)的效率比字符串、浮点数要高。比如某客户场景中对列存表进行点查询,filter条件在一个numeric列上,执行时间为10+s;修改numeric为int类型之后,执行时间缩短为1.8s左右。 尽量使用短字段的数据类型 长度较短的数据类型不仅可以减小数据文件的大小,提升IO性能;同时也可以减小相关计算时的内存消耗,提升计算性能。比如对于整型数据,如果可以用smallint就尽量不用int,如果可以用int就尽量不用bigint。 使用一致的数据类型 表关联列尽量使用相同的数据类型。如果表关联列数据类型不同,数据库必须动态地转化为相同的数据类型进行比较,这种转换会带来一定的性能开销。 父主题: 审视和修改表定义
  • 权限设计规范 业务使用前必须由root用户为业务创建DATABASE、SCHEMA和USER,然后再赋予相关用户对应对象的权限。 如果该用户不是该schema的owner,要访问schema下的对象,需要同时给用户赋予schema的usage权限和对象的相应权限。 DATABASE、SCHEMA和USER名使用小写。 由于数据库默认会把对象名称转为小写,连接串里面如果出现大写的对象名无法连接到数据库。如create user MyUser;创建的用户,无法使用user=MyUser连接到数据库,需要用user=myuser才能连接到数据库。为了避免混淆,一律使用小写。 合理对角色和用户赋权,应使用最小化权限原则。 表1 数据库对象权限及说明 对象 权限 说明 数据库 DATABASE CONNECT 允许用户连接到指定的数据库。 TEMP - CREATE 允许在数据库里创建新的模式。 模式 SCHEMA CREATE 允许在模式中创建新的对象。 USAGE 允许访问包含在指定模式中的对象,若没有该权限,则只能看到这些对象的名字。 函数 FUNCTION EXECUTE 允许使用指定的函数,以及利用这些函数实现的操作符。 表空间 TABLESPACE CREATE 允许在表空间中创建表,允许在创建数据库和模式的时候把该表空间指定为缺省表空间。 表 TABLE INSERT,DELETE UPDATE,SELECT 允许用户对指定表进行增删改查操作。 TRUNCATE 允许执行TRUNCATE语句删除指定表中的所有记录。 REFERENCES 创建一个外键约束,必须拥有参考表和被参考表的REFERENCES权限。 通过角色而不是用户来管理权限。 使用角色管理权限,即在角色中配置权限,再将角色赋予用户。 通过角色管理权限,更便于多用户、用户变更等场景下的权限管理。例如: 角色和用户为多对多关系,一个角色可以赋予多个用户,修改角色中的权限,被赋予角色的用户权限就可以同时更新。 删除用户时,不会影响到角色。 新建用户后可以通过赋予角色快速获取所需权限。 在删除指定数据库时,应回收用户对该数据库的CONNECT权限,避免删除时仍然存在活跃的数据库连接而失败。 父主题: 数据库设计规范
  • SQL调优指南 SQL调优的唯一目的是“资源利用最大化”,即CPU、内存、磁盘IO、网络IO四种资源利用最大化。所有调优手段都是围绕资源使用开展的。所谓资源利用最大化是指SQL语句尽量高效,节省资源开销,以最小的代价实现最大的效益。比如做典型点查询的时候,可以用seqscan+filter(即读取每一条元组和点查询条件进行匹配)实现,也可以通过indexscan实现,显然indexscan可以以更小的代价实现相同的效果。根据硬件资源和客户的业务特征确定合理的集群部署方案和表定义是数据库在多数情况下满足性能要求的基础。 Query执行流程 SQL执行计划介绍 调优流程 更新统计信息 审视和修改表定义 典型SQL调优点 经验总结:SQL语句改写规则 SQL调优关键参数调整 使用Plan Hint进行调优 检查隐式转换的性能问题 父主题: 性能调优
  • 示例 explain select /*+nestloop(store_sales tt) */ * from store_sales where ss_item_sk in (select /*+blockname(tt)*/ i_item_sk from item group by 1); 该hint表示:子链接的别名为tt,提升后与上层的store_sales表关联时使用nestloop。生成计划如下所示:
  • 参数说明 table表示为该子链接块hint的别名的名称。 blockname hint仅在对应的子链接块提升时才会被上层查询使用。目前支持的子链接提升包括IN子链接提升、EXISTS子链接提升和包含Agg等值相关子链接提升。该hint通常会和前面章节提到的hint联合使用。 对于FROM关键字后的子查询,则需要使用子查询的别名进行hint,blockname hint不会被用到。 如果子链接中含有多个表,则提升后这些表可与外层表以任意优化顺序连接,hint也不会被用到。
  • JDBC JDBC实例必须指定数据库,一旦实例创建,无法切换数据库。 单条SQL语句的长度不允许超过2G字节,业务应考虑通信成本,建议单条SQL语句不超过5K行。 不支持对DDL使用Prepare Execute执行方式。 fetchsize必须要在autocommit关闭情况下使用,否则fetchsize配置无效。 使用默认GUC参数,避免通过JDBC发送SET请求修改GUC参数。 更多说明请参考GUC参数编程规范。 必须使用Prepare Execute方式执行查询语句,提高执行效率。 JDBC客户端所在主机时区、数据库集群所在主机时区和集群配置过程中的时区,三者应保持一致。 如果在连接中创建了临时表,那么在将连接归还给连接池之前,必须将临时表删除,避免业务出错。 合理设置prepareThreshold,如果query语句十分固定,建议设置为1。 建议设置连接参数autobalance=true,开启CN负载均衡功能,并中设置多个CN连接地址(使用逗号分隔)。 一旦开启autobalance,JDBC DRIVER会尝试将JDBC connection分配到不同的CN节点上。 设置多个CN连接地址的目的是避免JDBC DRIVER在首次获取集群CN列表时,因所设置的CN节点故障而失败。 一旦首次成功获取,便不会再依赖连接参数中指定的CN列表,而是根据实时获取的集群CN列表,每隔一段时间,选取连接其中有效的CN获取最新的CN列表。 应根据业务上层请求超时时间合理设置JDBC连接超时时间,避免作业完成或常超作业持续占用数据库资源 超时参数包括loginTimeout、connectTimeout、socketTimeout等。 loginTimeout:Integer类型。指建立数据库连接的等待时间。超时时间单位为秒。 connectTimeout:Integer类型。用于连接CN操作的超时值。如果连接到CN花费的时间超过此值,则连接断开。超时时间单位为秒,默认值为0,表示已禁用,timeout不发生。 socketTimeout:Integer类型。用于socket读取操作的超时值。如果从CN读取所花费的时间超过此值,则连接关闭。超时时间单位为秒,默认值为0,表示已禁用,timeout不发生。 cancelSignalTimeout:Integer类型。发送取消消息本身可能会阻塞,此属性控制用于取消命令的“connect超时”和“socket超时”。超时时间单位为秒,默认值为10秒。 tcpKeepAlive:Boolean类型。启用或禁用TCP保活探测功能。默认为false。 以上参数可以在JDBC连接串或者property连接属性中配置,例如: 在连接串中配置: jdbc:postgresql://host:port/postgres?tcpKeepAlive=true 在property中配置: Properties info = new Properties(); Info.setProperty("tcpKeepAlive", true); 父主题: 客户端编程规范
  • 调优手段之统计信息 GaussDB优化器是典型的基于代价的优化 (Cost-Based Optimization,简称CBO)。在这种优化器模型下,数据库根据表的元组数、字段宽度、NULL记录比率、distinct值、MCV值、HB值等表的特征值,以及一定的代价计算模型,计算出每一个执行步骤的不同执行方式的输出元组数和执行代价(cost),进而选出整体执行代价最小/首元组返回代价最小的执行方式进行执行。这些特征值就是统计信息。从上面描述可以看出统计信息是查询优化的核心输入,准确的统计信息将帮助规划器选择最合适的查询规划,一般来说通过analyze语法收集整个表或者表的若干个字段的统计信息,周期性地运行ANALYZE,或者在对表的大部分内容做了更改之后马上运行它是个好习惯。
  • 调优手段之GUC参数 查询优化的主要目的是为查询语句选择高效的执行方式。 如下SQL语句: select count(1) from customer inner join store_sales on (ss_customer_sk = c_customer_sk); 在执行customer inner join store_sales的时候,GaussDB支持Nested Loop、Merge Join和Hash Join三种不同的Join方式。优化器会根据表customer和表store_sales的统计信息估算结果集的大小以及每种join方式的执行代价,然后对比选出执行代价最小的执行计划。 正如前面所说,执行代价计算都是基于一定的模型和统计信息进行估算,当因为某些原因代价估算不能反映真实的cost的时候,就需要通过GUC参数设置的方式让执行计划倾向更优规划。
  • 添加与会者 支持通过姓名、手机号、邮箱、历史会议等方式搜索用户进行邀请,快速开会。 直接拨打手机,外呼联系人。 预约会议时支持输入外部联系人的邮箱地址,预约完成后,将会以邮件形式发送会议通知给该联系人。 如果您添加了外部联系人,可以邀请外部联系人作为与会者。 您可以在“通讯录”页面选择“我的外部联系人”,单击右上角的按钮,添加个人外部联系人。 若您是企业管理员,也可以在“通讯录”页面选择“企业外部联系人”,单击右上角的按钮,跳转至华为云会议管理平台添加企业外部联系人。
  • 发起会议 您可以根据需要随时发起立即会议。 单击“发起会议”右侧的按钮,选择“更多会议设置”打开弹窗,可以选择使用不同类型的会议号,并设置来宾密码。 个人会议号:保持不变,方便记忆,适合召开部门例会。 此时可对来宾密码进行修改或置空的操作,置空后,其他用户无需输入会议密码即可主动接入会议。 自动生成会议号:随机产生,适合发起临时讨论,或召开安全性高的会议。 此时可以选择是否启用来宾密码。 云会议室会议号:会议资源稳定,适合召开大型或固定会议。 此时可对来宾密码进行修改或置空的操作,置空后,其他用户无需输入来宾密码即可主动接入会议。 如果您的企业同时购买了云会议室资源和并发资源,您可以选择云会议室会议号(需要企业管理员为您分配云会议室)、个人会议号、自动生成会议号。 如果您的企业只购买了会议并发资源,您可以选择个人会议号、自动生成会议号。 如果您的企业只购买了云会议室资源,您可以选择云会议室会议号(需要企业管理员为您分配云会议室)、自动生成会议号。 可以设置允许入会人员的范围。 如果您的企业购买了录播资源,还可以在“更多设置”中开启“自动录制会议”。 创建成功后,可邀请其他与会方加入会议。
  • 发起会议 可以选择使用不同类型的会议号,并设置来宾密码。 个人会议号:保持不变,方便记忆,适合召开部门例会。 此时可对来宾密码进行修改或置空的操作,置空后,其他用户无需输入会议密码即可主动接入会议。 随机会议号:随机产生,适合发起临时讨论,或召开安全性高的会议。 此时可以选择是否启用来宾密码。 云会议室会议号:会议资源稳定,适合召开大型或固定会议。 此时可对来宾密码进行修改或置空的操作,置空后,其他用户无需输入来宾密码即可主动接入会议。 如果您的企业同时购买了云会议室资源和并发资源,您可以选择云会议室会议号(需要企业管理员为您分配云会议室)、个人会议号、自动生成会议号。 如果您的企业只购买了会议并发资源,您可以选择个人会议号、自动生成会议号。 如果您的企业只购买了云会议室资源,您可以选择云会议室会议号(需要企业管理员为您分配云会议室)、自动生成会议号。 可以设置允许入会人员的范围。 如果您的企业购买了录播资源,还可以在“高级设置”中开启“自动录制会议”。 创建成功后,可邀请其他与会方加入会议。
  • 身份认证 无论通过管理控制台或API接口访问CodeArts Link,CodeArts Link使用统一身份认证服务IAM进行认证鉴权。 CodeArts Link支持两种认证方式: Token认证:通过Token认证调用请求。 AK/SK认证:通过AK(Access Key ID)/SK(Secret Access Key)加密调用请求。推荐使用AK/SK认证,其安全性比Token认证要高。 关于认证鉴权的详细介绍及获取方式,请参见认证鉴权。
  • 访问控制 用户级别资源隔离 权限管理是基于角色与权限的细粒度授权,即根据不同角色的工作需要分配不同的操作权限,用户只可访问被授权资源。 CodeArts中的资源目前是用户隔离的,用户只能看到自己创建和系统预置的组合应用、连接器、模板等资源。 运维SOD 为规范开发、测试、发布上线全流程运维脚本,推行和加强标准化作业的管理,保证流程合规、安全合规、质量合规。 防护墙和VPC隔离 CodeArts Link通过防护墙和VPC隔离支持租户间网络和资源隔离。
  • 标签命名规则 每个标签由一对键值对(Key-Value)组成。 每个数据加密服务资源最多可以添加20个标签。 对于每个资源,每个标签键(Key)都必须是唯一的,每个标签键(Key)只能有一个值(Value)。 标签共由两部分组成:“标签键”和“标签值”,其中,“标签键”和“标签值”的命名规则如表 标签参数说明所示。 标签以键值对的形式表示,用于标识存储库,便于对存储库进行分类和搜索。此处的标签仅用于存储库的过滤和管理。一个存储库最多添加10个标签。 如您的组织已经设定数据加密服务的相关标签策略,则需按照标签策略规则为密钥、凭据等添加标签。标签如果不符合标签策略的规则,则可能会导致密钥、凭据创建失败,请联系组织管理员了解标签策略详情。 表1 标签参数说明 参数 规则 样例 标签键 必填。 对于同一个自定义密钥,标签键唯一。 长度不超过128个字符。 首尾不能包含空格。 不能以_sys_开头。 可以包含以下字符: 中文 英文 数字 空格 特殊字符 “_”、“.”、“:”、“/”、“=”、“+”、 cost 标签值 可以为空。 长度不超过255个字符。 可以包含以下字符: 中文 英文 数字 空格 特殊字符 “_”、“.”、“:”、“/”、“=”、“+”、“-”、“@” 100
  • 添加转储到数据仓库服务(DWS)的转储任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 CreateTransferTaskRequest request = new CreateTransferTaskRequest(); //配置通道名称:用户在数据接入服务(简称DIS)控制台创建通道 request.setStreamName(streamName); //添加DWS转储任务,并设置任务名称 DwsDestinationDescriptorRequest descriptor = new DwsDestinationDescriptorRequest(); descriptor.setTransferTaskName(taskName); // 配置DWS集群信息:集群名称、集群ID、数据库等信息。可通过数据仓库服务(简称DWS)控制台创建和查询集群,并通过客户端或其他方式创建数据表 descriptor.setDwsClusterName("dis_test"); descriptor.setDwsClusterId("92f90f6a-de4d-4689-82f6-320c328b0062"); descriptor.setDwsDatabaseName("postgres"); descriptor.setDwsSchema("dbadmin"); descriptor.setDwsTableName("distable01"); descriptor.setDwsDelimiter("|"); descriptor.setUserName(System.getenv("DB_ADMIN")); descriptor.setUserPassword(System.getenv("DB_PASSWORD")); //DIS调用KMS服务加密存储DWS的密码,保证用户数据安全:用户可通过数据加密服务(简称KMS)控制台的"秘钥管理"创建和查询KMS秘钥信息 descriptor.setKmsUserKeyName("qiyinshan"); descriptor.setKmsUserKeyId("9521c600-64a8-4971-ad36-7bbfa6d00c41"); // 转储DWS通过OBS服务中转,需配置OBS桶名和子文件夹名,此目录也用于保存转储失败的源数据文件。可通过OBS控制台或客户端创建桶和文件夹 descriptor.setObsBucketPath("obs-dis"); descriptor.setFilePrefix("transfertask"); // 转储周期,单位s descriptor.setDeliverTimeInterval(900); // 可选:在DIS管理页面自动创建dis_admin_agency委托后,默认采用此委托。如未创建过IAM委托,请用主账户登录DIS控制台并创建通道,点击“添加转储任务”,前往授权。 descriptor.setAgencyName("dis_admin_agency"); // 设置从DIS通道拉取数据时的初始偏移量: 默认LATEST,从通道内最新上传的记录开始读取; TRIM_HORIZON,从通道内最早的未过期记录开始读取 descriptor.setConsumerStrategy(PartitionCursorTypeEnum.LATEST.name()); request.setDwsDestinationDescriptor(descriptor);
  • 添加转储到对象存储服务(OBS)的转储任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 CreateTransferTaskRequest request = new CreateTransferTaskRequest(); // 配置通道名称:用户在数据接入服务(简称DIS)控制台创建通道 request.setStreamName(streamName); // 添加OBS转储任务,并设置任务名称 OBSDestinationDescriptorRequest descriptor = new OBSDestinationDescriptorRequest(); descriptor.setTransferTaskName(taskName); // 转储至对象存储服务(简称OBS):OBS桶名和子文件夹名,通过OBS控制台或客户端创建桶和文件夹 descriptor.setObsBucketPath("obs-dis"); descriptor.setFilePrefix("transfertask"); // 转储周期,单位s descriptor.setDeliverTimeInterval(900); // 可选:在DIS管理页面自动创建名称为“dis_admin_agency”的IAM委托,默认采用此委托,用于授权访问。如未创建过IAM委托,请用主账户登录DIS控制台并创建通道,点击“添加转储任务”,前往授权。 descriptor.setAgencyName("dis_admin_agency"); // 可选,转储OBS的目标文件格式:默认text,可配置parquet、carbon descriptor.setDestinationFileType(DestinationFileTypeEnum.TEXT.getType()); // 设置从DIS通道拉取数据时的初始偏移量: 默认LATEST,从通道内最新上传的记录开始读取; TRIM_HORIZON,从通道内最早的未过期记录开始读取 descriptor.setConsumerStrategy(PartitionCursorTypeEnum.LATEST.name()); request.setObsDestinationDescriptor(descriptor);
  • 添加转储到MapReduce服务(MRS)的转储任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 CreateTransferTaskRequest request = new CreateTransferTaskRequest(); //配置通道名称:用户在数据接入服务(简称DIS)控制台创建通道 request.setStreamName(streamName); //添加MRS转储任务,并设置任务名称 MRSDestinationDescriptorRequest descriptor = new MRSDestinationDescriptorRequest(); descriptor.setTransferTaskName(taskName); // 配置MRS集群信息:集群名称和集群ID。可通过弹性大数据服务(简称MRS)控制台创建和查询,集群需为非安全模式 descriptor.setMrsClusterName("mrs_dis"); descriptor.setMrsClusterId("fe69a732-c7d3-4b0f-8cda-ec9eca0cf141"); // 转储MRS通过OBS服务中转,需配置OBS桶名和子文件夹名,此目录也用于保存转储失败的源数据文件。可通过OBS控制台或客户端创建桶和文件夹 descriptor.setObsBucketPath("obs-dis"); descriptor.setFilePrefix("transfertask"); // 转储周期,单位s descriptor.setDeliverTimeInterval(900); // 可选:在DIS管理页面自动创建dis_admin_agency委托后,默认采用此委托。如未创建过IAM委托,请用主账户登录DIS控制台并创建通道,点击“添加转储任务”,前往授权。 descriptor.setAgencyName("dis_admin_agency"); // 转储OBS的目标文件格式:默认text,可配置parquet、carbon descriptor.setDestinationFileType(DestinationFileTypeEnum.TEXT.getType()); // 设置从DIS通道拉取数据时的初始偏移量: 默认LATEST,从通道内最新上传的记录开始读取; TRIM_HORIZON,从通道内最早的未过期记录开始读取 descriptor.setConsumerStrategy(PartitionCursorTypeEnum.LATEST.name()); request.setMrsDestinationDescriptor(descriptor);
  • 添加转储到数据湖探索服务(DLI)的转储任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 CreateTransferTaskRequest request = new CreateTransferTaskRequest(); // 配置通道名称:用户在数据接入服务(简称DIS)控制台创建通道 request.setStreamName(streamName); // 添加DLI转储任务,并设置任务名称 UqueryDestinationDescriptorRequest descriptor = new UqueryDestinationDescriptorRequest(); descriptor.setTransferTaskName(taskName); // 配置DLI相关信息:数据库和内表名称。可通过数据湖探索(简称DLI)控制台创建和查询,DLI表需为内表 descriptor.setDliDatabaseName("dis_dli"); descriptor.setDliTableName("dis_test"); // 转储DLI通过OBS服务中转,需配置OBS桶名和子文件夹名,此目录也用于保存转储失败的源数据文件。可通过OBS控制台或客户端创建桶和文件夹 descriptor.setObsBucketPath("obs-dis"); descriptor.setFilePrefix("transfertask"); // 转储周期,单位s descriptor.setDeliverTimeInterval(900); // 可选:在DIS管理页面自动创建dis_admin_agency委托后,默认采用此委托。如未创建过IAM委托,请用主账户登录DIS控制台并创建通道,点击“添加转储任务”,前往授权。 descriptor.setAgencyName("dis_admin_agency"); // 设置从DIS通道拉取数据时的初始偏移量: 默认LATEST,从通道内最新上传的记录开始读取; TRIM_HORIZON,从通道内最早的未过期记录开始读取 descriptor.setConsumerStrategy(PartitionCursorTypeEnum.LATEST.name()); request.setDliDestinationDescriptor(descriptor);
  • 初始化DIS客户端 您可以使用以下两种方法初始化DIS SDK客户端实例,优先选择使用代码进行初始化。其中,“endpoint”,“ak”,“sk”,“region”,“projectId”信息请参看获取认证信息。 使用代码初始化DIS SDK客户端实例。 1 2 3 4 5 6 7 8 9 10 11 // 创建DIS客户端实例 DIS dic = DISClientBuilder.standard() .withEndpoint("YOUR_ENDPOINT") .withAk("YOUR_AK") .withSk("YOUR_SK") .withProjectId("YOUR_PROJECT_ID") .withRegion("YOUR_REGION") // 以下配置失败时的重试次数 .withProperty(DISConfig.PROPERTY_PRODUCER_RECORDS_RETRIES, "-1") .withProperty(DISConfig.PROPERTY_PRODUCER_EXCEPTION_RETRIES, "-1") .build(); 若需要使用代理,请使用如下方法初始化DIS客户端: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // 创建DIS客户端实例 DIS dic = DISClientBuilder.standard() .withEndpoint("YOUR_ENDPOINT") // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 .withAk(System.getenv("HUAWEICLOUD_SDK_AK")) .withSk(System.getenv("HUAWEICLOUD_SDK_SK")) .withProjectId("YOUR_PROJECT_ID") .withRegion("YOUR_REGION") .withProxyHost("YOUR_PROXY_HOST") // 代理IP .withProxyPort("YOUR_PROXY_PORT") // 代理端口 .withProxyProtocol(Protocol.HTTP) // 代理协议,默认为HTTP .withProxyUsername("YOUR_PROXY_USER_NAME") // 代理用户名(可选) .withProxyPassword("YOUR_PROXY_PASSWORD") // 代理密码(可选) // 以下配置失败时的重试次数 .withProperty(DISConfig.PROPERTY_PRODUCER_RECORDS_RETRIES, "-1") .withProperty(DISConfig.PROPERTY_PRODUCER_EXCEPTION_RETRIES, "-1") .build(); 若需在客户端设置DIS连接超时时间,请使用如下方法初始化DIS客户端: 1 2 3 4 5 6 7 8 9 // 创建DIS客户端实例 DIS dic = DISClientBuilder.standard() .withEndpoint("YOUR_ENDPOINT") .withAk(System.getenv("HUAWEICLOUD_SDK_AK")) .withSk(System.getenv("HUAWEICLOUD_SDK_SK")) .withProjectId("YOUR_PROJECT_ID") .withRegion("YOUR_REGION") .withProperty(DISConfig.PROPERTY_CONNECTION_TIMEOUT, "60") // 单位:秒 .build(); 若需要开启传输压缩,请使用如下方法初始化DIS客户端: 1 2 3 4 5 6 7 8 9 10 11 12 13 // 创建DIS客户端实例 DIS dic = DISClientBuilder.standard() .withEndpoint("YOUR_ENDPOINT") .withAk(System.getenv("HUAWEICLOUD_SDK_AK")) .withSk(System.getenv("HUAWEICLOUD_SDK_SK")) .withProjectId("YOUR_PROJECT_ID") .withRegion("YOUR_REGION") .withBodyCompressEnabled(true) .withBodyCompressType(CompressionType.ZSTD) // 配置压缩算法,当前支持lz4和zstd,默认值为lz4 // 以下配置失败时的重试次数 .withProperty(DISConfig.PROPERTY_PRODUCER_RECORDS_RETRIES, "-1") .withProperty(DISConfig.PROPERTY_PRODUCER_EXCEPTION_RETRIES, "-1") .build(); 若需在客户端将数据加密后再上传到DIS,DIS SDK提供了加密方法。即在构建disclient时增加参数DataEncryptEnabled和data.password。 1 2 3 4 5 6 7 8 9 10 11 12 13 // 创建DIS客户端实例 DIS dic = DISClientBuilder.standard() .withEndpoint("YOUR_ENDPOINT") .withAk(System.getenv("HUAWEICLOUD_SDK_AK")) .withSk(System.getenv("HUAWEICLOUD_SDK_SK")) .withProjectId("YOUR_PROJECT_ID") .withRegion("YOUR_REGION") .withDataEncryptEnabled(true) .withProperty("data.password", "xxx") //xxx替换为用户配置的数据加密秘钥 // 以下配置失败时的重试次数 .withProperty(DISConfig.PROPERTY_PRODUCER_RECORDS_RETRIES, "-1") .withProperty(DISConfig.PROPERTY_PRODUCER_EXCEPTION_RETRIES, "-1") .build(); 若使用JAVA SDK加密上传数据,读取数据也需要使用JAVA SDK配置相同的秘钥。 使用配置文件初始化DIS SDK客户端实例。 在“dis-sdk-demo\src\main\resources”目录下的“dis.properties”文件中添加如下配置项。 ak/sk:用户在IAM中创建的AK/SK。 region:用户使用通道所在的区域。 endpoint:DIS的访问地址。 projectId:通道所在的资源ID。 1 2 // 创建DIS客户端实例 DIS dic = DISClientBuilder.standard().build(); 父主题: 使用SDK(Java)
  • 初始化DIS客户端 您可以使用以下方法初始化DIS SDK客户端实例。其中,“endpoint”,“ak”,“sk”,“region”,“projectId”信息请参看获取认证信息。 cli = disclient(endpoint='**your-endpoint**', // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 ak=os.environ.get("HUAWEICLOUD_SDK_AK"), sk=os.environ.get("HUAWEICLOUD_SDK_SK"), projectid='**your-projectid**', region='**your-region**') 父主题: 使用SDK(Python)
  • Protobuf格式上传流式数据 参见初始化DIS客户端的操作初始化一个DIS客户端实例。 初始化DIS客户端,加入一项参数bodySerializeType,如下所示: cli = disclient(endpoint='', ak=os.environ.get("HUAWEICLOUD_SDK_AK"), sk=os.environ.get("HUAWEICLOUD_SDK_SK"), projectid='', region='',bodySerializeType='protobuf') 配置参数如下: 1 streamname="dis-test1" #已存在的通道名 参照该文件中的test方法,bodySerializeType="protobuf"选取protobuf格式上传。 protobuf_putRecords_sample.py文件中的protobuf_putRecords_test方法中的records为需要上传的数据内容,数据上传格式如下: 1 2 3 4 records=[{"data": "abcdefd", "partition_id": “shardId-0000000001”}] #"data":"xxx"为上传的数据值,请自定义;“partition_id”:“shardId-0000000001”为数据写入的分区id值,请自定义。 record1 = {"data": "xxx","partition_id": partition_id} #可写入多条数据,数据格式如record1所示,每写一条数据使用下面的append方法传入records中。 配置好以上参数后,执行protobuf_putRecords_sample.py文件调用protobuf_putRecords_test方法,响应结果下: 1 2 200 {'failed_record_count': 0, 'records': [{'partition_id': 'shardId-0000000001', 'sequence_number': '15'}]} 父主题: 使用SDK(Python)
  • Protobuf格式下载 参见初始化DIS客户端的操作初始化一个DIS客户端实例。 初始化DIS客户端,加入一项参数bodySerializeType,如下所示: cli = disclient(endpoint='', ak=os.environ.get("HUAWEICLOUD_SDK_AK"), sk=os.environ.get("HUAWEICLOUD_SDK_SK"), projectid='', region='',bodySerializeType='protobuf')
  • 参数说明 表2 参数说明 参数名 参数类型 说明 partitionId String 分区ID。 说明: 请根据上传流式数据的执行结果,控制台的返回信息字段,例如 “partitionId [shardId-0000000000]”进行定义。 startingSequenceNumber String 序列号。序列号是每个记录的唯一标识符。序列号由DIS在数据生产者调用PutRecords操作以添加数据到DIS数据通道时DIS服务自动分配的。同一分区键的序列号通常会随时间变化增加。PutRecords请求之间的时间段越长,序列号越大。 说明: 请根据上传流式数据的执行结果,控制台的返回信息字段,例如“sequenceNumber [1]”进行定义。 cursorType String 游标类型。 AT_SEQUENCE_NUMBER:从特定序列号(即startingSequenceNumber定义的序列号)所在的记录开始读取数据。此类型为默认游标类型。 AFTER_SEQUENCE_NUMBER:从特定序列号(即startingSequenceNumber定义的序列号)后的记录开始读取数据。 TRIM_HORIZON:从最早被存储至分区的有效记录开始读取。 例如,某租户使用DIS的通道,分别上传了三条数据A1,A2,A3。N天后(设定A1已过期,A2和A3仍在有效期范围内),该租户需要下载数据,并选择了TRIM_HORIZON这种下载方式。那么用户可下载的数据将从A2开始读取。 LATEST:从分区中的最新记录开始读取,此设置可以保证你总是读到分区中最新记录。 AT_TIMESTAMP:从特定时间戳(即timestamp定义的时间戳)开始读取。
  • 背景信息 下载流式数据,需要确定从分区的什么位置开始获取(即获取游标)。确定起始位置后,再循环获取数据。 获取游标有如下五种方式: AT_SEQUENCE_NUMBER AFTER_SEQUENCE_NUMBER TRIM_HORIZON LATEST AT_TIMESTAMP 为更好理解游标类型,您需要了解如下几个基本概念。 序列号(sequenceNumber),每个记录的唯一标识符。序列号由DIS在数据生产者调用PutRecord操作以添加数据到DIS数据通道时DIS服务自动分配的。同一分区键的序列号通常会随时间变化增加。PutRecords请求之间的时间段越长,序列号越大。 每个分区的sequenceNumber从0开始持续增长,每条数据对应唯一的sequenceNumber,超过生命周期后此sequenceNumber将过期不可用。(例如上传一条数据到新分区,其sequenceNumber起始为0,上传100条之后,则最后一条的sequenceNumber为99;如超过生命周期之后,0~99的数据则不可用) 分区的数据有效范围可以通过调用describeStream(查询通道详情)接口获取,其sequenceNumberRange代表数据有效范围,第一个值为最老数据的sequenceNumber,最后一个值为下一条上传数据的sequenceNumber(最新数据的sequenceNumber为此值-1) 例如[100, 200],表示此分区总共上传了200条数据,其中第0~99条已过期,有效的最老数据为100,最新数据为199,下一条上传数据的sequenceNumber为200。
  • 响应示例:设置桶的网站配置,并重定向错误 x-obs-id-2: 32AAAQAAEAABSAAgAAEAABAAAQAAEAABCS/xBBLGZwRUiL439eWMw1v/vphFB6JY x-obs-request-id: 0000018A3A06C048D38610C04366B2F5 Server: OBS Content-Length: 0 Date: WED, 01 Jul 2015 02:37:22 GMT
  • 响应示例:设置桶的网站配置,不配置重定向 x-obs-id-2: 32AAAQAAEAABSAAgAAEAABAAAQAAEAABCSfxlr+FrXuJzYpLod1lrLK45tVx+GPR x-obs-request-id: 0000018A39F07D0DD3888442DC29719E Server: OBS Content-Length: 0 Date: WED, 01 Jul 2015 02:37:22 GMT
共100000条