• [其他] 联邦学习
        联邦机器学习(Federated machine learning/Federated Learning),又名联邦学习,联合学习,联盟学习。联邦机器学习是一个机器学习框架,能有效帮助多个机构在满足用户隐私保护、数据安全和政府法规的要求下,进行数据使用和机器学习建模。联邦学习作为分布式的机器学习范式,可以有效解决数据孤岛问题,让参与方在不共享数据的基础上联合建模,能从技术上打破数据孤岛,实现AI协作。谷歌在2016年提出了针对手机终端的联邦学习,微众银行AI团队则从金融行业实践出发,关注跨机构跨组织的大数据合作场景,首次提出“联邦迁移学习”的解决方案,将迁移学习和联邦学习结合起来。据杨强教授在“联邦学习研讨会”上介绍,联邦迁移学习让联邦学习更加通用化,可以在不同数据结构、不同机构间发挥作用,没有领域和算法限制,同时具有模型质量无损、保护隐私、确保数据安全的优势。    联邦学习定义了机器学习框架,在此框架下通过设计虚拟模型解决不同数据拥有方在不交换数据的情况下进行协作的问题。虚拟模型是各方将数据聚合在一起的最优模型,各自区域依据模型为本地目标服务。联邦学习要求此建模结果应当无限接近传统模式,即将多个数据拥有方的数据汇聚到一处进行建模的结果。在联邦机制下,各参与者的身份和地位相同,可建立共享数据策略。由于数据不发生转移,因此不会泄露用户隐私或影响数据规范。为了保护数据隐私、满足合法合规的要求。联邦学习有三大构成要素:数据源、联邦学习系统、用户。三者间关系如图所示,在联邦学习系统下,各个数据源方进行数据预处理,共同建立及其学习模型,并将输出结果反馈给用户。联邦学习的分类根据参与各方数据源分布的情况不同,联邦学习可以被分为三类:横向联邦学习、纵向联邦学习、联邦迁移学习。横向联邦学习在两个数据集的用户特征重叠较多而用户重叠较少的情况下,我们把数据集按照横向(即用户维度)切分,并取出双方用户特征相同而用户不完全相同的那部分数据进行训练。这种方法叫做横向联邦学习。比如业务相同但是分布在不同地区的两家企业,它们的用户群体分别来自各自所在的地区,相互的交集很小。但是,它们的业务很相似,因此,记录的用户特征是相同的。此时,就可以使用横向联邦学习来构建联合模型。横向联邦学习中多方联合训练的方式与分布式机器学习(Distributed Machine Learning)有部分相似的地方。分布式机器学习涵盖了多个方面,包括把机器学习中的训练数据分布式存储、计算任务分布式运行、模型结果分布式发布等,参数服务器是分布式机器学习中一个典型的例子。参数服务器作为加速机器学习模型训练过程的一种工具,它将数据存储在分布式的工作节点上,通过一个中心式的调度节点调配数据分布和分配计算资源,以便更高效的获得最终的训练模型。而对于联邦学习而言,首先在于横向联邦学习中的工作节点代表的是模型训练的数据拥有方,其对本地的数据具有完全的自治权限,可以自主决定何时加入联邦学习进行建模,相对地在参数服务器中,中心节点始终占据着主导地位,因此联邦学习面对的是一个更复杂的学习环境;其次,联邦学习则强调模型训练过程中对数据拥有方的数据隐私保护,是一种应对数据隐私保护的有效措施,能够更好地应对未来愈加严格的数据隐私和数据安全监管环境。纵向联邦学习在两个数据集的用户重叠较多而用户特征重叠较少的情况下,我们把数据集按照纵向(即特征维度)切分,并取出双方用户相同而用户特征不完全相同的那部分数据进行训练。这种方法叫做纵向联邦学习。比如有两个不同机构,一家是某地的银行,另一家是同一个地方的电商。它们的用户群体很有可能包含该地的大部分居民,因此用户的交集较大。但是,由于银行记录的都是用户的收支行为与信用评级,而电商则保有用户的浏览与购买历史,因此它们的用户特征交集较小。纵向联邦学习就是将这些不同特征在加密的状态下加以聚合,以增强模型能力的联邦学习。目前机器学习模型如逻辑回归、决策树等均是建立在纵向联邦学习系统框架之下的。联邦迁移学习在两个数据集的用户与用户特征重叠都较少的情况下,我们不对数据进行切分,而可以利用迁移学习来克服数据或标签不足的情况。这种方法叫做联邦迁移学习。比如有两个不同机构,一家是位于中国的银行,另一家是位于美国的电商。由于受到地域限制,这两家机构的用户群体交集很小。同时,由于机构类型的不同,二者的数据特征也只有小部分重合。在这种情况下,要想进行有效的联邦学习,就必须引入迁移学习,来解决单边数据规模小和标签样本少的问题,从而提升模型的效果。
  • [技术干货] Saga模式小窍门
    Saga模式小窍门1,给每一个分布式事务创建一个唯一的Tx id。这个唯一的Tx id可以用来在各个业务参与方沟通时精确定位哪一笔分布式事务。2,对于基于命令的方式,在命令中携带回复地址。这种方式可以让服务同时响应多个协调中心请求。3,幂等性。幂等性能够增加系统的容错性,让各个业务参与方服务提供幂等性操作,能够在遇到异常情况下进行重试。4,尽量在命令或者消息中携带下游处理需要的业务数据,避免下游处理时需要调用消息产生方接口获取更多数据。减少系统之间的相互依赖。
  • [SQL] 【GaussDB(DWS)征文】GaussDB(DWS)分布式计算的倾斜优化
    数据倾斜问题是分布式架构的重要难题,它破坏了MPP架构中各个节点对等的要求,导致单节点(倾斜节点)所存储或者计算的数据量远大于其他节点,所以会造成以下危害:存储上的倾斜会严重限制系统容量,在系统容量不饱和的情况下,由于单节点倾斜的限制,使得整个系统容量无法继续增长。计算上的倾斜会严重影响系统性能,由于倾斜节点所需要运算的数据量远大于其它节点,导致倾斜节点降低系统整体性能。数据倾斜还严重影响了MPP架构的扩展性。由于在存储或者计算时,往往会将相同值的数据放到同一节点,因此当倾斜数据(大量数据的值相同)出现之后,即使我们增加节点,系统瓶颈仍然受限于倾斜节点的容量或者性能。GaussDB(DWS)数据库针对数据倾斜问题给出了完整的解决方案,下面简单介绍一下GaussDB(DWS)倾斜优化的机制和效果1. 预置条件CREATE TABLE t1(a int, b int) DISTRIBUTE BY HASH(a); CREATE TABLE t2(a int, b int) DISTRIBUTE BY HASH(a); INSERT INTO t1 VALUES (generate_series(1, 1000), generate_series(1, 1000)); INSERT INTO t1 SELECT a+1000*2, b+1000*2 FROM t1; INSERT INTO t1 SELECT a+1000*2*2, b+1000*2*2 FROM t1; INSERT INTO t1 SELECT a+1000*2*2*2, b+1000*2*2*2 FROM t1; INSERT INTO t1 SELECT a+1000*2*2*2*2, b+1000*2*2*2*2 FROM t1; INSERT INTO t1 SELECT a+1000*2*2*2*2*2, b+1000*2*2*2*2*2 FROM t1; INSERT INTO t1 SELECT a+1000*2*2*2*2*2*2, b+1000*2*2*2*2*2*2 FROM t1; INSERT INTO t1 SELECT a+1000*2*2*2*2*2*2*2, b+1000*2*2*2*2*2*2*2 FROM t1; INSERT INTO t2 SELECT a, 1 FROM t1; ANALYZE t1; ANALYZE t2;2. 执行概述以如下SQL为例,分析普通执行机制和倾斜优化执行机制的差异SELECT count(1) FROM t1 INNER JOIN t2 ON t1.b = t2.b;2.1 非倾斜优化执行机制GaussDB(DWS)默认采取倾斜优化执行机制。在在生成执行计划阶段,优化器根据统计信息识别杂在join列上是否存在倾斜情况,如果识别存在倾斜,自动生成优化优化计划。同时GaussDB(DWS)提供了配置参数skew_option,设置此参数为off之后,优化器会skip倾斜优化计划。postgres=# SET skew_option TO off; SET postgres=# explain analyze SELECT count(1) FROM t1 INNER JOIN t2 ON t1.b = t2.b;                                                                     QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------   id |                 operation                  |       A-time       | A-rows | E-rows | Peak Memory  | E-memory | A-width | E-width | E-costs  ----+--------------------------------------------+--------------------+--------+--------+--------------+----------+---------+---------+----------    1 | ->  Aggregate                              | 371.797            |      1 |      1 | 10KB         |          |         |       8 | 14928.22    2 |    ->  Streaming (type: GATHER)            | 371.693            |      4 |      4 | 79KB         |          |         |       8 | 14928.22    3 |       ->  Aggregate                        | [236.825, 350.166] |      4 |      4 | [10KB, 10KB] | 1MB      |         |       8 | 14918.22    4 |          ->  Hash Join (5,7)               | [236.817, 298.880] | 128000 | 128000 | [4KB, 5KB]   | 1MB      |         |       0 | 14838.21    5 |             ->  Streaming(type: BROADCAST) | [82.726, 144.617]  | 512000 | 512000 | [53KB, 53KB] | 2MB      |         |       4 | 13168.21    6 |                ->  Seq Scan on t2          | [15.528, 25.093]   | 128000 | 128000 | [12KB, 12KB] | 1MB      |         |       4 | 469.00    7 |             ->  Hash                       | [35.826, 69.033]   | 128000 | 128000 | [1MB, 1MB]   | 16MB     | [20,20] |       4 | 470.00    8 |                ->  Seq Scan on t1          | [17.163, 35.748]   | 128000 | 128000 | [12KB, 12KB] | 1MB      |         |       4 | 470.00  Predicate Information (identified by plan id)  ---------------------------------------------    4 --Hash Join (5,7)          Hash Cond: (t2.b = t1.b)               Memory Information (identified by plan id)  --------------------------------------------------------------------  Coordinator Query Peak Memory:          Query Peak Memory: 1MB  Datanode:          Max Query Peak Memory: 4MB          Min Query Peak Memory: 4MB    7 --Hash          Max Buckets: 32768  Max Batches: 1  Max Memory Usage: 1130kB          Min Buckets: 32768  Min Batches: 1  Min Memory Usage: 1120kB                       User Define Profiling  ----------------------------------------------------------------  Segment Id: 3  Track name: Datanode build connection   (actual time=[0.759, 15.526], calls=[1, 1])  Segment Id: 3  Track name: Datanode wait connection   (actual time=[0.001, 0.638], calls=[1, 1])  Plan Node id: 2  Track name: coordinator get datanode connection   (actual time=[0.032, 0.032], calls=[1, 1])                            ====== Query Summary =====  -------------------------------------------------------------------------------  Datanode executor start time [dn_6003_6004, dn_6001_6002]: [2.036 ms,16.202 ms]  Datanode executor end time [dn_6007_6008, dn_6001_6002]: [0.606 ms,1.310 ms]  System available mem: 3112960KB  Query Max mem: 3112960KB  Query estimated mem: 6690KB  Coordinator executor start time: 0.529 ms  Coordinator executor run time: 372.044 ms  Coordinator executor end time: 0.436 ms  Planner runtime: 1.156 ms  Query Id: 72339069014639413  Total runtime: 373.079 ms (49 rows)正常机制下,t1和t2表都会按照b列做数据重分,重分布之后在各个DN上进行JOIN操作。但是此处的表t2的数据比较特殊,表t2的字段b上值为1比例高达100%,这样的话重分布之后值1所在DN上的计算量会比其它DN大,我们一般称之为计算倾斜。计算倾斜一般会导致两个问题1)重负载DN上资源开销比较大,导致集群负载不均衡2)重负载DN上计算耗时较长,短板效应导致SQL执行时间变长针对这种场景GaussDB(DWS)进行了特殊的倾斜执行优化2.2 倾斜优化执行机制postgres=# RESET skew_option; RESET postgres=# explain analyze SELECT count(1) FROM t1 INNER JOIN t2 ON t1.b = t2.b;                                                                                  QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------   id |                              operation                               |       A-time       | A-rows | E-rows | Peak Memory  | E-memory | A-width | E-width | E-costs  ----+----------------------------------------------------------------------+--------------------+--------+--------+--------------+----------+---------+---------+---------    1 | ->  Aggregate                                                        | 182.837            |      1 |      1 | 10KB         |          |         |       8 | 7309.01    2 |    ->  Streaming (type: GATHER)                                      | 182.748            |      4 |      4 | 79KB         |          |         |       8 | 7309.01    3 |       ->  Aggregate                                                  | [158.711, 169.947] |      4 |      4 | [10KB, 10KB] | 1MB      |         |       8 | 7299.01    4 |          ->  Hash Join (5,7)                                         | [147.187, 156.273] | 128000 | 128000 | [5KB, 5KB]   | 1MB      |         |       0 | 7219.00    5 |             ->  Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN)   | [16.308, 23.164]   | 128000 | 128000 | [53KB, 53KB] | 2MB      |         |       4 | 3189.00    6 |                ->  Seq Scan on t2                                    | [14.062, 17.578]   | 128000 | 128000 | [12KB, 12KB] | 1MB      |         |       4 | 469.00    7 |             ->  Hash                                                 | [87.374, 92.295]   | 128003 | 128000 | [1MB, 1MB]   | 16MB     | [20,20] |       4 | 3190.00    8 |                ->  Streaming(type: PART REDISTRIBUTE PART BROADCAST) | [51.194, 56.189]   | 128003 | 128000 | [61KB, 61KB] | 2MB      |         |       4 | 3190.00    9 |                   ->  Seq Scan on t1                                 | [13.989, 15.170]   | 128000 | 128000 | [12KB, 12KB] | 1MB      |         |       4 | 470.00       Predicate Information (identified by plan id)  --------------------------------------------------------    4 --Hash Join (5,7)          Hash Cond: (t2.b = t1.b)          Skew Join Optimized by Statistic    5 --Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN)          Skew Filter: (b = 1)    8 --Streaming(type: PART REDISTRIBUTE PART BROADCAST)          Skew Filter: (b = 1)               Memory Information (identified by plan id)  --------------------------------------------------------------------  Coordinator Query Peak Memory:          Query Peak Memory: 1MB  Datanode:          Max Query Peak Memory: 6MB          Min Query Peak Memory: 6MB    7 --Hash          Max Buckets: 32768  Max Batches: 1  Max Memory Usage: 1131kB          Min Buckets: 32768  Min Batches: 1  Min Memory Usage: 1120kB                       User Define Profiling  ----------------------------------------------------------------  Segment Id: 3  Track name: Datanode build connection   (actual time=[2.924, 7.101], calls=[1, 1])  Segment Id: 3  Track name: Datanode wait connection   (actual time=[0.000, 1.478], calls=[1, 1])  Plan Node id: 2  Track name: coordinator get datanode connection   (actual time=[0.025, 0.025], calls=[1, 1])                            ====== Query Summary =====  ------------------------------------------------------------------------------  Datanode executor start time [dn_6005_6006, dn_6003_6004]: [3.544 ms,8.513 ms]  Datanode executor end time [dn_6005_6006, dn_6001_6002]: [0.450 ms,0.576 ms]  System available mem: 3112960KB  Query Max mem: 3112960KB  Query estimated mem: 8802KB  Coordinator executor start time: 0.665 ms  Coordinator executor run time: 183.161 ms  Coordinator executor end time: 0.607 ms  Planner runtime: 1.517 ms  Query Id: 72339069014639134  Total runtime: 184.519 ms针对计算倾斜场景下,在数据重分布的时候对倾斜值进行特殊优化。此查询中JOIN的外表t2的字段b在值1上有倾斜内外表除了1之外的值按照正常机制进行分布和计算 对于外表(t2)上重分布字段b为1的值,进行roundrobin分布(均匀打散到各个DN上)对于内表(t1)上重分布字段b为1的值,进行broadcast分布(每个DN都保留一份)注:除非t1表是复制分布,否则PART ROUNDROBIN和PART BROADCAST总是配对出现通过这种分布机制,可以把外表重分布字段b为1的值的计算压力均摊到各个DN上,从而避免计算倾斜问题。从上述也可以看出比较明显的优化效果
  • [SQL] 如何通过SQL进行分布式死锁的检测与消除
    【摘要】 实际业务中,我们可能会遇到数据库系统 hang 住的问题,分布式死锁是数据库系统 hang 问题的一个主要原因。本文重点介绍如何通过 SQL 语句,对分布式死锁进行检测和恢复。分布式数仓应用场景中,我们经常遇到数据库系统 hang 住的问题,所谓 hang 是指虽然数据库系统还在运行,但部分或全部业务无法正常执行。hang 问题的原因有很多,其中以分布式死锁最为常见,本次主要分享在碰到分布式死锁时,如何快速地解决死锁问题。GaussDB(DWS) 作为分布式数仓,通过锁机制来实行并发控制,因此也存在产生分布式死锁的可能。虽然分布式死锁无法避免,但幸运的是其提供了多种系统视图,能够保证在分布式死锁发生之后,快速地对死锁进行定位。本文主要介绍了在 GaussDB(DWS) 中,如何通过 SQL 语句,对分布式死锁进行检测和恢复。本文介绍的方法大致分为 4 步:1. 收集各节点的锁信息。2. 构建等待关系。3. 检测循环等待。4. 中止事务以消除死锁。本文介绍的方法使用简单,门槛低,可以确保在分布式死锁发生之后,快速解决问题,恢复业务。通过 SQL 语句进行分布式死锁的检测与消除分布式死锁和单节点死锁的比较单节点死锁单节点死锁是指,死锁中的所有锁等待信息来自同一个节点,例如:-- 事务 transaction1-- 所在节点:CN1BEGIN;TRUNCATE t1;EXECUTE DIRECT ON(DN1) 'SELECT * FROM t2';COMMIT;-- 事务 transaction2-- 所在节点:CN1BEGIN;TRUNCATE t2;EXECUTE DIRECT ON(DN2) 'SELECT * FROM t1';COMMIT;假设上述两个事务的执行顺序如下:1. [transaction1] TRUNCATE t12. [transaction2] TRUNCATE t23. [transaction1] EXECUTE DIRECT ON(DN1) 'SELECT * FROM t2'4. [transaction2] EXECUTE DIRECT ON(DN2) 'SELECT * FROM t1'该执行顺序会导致死锁的产生。由于事务 transaction1 和 transaction2 都在 CN1 上执行,死锁中的所有锁等待信息都在 CN1 上,因此该死锁为单节点死锁。节点持有锁等待锁CN1[transaction1] TRUNCATE t1[transaction2] EXECUTE DIRECT ON(DN1) 'SELECT * FROM t2'CN1[transaction2] TRUNCATE t2[transaction1] EXECUTE DIRECT ON(DN2) 'SELECT * FROM t1'GaussDB(DWS) 支持自动处理单节点死锁。当某个节点上的多个事务陷入循环等待时,数据库系统会自动将其中一个事务中止,从而消除死锁。分布式死锁分布式死锁是指,死锁中的锁等待信息来自不同节点。例如:-- 事务 transaction1-- 所在节点:CN1BEGIN;TRUNCATE t1;EXECUTE DIRECT ON(DN1) 'SELECT * FROM t2';COMMIT;-- 事务 transaction2-- 所在节点:CN2BEGIN;TRUNCATE t2;EXECUTE DIRECT ON(DN2) 'SELECT * FROM t1';COMMIT;本例与上一节中的例子相比,只有事务 transaction2 的所在节点从 CN1 改为了 CN2。假设两个事务的执行顺序和上一节中的执行顺序一致,还是会产生死锁,死锁中的锁等待信息如下:节点持有锁等待锁CN1[transaction1] TRUNCATE t1[transaction2] EXECUTE DIRECT ON(DN1) 'SELECT * FROM t2'CN2[transaction1] TRUNCATE t2[transaction1] EXECUTE DIRECT ON(DN2) 'SELECT * FROM t1'这就是一个典型的分布式死锁,单独看 CN1 或 CN2 上的锁等待信息,都看不出来有死锁,但将多个节点的锁等待信息放到一起看,就能找到有循环等待的现象。发生分布式死锁时,陷入死锁的事务全部都无法继续执行下去,只有其中一个事务锁等待超时,剩余事务才能继续执行。默认情况下,锁等待超时时间是 20 分钟。分布式死锁的检测与消除当我们观察到数据库系统出现 hang 问题时,我们需要通过 SQL 语句检测分布式死锁,如果发现确实存在分布式死锁,还需要对死锁进行消除。接下来以之前的分布式死锁为例,介绍分布式死锁的检测和消除的方法。收集各节点的锁信息为了检测分布式死锁,首先需要获得各节点的锁信息。GaussDB(DWS) 中可以通过 PG_LOCKS 视图查询当前节点的锁信息,因此可以通过 EXECUTE DIRECT 语句在所有节点查询 PG_LOCKS 视图,并收集到当前节点中。注意此处有一个细节,PG_LOCKS 视图中,很多信息是以 OID 类型给出的,例如一个锁加在一个表上,PG_LOCKS 视图会给出表的 OID。由于同一个表在各节点中的 OID 不一定相同,因此不能通过 OID 来标识一个表。在收集锁信息时,需要先将表的 OID 转换成 SCHEMA 名加表名。其它 OID 信息例如分区 OID 等也同理,需要转化为对应的名字。执行附件中的示例代码 pgxc_locks.sql,就可以收集到各节点的锁信息:   locktype    |   nodename   | datname  | usename | nspname | relname | partname | page | tuple | virtualxid | transactionid | virtualtransaction |        mode         | granted | client_addr | application_name |       pid       |         xact_start         |        query_start         |        state        |     query_id      |                        query---------------+--------------+----------+---------+---------+---------+----------+------+-------+------------+---------------+--------------------+---------------------+---------+-------------+------------------+-----------------+----------------------------+----------------------------+---------------------+-------------------+----------------------------------------------------- virtualxid    | cn_5002      | postgres | tyx_1   |         |         |          |      |       | 12/94      |               | 12/94              | ExclusiveLock       | t       |             | gsql             | 140110481323776 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:19:37.715447 | active              |                 0 | EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1'; virtualxid    | cn_5002      | postgres | tyx_1   |         |         |          |      |       | 9/298      |               | 9/298              | ExclusiveLock       | t       | ::1/128     | cn_5001          | 140110672164608 | 2020-12-25 17:18:40.478704 | 2020-12-25 17:18:40.479682 | idle in transaction |                 0 | TRUNCATE t1; virtualxid    | cn_5002      | postgres | tyx_1   |         |         |          |      |       | 6/161      |               | 6/161              | ExclusiveLock       | t       |             | WLMArbiter       | 140110762325760 | 2020-12-25 17:20:18.613815 | 2020-12-25 16:53:35.027585 | active              |                 0 | WLM arbiter sync info by CCN and CNs virtualxid    | cn_5002      | postgres | tyx_1   |         |         |          |      |       | 5/162      |               | 5/162              | ExclusiveLock       | t       |             | WorkloadMonitor  | 140110779119360 | 2020-12-25 17:20:27.16458  | 2020-12-25 16:53:35.027217 | active              |                 0 | WLM monitor update and verify local info virtualxid    | cn_5002      | postgres | tyx_1   |         |         |          |      |       | 3/325      |               | 3/325              | ExclusiveLock       | t       |             | workload         | 140110846744320 | 2020-12-25 17:20:25.372654 | 2020-12-25 16:53:35.02741  | active              | 72339069014641297 | WLM fetch collect info from data nodes advisory      | cn_5002      | postgres | tyx_1   |         |         |          |      |       |            |               | 12/94              | ShareLock           | t       |             | gsql             | 140110481323776 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:19:37.715447 | active              |                 0 | EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1'; relation      | cn_5002      | postgres | tyx_1   | public  | t1      |          |      |       |            |               | 9/298              | AccessExclusiveLock | t       | ::1/128     | cn_5001          | 140110672164608 | 2020-12-25 17:18:40.478704 | 2020-12-25 17:18:40.479682 | idle in transaction |                 0 | TRUNCATE t1; relation      | cn_5002      | postgres | tyx_1   | public  | t1      |          |      |       |            |               | 12/94              | AccessShareLock     | f       |             | gsql             | 140110481323776 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:19:37.715447 | active              |                 0 | EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1'; transactionid | cn_5002      | postgres | tyx_1   |         |         |          |      |       |            | 10269         | 12/94              | ExclusiveLock       | t       |             | gsql             | 140110481323776 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:19:37.715447 | active              |                 0 | EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1'; transactionid | cn_5002      | postgres | tyx_1   |         |         |          |      |       |            | 10266         | 9/298              | ExclusiveLock       | t       | ::1/128     | cn_5001          | 140110672164608 | 2020-12-25 17:18:40.478704 | 2020-12-25 17:18:40.479682 | idle in transaction |                 0 | TRUNCATE t1; relation      | cn_5002      | postgres | tyx_1   | public  | t2      |          |      |       |            |               | 12/94              | AccessExclusiveLock | t       |             | gsql             | 140110481323776 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:19:37.715447 | active              |                 0 | EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1'; virtualxid    | dn_6001_6002 | postgres | tyx_1   |         |         |          |      |       | 17/433     |               | 17/433             | ExclusiveLock       | t       | ::1/128     | cn_5001          | 140552375822080 | 2020-12-25 17:18:40.478704 | 2020-12-25 17:18:50.513948 | idle in transaction |                 0 | TRUNCATE t1; virtualxid    | dn_6001_6002 | postgres | tyx_1   |         |         |          |      |       | 23/692     |               | 23/692             | ExclusiveLock       | t       | ::1/128     | cn_5002          | 140552359040768 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:18:56.830053 | idle in transaction |                 0 | TRUNCATE t2; virtualxid    | dn_6001_6002 | postgres | tyx_1   |         |         |          |      |       | 2/1607     |               | 2/1607             | ExclusiveLock       | t       |             | workload         | 140552945264384 |                            | 2020-12-25 16:53:35.041283 | active              |                 0 | WLM fetch collect info from data nodes transactionid | dn_6001_6002 | postgres | tyx_1   |         |         |          |      |       |            | 10266         | 17/433             | ExclusiveLock       | t       | ::1/128     | cn_5001          | 140552375822080 | 2020-12-25 17:18:40.478704 | 2020-12-25 17:18:50.513948 | idle in transaction |                 0 | TRUNCATE t1; relation      | dn_6001_6002 | postgres | tyx_1   |         |         |          |      |       |            |               | 23/692             | AccessExclusiveLock | t       | ::1/128     | cn_5002          | 140552359040768 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:18:56.830053 | idle in transaction |                 0 | TRUNCATE t2; relation      | dn_6001_6002 | postgres | tyx_1   |         |         |          |      |       |            |               | 17/433             | AccessExclusiveLock | t       | ::1/128     | cn_5001          | 140552375822080 | 2020-12-25 17:18:40.478704 | 2020-12-25 17:18:50.513948 | idle in transaction |                 0 | TRUNCATE t1; relation      | dn_6001_6002 | postgres | tyx_1   | public  | t2      |          |      |       |            |               | 23/692             | ShareLock           | t       | ::1/128     | cn_5002          | 140552359040768 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:18:56.830053 | idle in transaction |                 0 | TRUNCATE t2; relation      | dn_6001_6002 | postgres | tyx_1   | public  | t2      |          |      |       |            |               | 23/692             | AccessExclusiveLock | t       | ::1/128     | cn_5002          | 140552359040768 | 2020-12-25 17:18:54.238933 | 2020-12-25 17:18:56.830053 | idle in transaction |                 0 | TRUNCATE t2;省略若干行(55 rows)构建等待关系收集到各节点的锁信息之后,就可以开始构建等待关系了。事务 A 等待事务 B,需要满足 3 个条件:1. 两个事务加锁的资源相同(同一个表、同一个分区、同一个页面或同一个元组等)。特别注意,如果事务 A 对 DN1 的 t1 表的加锁,事务 B 对 DN2 的 t1 表的加锁,则我们认为它们加锁的资源不同,只有同一节点上的同一资源才被认为是相同的资源。2. 事务 B 已经持有锁,而事务 A 还未持有锁。3. 事务 A 和事务 B 申请的锁的级别互斥。通过对上一步收集到的锁信息进行处理,就可以构建出事务的等待关系。执行附件中的示例代码 pgxc_locks_wait.sql,就可以获得等待关系: locktype | nodename | datname  | acquire_lock_pid |  hold_lock_pid  |                           acquire_lock_event                            |                    hold_lock_event----------+----------+----------+------------------+-----------------+-------------------------------------------------------------------------+-------------------------------------------------------- relation | cn_5001  | postgres |  140508814374656 | 140508792350464 | usename           : tyx_1                                              +| usename           : tyx_1                             +          |          |          |                  |                 | nspname           : public                                             +| nspname           : public                            +          |          |          |                  |                 | relname           : t2                                                 +| relname           : t2                                +          |          |          |                  |                 | partname          :                                                    +| partname          :                                   +          |          |          |                  |                 | page              :                                                    +| page              :                                   +          |          |          |                  |                 | tuple             :                                                    +| tuple             :                                   +          |          |          |                  |                 | virtualxid        :                                                    +| virtualxid        :                                   +          |          |          |                  |                 | transactionid     :                                                    +| transactionid     :                                   +          |          |          |                  |                 | virtualtransaction: 11/13                                              +| virtualtransaction: 12/1323                           +          |          |          |                  |                 | mode              : AccessShareLock                                    +| mode              : AccessExclusiveLock               +          |          |          |                  |                 | client_addr       :                                                    +| client_addr       : ::1/128                           +          |          |          |                  |                 | application_name  : gsql                                               +| application_name  : cn_5002                           +          |          |          |                  |                 | xact_start        : 2020-12-25 17:18:40.478704                         +| xact_start        : 2020-12-25 17:18:54.238933        +          |          |          |                  |                 | query_start       : 2020-12-25 17:19:23.0923                           +| query_start       : 2020-12-25 17:18:54.239319        +          |          |          |                  |                 | state             : active                                             +| state             : idle in transaction               +          |          |          |                  |                 | query_id          : 0                                                  +| query_id          : 0                                 +          |          |          |                  |                 | query             : EXECUTE DIRECT ON(dn_6001_6002) 'SELECT * FROM t2';+| query             : TRUNCATE t2;                      +          |          |          |                  |                 | ------------------------------------------------------                  | ------------------------------------------------------ relation | cn_5002  | postgres |  140110481323776 | 140110672164608 | usename           : tyx_1                                              +| usename           : tyx_1                             +          |          |          |                  |                 | nspname           : public                                             +| nspname           : public                            +          |          |          |                  |                 | relname           : t1                                                 +| relname           : t1                                +          |          |          |                  |                 | partname          :                                                    +| partname          :                                   +          |          |          |                  |                 | page              :                                                    +| page              :                                   +          |          |          |                  |                 | tuple             :                                                    +| tuple             :                                   +          |          |          |                  |                 | virtualxid        :                                                    +| virtualxid        :                                   +          |          |          |                  |                 | transactionid     :                                                    +| transactionid     :                                   +          |          |          |                  |                 | virtualtransaction: 12/94                                              +| virtualtransaction: 9/298                             +          |          |          |                  |                 | mode              : AccessShareLock                                    +| mode              : AccessExclusiveLock               +          |          |          |                  |                 | client_addr       :                                                    +| client_addr       : ::1/128                           +          |          |          |                  |                 | application_name  : gsql                                               +| application_name  : cn_5001                           +          |          |          |                  |                 | xact_start        : 2020-12-25 17:18:54.238933                         +| xact_start        : 2020-12-25 17:18:40.478704        +          |          |          |                  |                 | query_start       : 2020-12-25 17:19:37.715447                         +| query_start       : 2020-12-25 17:18:40.479682        +          |          |          |                  |                 | state             : active                                             +| state             : idle in transaction               +          |          |          |                  |                 | query_id          : 0                                                  +| query_id          : 0                                 +          |          |          |                  |                 | query             : EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1';+| query             : TRUNCATE t1;                      +          |          |          |                  |                 | ------------------------------------------------------                  | ------------------------------------------------------(2 rows)等待关系判环构建出事务的等待关系之后,就可以通过检查等待关系是否成环,来判断当前是否有分布式死锁。一般情况下,等待关系不会太多,通过观察就可以判断出当前有无分布式死锁。通过观察上一节中构建的等待信息,可以很容易地判断出事务 transaction1 和 transaction2 发生了循环等待,即产生了死锁。消除死锁上一步最终可能会找到等待关系中的一个或多个环,对于每个环,需要中止环中的一个事务,才能消除死锁。至于应该选择环中的哪个事务进行中止,需要我们从事务的重要性、已执行时间等多方面进行考虑,最终选择一个对业务影响最小的事务进行中止。总结通过 SQL 语句,我们可以很方便地处理分布式死锁。当我们在实际业务中遇到数据库系统 hang 住的问题时,可以借助本文提供的方法,检查 hang 问题是否是分布式死锁引起的,如果问题确实是由分布式死锁引起的,还可以通过中止某个陷入死锁的事务,来快速恢复业务。原文链接:https://bbs.huaweicloud.com/blogs/228840【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [存储] GaussDB(DWS)中两阶段事务的故障与恢复
    GaussDB(DWS) 是 share nothing 架构,使用分布式事务解决数据的一致性问题。当前 GaussDB(DWS) 使用的是两阶段提交(2PC)协议。2PC 协议有两类节点:协调者和参与者。一个事务会涉及一个协调者和多个参与者。当协调者或者参与者出现故障或者节点间出现网络问题时,2PC 事务就面临着失败或者残留的问题。在 GaussDB(DWS) 中,发起事务的 CN 节点就是协调者,其他参与此事务的 CN 或者 DN 节点就是参与者。1.1. 2PC 事务失败/残留的原因1.1.1. 2PC 事务的正常提交流程首先看一下 2PC 事务的正常提交流程,一般情况下,对于一个事务,至少要经过一个 CN(执行 CN )、一个 DN 和 GTM。如果涉及本地,先在本地进行 PREPARE;在远端其他节点进行 PREPARE。如果任一节点失败,则报告错误并进行 ABORT 操作;到这步时,所有涉及的节点都已经 PREPARE 了,可以进行 COMMIT 了:首先通知 GTM 当前事务已经 PREPARED,并提供一个节点列表给GTM;先在本地 COMMIT PREPARED,然后在其他远端节点 COMMIT;返回并做提交动作的收尾工作1.1.2. 故障对于上述流程,在任意执行路径上出错,都可能导致整个分布式事务的状态无法达到终点,最终当前事务整体提交失败。如果事务不能完整结束,那么它所占有的资源就会一直无法释放1.1.3. 故障处理的总体原则当故障发生后,通过全局回滚或者是由 gs_clean 工具进行残留事务清理,以保证事务完整结束。1.1.4. 故障场景在事务运行过程中,或者 prepare 阶段,对于 CN、DN、GTM 实例本身或者网络出现故障,事务都要进行回滚,根据实际情况,执行 CN 没问题的话,CN 提交回滚操作;否则需要由 gs_clean 工具进行清理。在 commit prepared 阶段,CN 向其他 CN 和 DN 发送 commit prepared 命令,并收取返回信息,这时如果实例发生了故障,那么事务会残留,就需要等待 gs_clean 工具清理了。1.2. gs_clean上面的故障情况中,对于执行 CN 不能自动进行回滚的的场景,就需要 gs_clean 工具来协助进行清理了。1.2.1. gs_clean 是干什么的gs_clean 工具是用于清理 GaussDB(DWS) 集群中残留的两阶段事务的组件。1.2.2. 为什么需要 gs_clean由于 GaussDB(DWS) 集群使用多个工作节点一起来支持分布式事务,单个组件的故障会导致分布式事务(2PC)的全局状态产生异常。在某些情况下,异常的事务由于无法判断后续状态进而无法继续下去,这时就需要一个第三方的组件来判断事务状态并将事务圆满的结束。1.2.3. gs_clean 在哪里gs_clean 二进制文件跟随内核包一起部署在 $GAUSSHOME/bin 目录下。1.2.4. 谁来调用 gs_clean每个 CN 中有一个叫做 TwoPhaseCleanerMain 的辅助线程线程,所有的 gs_clean 调用都是由这个线程自动完成的。一般情况下,不需要人工调用 gs_clean。1.2.5. 什么时候调用 gs_clean在 CN 正常运行过程中,每隔 5mins 会调一次 gs_clean 命令,对集群中所有的数据库中的两阶段残留事务进行扫描和清理;如果是进程刚启动,或者上次 gs_clean 调用失败,则 60s 后会再次调用;sync 等待时,如果等待超时,会给这个线程发消息线程调用 gs_clean;如果已经有 gs_clean 进程启动,则不会再调用;1.2.6. gs_clean的结果与日志gs_clean 的所有信息都保存在自己的日志文件中,日志文件路径为:$GAUSSLOG/bin/gs_clean/1.2.7. gs_clean 的主要工作流程连接 CN,做一些前期的信息收集和准备工作:获取要清理的 database 列表连接 CN,设置为维护模式获取自己的 node name 和 所有的 node list扫描两阶段残留信息:去各个节点上执行视图 pg_prepared_xacts获取 prepared 的事务信息,把结果和事务状态记录在链表里遍历链表,查看是否有要进行恢复的 2PC 事务针对每个处于 prepared 阶段的事务,去其他所有节点上查找对应事务是否已经提交,把结果也更新到链表中收集了所有需要的信息后,针对每个 database 中的每一个事务,根据规则判断应该进行提交、回滚还是继续等待,如果需要提交或回滚,那么直接向所有相关节点发起 commit/rollback prepared 动作1.2.8. 残留事务的处理规则如果有一个节点处于 committed 状态,则标记为提交,并最终提交该事务;如果有一个节点处于 aborted 状态,则标记为回滚,并最终回滚该事务;如果所有节点都处于 prepared 状态,则可选择回滚或者提交(参数),默认是回滚;如果有节点连不上,则不提交也不回滚。1.2.9. 实际运行过程中的一些事情GUC 参数 gs_clean_timeout 可以用来控制 CN 调用 gs_clean 的周期间隔。默认为 5min。当 CN 上进行事务 sync 等待时,如果超过 transaction_sync_naptime 参数(默认5s),则会触发 gs_clean。CN 自动触发的 gs_clean 命令为: gs_clean -a -p PORT -v -r        1. -a:清理所有数据库        2. -p:CN 端口        3. -v:打印详细信息,包括数据库信息,残留事务信息等        4. -r:将处于 PREPARED 状态的事务进行回滚        5. 其他 gs_clean 参数可以参考 gs_clean --help原文链接:https://bbs.huaweicloud.com/blogs/201221【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [SQL] 分布式数据存储倾斜快速检测
    【摘要】 本文主要分享快速、准确识别数据存储倾斜的方法。前言数据存储倾斜(即图中1-4被占用存储资源不均衡)是Shared nothing分布式架构下的重要难题,它破坏了MPP架构中各个节点对等的要求,导致倾斜节点所需存储及计算资源都远大于其他节点,进而导致性能下降(木桶效应)、full disk或oom等严重问题。技术背景目前各类分布式数据库厂商都有提供存储倾斜的检测工具,常用方法主要有计算表的COUNT,计算表的SIZE和通过统计信息计算这三种,下面以在GaussDB(DWS)分布式数据库产品为例,分别介绍这三种方式的优劣:方法一:通过表的COUNT计算倾斜方案:例如使用table_skewness函数,其内部通过统计表在各节点的COUNT数实现postgres=# select dnname,num from table_skewness('mytable') order by dnname;   dnname   | num---------------+------  datanode1  | 4800  datanode2  | 5216  datanode3  | 5792  datanode4  | 5568  datanode5  | 5152  datanode6  | 5472(6 rows)优点:简单粗暴,适用表数据量小且UPDATE/DELETE少的表;缺点:数据量大的场景计算表的COUNT比较耗时;脏数据占存储和SCAN消耗但不会统计;方法二:通过表的SIZE计算倾斜(推荐)方案:例如使用table_distribution函数,其内部通过统计表在各节点的SIZE大小实现postgres=# select nodename,dnsize from table_distribution('public','mytable') order by nodename;  nodename  | dnsize-------------+--------  datanode1 | 221184  datanode2 | 229376  datanode3 | 253952  datanode4 | 253952  datanode5 | 229376  datanode6 | 253952(6rows)优点:实时性好;准确度高;相比计算COUNT速度快;缺点:表对应数据文件多的场景性能会受影响,当前实测100+节点场景影响在可接受范围方法三:通过统计信息计算倾斜方案:使用pg_class中reltuples/relpages以及统计信息来计算倾斜CREATE OR REPLACE FUNCTION PUBLIC.pgxc_analyzed_tuples(     OUT schemaname text,     OUT tablename text,     OUT dn_name text,     OUT tuples real)RETURNS SETOF recordAS $$DECLARE     datanode_rd     record;     fetch_tuples    record;     fetch_dn        text;     fetch_tuple_str text;BEGIN     fetch_dn := 'SELECT node_name FROM pg_catalog.pgxc_node WHERE node_type=''D'' order by node_name';     FOR datanode_rd IN EXECUTE(fetch_dn) LOOP         dn_name         :=  datanode_rd.node_name;         fetch_tuple_str := 'EXECUTE DIRECT ON (' || dn_name || ') ''SELECT n.nspname, c.relname, c.reltuples                   FROM pg_catalog.pg_class c                   INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace                    where c.oid >16384 AND c.relkind = ''''r''''                     and n.nspname <> ''''cstore'''' and n.nspname <> ''''pmk''''                     and n.nspname <> ''''pg_catalog''''''';         FOR fetch_tuples IN EXECUTE(fetch_tuple_str) LOOP             tuples    := fetch_tuples.reltuples;             schemaname := fetch_tuples.nspname;             tablename  := fetch_tuples.relname;             return next;         END LOOP;     RAISE INFO 'Finished fetching stats info from DataNode % at %',dn_name, clock_timestamp();     END LOOP;     return;END; $$LANGUAGE 'plpgsql'ROWS 1000000;postgres=# select dn_name,tuples from public.pgxc_analyzed_tuples() where tablename='mytable';   dn_name | tuples-------------+--------  datanode1 | 4800  datanode2 | 5216  datanode3 | 5792  datanode4 | 5568  datanode5 | 5152  datanode6 | 5472(6 rows)优点:计算过程不需要实时SCAN,只需要通过已有统计信息来计算,速度最快。缺点:强依赖实时ANALYZE统计信息来保证实时性;不包含实际占用存储空间和SCAN 消耗的脏数据统计,准确度不如方法二。小结以上三种方法主要针对单个表的倾斜查询,各有优劣,这里比较推荐准确度最高速度居中的方法二,并基于此方法实现了系统视图PGXC_GET_TABLE_SKEWNESS用于查询库内所有表的存储分布情况,例:postgres=# select * from PGXC_GET_TABLE_SKEWNESS;schemaname | tablename | totalsize | avgsize  | maxratio | minratio | skewsize | skewratio | skewstddev------------+------------+-------------+------------+------------+------------+-----------+------------+------------  public  | orders  | 705413120 | 117568853 |  .167  |  .166  | 278528  |  0.000  |  95628  public  | mytable  | 1441792  | 240299  |  .176  |  .153  | 32768  |  .023  |  15253  public  | customer | 131579904 | 21929984 |  .167  |  .166  | 131072  |  .001  |  46050  public  | part   | 101646336 | 16941056 |  .167  |  .166  | 114688  |  .001  |  38772  public  | supplier | 8552448  | 1425408  |  .168  |  .166  | 16384  |  .002  |  8974  public  | lineitem | 3351937024 | 558656171 |  .167  |  .166  | 1302528 |  0.000  |  516984  public  | partsupp | 461922304 | 76987051 |  .167  |  .166  | 401408  |  .001  |  148130(7 rows)后面将语句基于table_distribution函数及PGXC_GET_TABLE_SKEWNESS视图,介绍如何在真实业务场景中及早、快速定位到存储倾斜的表。实战场景从早发现、快定位、勤检查三个角度,介绍如何在实际业务场景中最大程度避免数据存储倾斜带来的影响。早发现:数据导入场景即时检测当前我们支持在数据导入过程对DN导入行数进行统计,导入完成后计算倾斜率,超过一定阈值时,立即进行告警。倾斜率通过( DN导入行数最大值-DN导入行数最小值) /导入总行数计算,方法如下:1、开启即时检测的参数table_skewness_warning_rows:表倾斜告警最小行数,取值范围0~ INT_MAX,默认值100000,表示当导入总行数超过该值与导入DN数之积时,才可能触发告警,避免小数据量导入的场景进行无意义的告警。table_skewness_warning_threshold:表倾斜告警阈值,取值范围0~1.0,默认值为0,表示当DN返回行数的最小值和最大值的比例小于指定的倾斜告警阈值时,进行告警。2、执行导入(INSERT或COPY)当导入数据出现倾斜,执行SQL和日志中会发出告警,告警信息包括表名、最小行数、最大行数、总行数、平均行数、倾斜率,以及提示信息(检查数据分布或者修改参数)。WARNING: Skewness occurs, table name: xxx, min value: xxx, max value: xxx, sum value: xxx, avg value: xxx, skew ratio: xxxHINT: Please check data distribution or modify warning threshold快定位:磁盘满场景快速定位倾斜表出现磁盘满场景,在表数量非常多的情况下,全量排查哪些表倾斜非常耗时,我们支持使用如下方式快速定位倾斜表:1、查询近期发生过数据变更的表通过pg_stat_get_last_data_changed_time(oid)函数查询出近期发生过数据变更的表,基于表的最后修改时间只在进行IUD操作的CN记录,要查询库内1天(间隔可在函数中调整)内被修改的所有表,可以使用如下封装函数:CREATE OR REPLACE FUNCTION get_last_changed_table(OUT schemaname text, OUT relname text) RETURNS setof recordAS $$DECLARE     row_data record;     row_name record;     query_str text;     query_str_nodes text;BEGIN     query_str_nodes := 'SELECT node_name FROM pgxc_node where node_type = ''C''';     FOR row_name IN EXECUTE(query_str_nodes) LOOP        query_str := 'EXECUTE DIRECT ON (' || row_name.node_name || ') ''SELECT b.nspname,a.relname               FROM pg_class a INNER JOIN pg_namespace b on a.relnamespace = b.oid where               pg_stat_get_last_data_changed_time(a.oid)                 BETWEEN current_timestamp - 1 AND current_timestamp;''';       FOR row_data IN EXECUTE(query_str) LOOP         schemaname = row_data.nspname;         relname = row_data.relname;         return next;       END LOOP;     END LOOP;     return;END; $$LANGUAGE plpgsql;2、查看近期数据变更的表的分布情况postgres=# SELECT table_distribution(schemaname,relname) FROM get_last_changed_table() limit 6;         table_distribution----------------------------------- (public,mytable,datanode1,221184) (public,mytable,datanode2,229376) (public,mytable,datanode3,253952) (public,mytable,datanode4,253952) (public,mytable,datanode5,229376) (public,mytable,datanode6,253952)(6 rows)勤检查:常规数据倾斜巡检1、在库中表个数比较少(<1W)场景直接使用PGXC_GET_TABLE_SKEWNESS视图来查询当前库内所有表的数据倾斜情况。2、在库中表个数非常多(>1W)场景PGXC_GET_TABLE_SKEWNESS涉及全库查并计算非常全面的倾斜字段,所以可能会花费比较长的时间(小时级),建议参考PGXC_GET_TABLE_SKEWNESS视图定义,直接使用table_distribution()函数自定义输出,减少输出列进行计算优化,例如:postgres=# SELECT schemaname,tablename,max(dnsize) AS maxsize, min(dnsize) AS minsize postgres-# FROM pg_catalog.pg_class c postgres-# INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace postgres-# INNER JOIN pg_catalog.table_distribution() s ON s.schemaname = n.nspname AND s.tablename =c.relname postgres-# INNER JOIN pg_catalog.pgxc_class x ON c.oid = x.pcrelid AND x.pclocatortype = 'H'postgres-# GROUP BY schemaname,tablename;schemaname | tablename | maxsize | minsize------------+-------------+-----------+-----------  public  | orders   | 117686272| 117407744  public  | mytable  | 253952  | 221184  public  | customer  | 21979136 | 21848064  public  | part    | 16982016 | 16867328  public  | supplier  | 1433600 | 1417216  public  | lineitem  | 559284224| 557981696  public  | partsupp  | 77094912 | 76693504(7 rows)总结分布式框架下的倾斜是个大课题,本文主要针对存储倾斜(不包含计算倾斜)重点分享我们在业务中如何尽快发现倾斜、定位倾斜,希望能给大家提供一些思路和帮助。原文链接:https://bbs.huaweicloud.com/blogs/183585【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [SQL] GaussDB(DWS)的stream执行机制
    GaussDB(DWS)架构简介    近期刚刚接触GaussDB(DWS),它是一个shared nothing的分布式架构,下图是一个简化的GaussDB(DWS)架构图。    其中各组件的功能如下:CN(Coordinator Node)为对外服务和协调节点,负责接受客户端连接以及对用户SQL命令解析下发,并收集DN节点执行的结果进行汇总,将结果展现给客户端。DN(Datanode)为内部数据节点,承载内部数据存储及计算单元的功能。GTM(Global Transaction Manager)负责集群全局事务控制,其与Datanode均有本地主备双机功能。分布式执行框架    对应于分布式架构,GaussDB(DWS)提供了分布式执行框架,这也是GaussDB(DWS)中最核心的技术,旨在充分利用DN的资源,尽量将计算下推到DN进行,避免CN成为瓶颈,以提升查询效率和系统扩展性。    分布式执行框架的技术特点如下:CN负责查询请求的解析、基于代价进行优化以及向DN进行任务下发,并收集DN节点执行的结果进行汇总DN上运行执行计划进程,基于本节点存储的数据执行任务执行过程中每个算子都是接收下级算子的数据输入,并向上级算子输出数据。是一个生产者—消费者的流水线工作模型  针对分布式框架,GaussDB(DWS)增加了支撑分布式计划的Stream算子。Stream算子有三种类型:Gather Stream(N:1):每个源节点都将其数据发送给目标节点            Redistribute Stream(N:N):每个源节点将其数据根据连接条件计算Hash值,根据重新计算的Hash值进行分布,发给对应的目标节点    Broadcast Stream(1:N):有一个源节点将其数据发给N个目标节点      下面通过tpch中的Q1和Q2为例,使用explain查看这两个SQL的执行计划来认识一下这几个算子。查看执行计划查看与Gather Stream和Redistribute Stream算子相关的执行计划  以tpch的Q1为例说明,Q1的SQL语句如下SET explain_perf_mode=pretty; --以Oracle-like风格打印执行计划,便于查看EXPLAINSELECT          l_returnflag,          l_linestatus,          SUM(l_quantity) as sum_qty,          SUM (l_extendedprice) as sum_base_price,          SUM (l_extendedprice * (1 - l_discount)) as sum_disc_price,          SUM (l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,          AVG(l_quantity) as avg_qty,          AVG (l_extendedprice) as avg_price,          AVG (l_discount) as avg_disc,          COUNT(*) as count_orderFROM          row_engine.lineitemWHERE          l_shipdate <= DATE '1998-12-01' - INTERVAL '3 day'GROUP BY          l_returnflag,          l_linestatusORDER BY          l_returnflag,          l_linestatus;      执行结果如下: id |                 operation                  | E-rows  | E-memory | E-width |  E-costs   ----+--------------------------------------------+---------+----------+---------+-----------   1 | ->  Streaming (type: GATHER)               |       5 |          |     257 | 146811.70   2 |    ->  Sort                                |       5 | 16MB     |     257 | 146811.20   3 |       ->  HashAggregate                    |       6 | 16MB     |     257 | 146811.19   4 |          ->  Streaming(type: REDISTRIBUTE) |      18 | 2MB      |     257 | 146810.87   5 |             ->  HashAggregate              |      18 | 16MB     |     257 | 146809.83   6 |                ->  Seq Scan on lineitem    | 6001622 | 1MB      |      25 | 66788.09(6 rows)                   Predicate Information (identified by plan id)                    ------------------------------------------------------------------------------------    3 --HashAggregate          Skew Agg Optimized by Statistic   6 --Seq Scan on lineitem          Filter: (l_shipdate <= '1998-11-28 00:00:00'::timestamp without time zone)(4 rows)    ====== Query Summary =====    ---------------------------------  System available mem: 9252864KB  Query Max mem: 9473228KB  Query estimated mem: 3123KB(3 rows)    为了便于说明,我在执行计划的每一行的行首加了一个序号。下面对这个计划进行一下说明:从第2行的Sort算子开始直到第6行,是CN下发到在DN上执行的部分;第1行是在CN上执行执行顺序首先从id为6的行开始,对lineitem表执行seqscanid为5的行,对下层扫描得到的数据根据GROUP BY分组键执行hashaggregate操作id为4的行,是一个Redistribute Stream算子,它将在DN上的local数据执行agg后结果,重分布给其他DNid为3的行,各DN收到其他DN上的数据,重新做aggid为2的行,对下层的agg结果进行排序id为1的行,是一个Gather Stream算子,CN节点收到DN返回的结果,汇集后将最终结果展示给客户端    在这个执行计划中,我们看到了两个和Stream算子相关的节点:Gather Stream,用于CN收集DN的结果Redistribute Stream,用于将DN上的数据重分布给其他DN做HashAgg。    这里有两个问题:Q1查询是一个单表查询,为什么需要在DN之间重分布数据呢?tpch的Q1是对lineitem表的单表查询,进行分组聚集计算。因为lineitem表是按照l_orderkey列作为分布列,将数据分布到各DN的。而聚集操作分组键是l_returnflag和l_linestatus,而不 是分布键l_orderkey,所以,属于同一个分组的数据分布在不同的DN上,这就需要各DN重新按照分组键作为分布键,将数据分发给其他DN,使得各DN上拥有相同分组键的数据完成聚集操作。从以上的计划中,可以看到在DN上先做了hashagg,再又重分发给其他DN,再次做hashagg,如下图中的右侧。为什么不是先把数据重分布发给其他DN后,做一次hashagg即可,如下图的左侧       这两个计划的区别在于:如果scan后数据量非常大,而聚集后数据量比较小的情况,就适合用第二个计划,可以减少DN之间的数据流动,降低网络开销。从上面Q1的执行计划中,可以明显看到,Seq Scan on lineitem对应的E-rows为6001622,即seqscan后的数据估计有6001622行,重分布之前HashAggregate的的结果数据估计只有18行,数据量大大减少。根据代价估算,重分布前做一次hashagg的代价,比直接重分布scan的结果的代价要小很多,故选择了重分布前先做一次hashagg。查看与Gather Stream和Broadcast Stream算子相关的执行计划    以tpch的Q2为例说明,Q2的SQL语句如下SET explain_perf_mode=pretty; --以Oracle-like风格打印执行计划,便于查看EXPLAIN     SELECT s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment    FROM row_engine.part, row_engine.supplier, row_engine.partsupp, row_engine.nation, row_engine.region    WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND p_size = 15 AND p_type LIKE 'SMALL%' AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'EUROPE ' AND ps_supplycost = ( SELECT MIN(ps_supplycost) FROM row_engine.partsupp, row_engine.supplier, row_engine.nation, row_engine.region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'EUROPE ' )ORDER BY s_acctbal DESC, n_name, s_name, p_partkeyLIMIT 100;   执行结果如下: id |                                            operation                                             | E-rows | E-memory | E-width | E-costs      ----+--------------------------------------------------------------------------------------------------+--------+----------+---------+----------   1 | ->  Limit                                                                                        |      3 |          |     192 | 23979.08   2 |    ->  Streaming (type: GATHER)                                                                  |      3 |          |     192 | 23979.08   3 |       ->  Limit                                                                                  |      3 | 1MB      |     192 | 23978.89   4 |          ->  Sort                                                                                |      3 | 16MB     |     192 | 23978.89   5 |             ->  Nested Loop (6,10)                                                               |      3 | 1MB      |     192 | 23978.88   6 |                ->  Nested Loop (7,9)                                                             |      5 | 1MB      |      30 | 2.48   7 |                   ->  Streaming(type: BROADCAST)                                                 |      3 | 2MB      |       4 | 1.30   8 |                      ->  Seq Scan on region                                                      |      1 | 1MB      |       4 | 1.02   9 |                   ->  Seq Scan on nation                                                         |     25 | 1MB      |      34 | 1.08   10 |                ->  Materialize                                                                   |      3 | 16MB     |     170 | 23976.35   11 |                   ->  Streaming(type: REDISTRIBUTE)                                              |      3 | 2MB      |     170 | 23976.34   12 |                      ->  Nested Loop (13,14)                                                     |      3 | 1MB      |     170 | 23976.14   13 |                         ->  Seq Scan on supplier                                                 |  10000 | 1MB      |     144 | 108.33   14 |                         ->  Materialize                                                          |      3 | 16MB     |      34 | 23767.83   15 |                            ->  Streaming(type: REDISTRIBUTE)                                     |      3 | 2MB      |      34 | 23767.82   16 |                               ->  Hash Join (17,21)                                              |      3 | 1MB      |      34 | 23767.71   17 |                                  ->  Hash Join (18,19)                                           |   2538 | 1MB      |      44 | 11916.85   18 |                                     ->  Seq Scan on partsupp                                     | 800000 | 1MB      |      14 | 8532.67   19 |                                     ->  Hash                                                     |    651 | 16MB     |      30 | 2373.01   20 |                                        ->  Seq Scan on part                                      |    651 | 1MB      |      30 | 2373.01   21 |                                  ->  Hash                                                        |    507 | 16MB     |      36 | 11841.97   22 |                                     ->  Subquery Scan on subquery                                |    507 | 1MB      |      36 | 11841.97   23 |                                        ->  HashAggregate                                         |    507 | 16MB     |      42 | 11840.28   24 |                                           ->  Streaming(type: REDISTRIBUTE)                      |    507 | 2MB      |      10 | 11837.75   25 |                                              ->  Hash Join (26,31)                               |    507 | 1MB      |      10 | 11833.54   26 |                                                 ->  Streaming(type: REDISTRIBUTE)                |   2538 | 2MB      |      14 | 11687.60   27 |                                                    ->  Hash Semi Join (28, 29)                   |   2538 | 1MB      |      14 | 11617.80   28 |                                                       ->  Seq Scan on partsupp                   | 800000 | 1MB      |      14 | 8532.67   29 |                                                       ->  Hash                                   |    651 | 16MB     |       4 | 2373.01   30 |                                                          ->  Seq Scan on part                    |    651 | 1MB      |       4 | 2373.01   31 |                                                 ->  Hash                                         |   2001 | 16MB     |       4 | 126.89   32 |                                                    ->  Hash Join (33,34)                         |   2000 | 1MB      |       4 | 126.89   33 |                                                       ->  Seq Scan on supplier                   |  10000 | 1MB      |       8 | 108.33   34 |                                                       ->  Hash                                   |     15 | 16MB     |       4 | 2.97   35 |                                                          ->  Streaming(type: BROADCAST)          |     15 | 2MB      |       4 | 2.97   36 |                                                             ->  Hash Join (37,38)                |      5 | 1MB      |       4 | 2.43   37 |                                                                ->  Seq Scan on nation            |     25 | 1MB      |       8 | 1.08   38 |                                                                ->  Hash                          |      3 | 16MB     |       4 | 1.30   39 |                                                                   ->  Streaming(type: BROADCAST) |      3 | 2MB      |       4 | 1.30   40 |                                                                      ->  Seq Scan on region      |      1 | 1MB      |       4 | 1.02(40 rows)    在这个计划中我们看到对region表的扫描结果使用Broadcast方式广播给其他DN节点,然后在各DN上和nation表做Nestloop连接。    那么什么时候用Broadcast Stream,什么时候用Redistribute Stream呢?    一般来说,Broadcast Stream比较适用于表要广播的表数据量比较小的情况,从上面的计划可以看到Streaming(type: BROADCAST)对应的E-rows 为3,即要广播的数据仅有3条。但是对于小表作为外连接的NonNullable-side时,是不适合用Broadcast Stream的。因为小表全表广播到所有DN后,和Nullable-side的表的数据进行外连接,因为Nullable-side的表在DN上存储的只是集群中该表的部分数据,而NonNullable-side表是所有数据,导致外连接的结果中Nullable-side的NULL行数增加。DN的结果再发给CN进行汇总后,会使整个结果的数据中结果增多。原文链接:https://bbs.huaweicloud.com/blogs/176347【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [行业资讯] ipfs GJ认可吗?filecoin是不是合法的项目
    IPFS被写入广电总局区块链技术应用,存储行业发展正当时。目前,全球主要国家都在加快布局区块链技术发展,并将区块链提升到核心技术自主创新重要突破口的战略高度。为积极推动区块链技术在广播电视和网络视听领域创新应用,近日,广播电视总局组织编制了区块链技术应用系列白皮书。IPFS被写入广电总局区块链技术应用 分布式存储行业发展正当时其中,星际文件系统IPFS作为对标HTTP的下一代互联网底层通信协议位居前列,“P2P”点对点系统、"CND”内容分发网络、“DAPP”分布式应用等也被提及,这些白皮书上的相关名词,或许在不久之后,将出现在我们所听到的广播中~IPFS被写入广电总局区块链技术应用 分布式存储行业发展正当时广播电视总局亦简称广电总局,是广播电视工作正部级直属机构,主要负责贯彻宣传方针政策,拟订广播电视管理的政策措施并督促落实,统筹规划和指导协调广播电视事业、产业发展等工作。此次广电总局发布区块链技术应用系列白皮书,就犹如区块链被纳入新基建般,对于区块链发展本身、对于区块链从业者甚至对于时代的发展而言,都具有重要意义。事实上,区块链技术和应用的发展需要云计算、大数据、5G、物联网等新一代信息技术作为基础设施支撑,同时,区块链技术和应用发展对推动新一代信息技术产业发展具有重要的促进作用。这其实就是这个时代最好的映射,各大顶级技术之间,各有长短、互相需要、强强联合以推动区块链3.0和web3.0的到来。在这样的一个时代,数据变得愈发庞大并且珍贵,甄别并且存储有价值的数据成为新的时代难题,而也成为了IPFS&Filecoin的愿景。无论是IPFS还是Filscoin,在其网络上,他的每一个节点都可以链接成百上千的节点,于此同时,已经链接的节点又可以通过成百上千的节点链接出去,从而共同组成一个全球化的超大网络。这是一个没有存储容量上限的网络,也是一个致力于保障数据安全、降低数据存储成本的网络。时代日新月异、世界高速发展,IPFS&Filecoin赋能分布式存储行业发展正当时!
  • openGauss 【创建表】报错目前不支持分布式功能
    openGauss版本为1.0.0 , 单机部署。创建表时,报错ERROR: Un-support feature  Detail: The distributed capability is not supported currently建表语句如下:CREATE  TABLE task (     username character varying(50),     filename character varying(500),     tasktime character varying(50),     status character varying(10) ) WITH (orientation=column, compression=no) DISTRIBUTE BY HASH(username) TO GROUP group_version;是因为单机部署的原因吗? openGauss和DWS 有什么区别吗
  • [其他系列] 【openGauss 1.0.0】【创建表】报错目前不支持分布式功能
    【功能模块】openGauss版本为1.0.0 , 单机部署。创建表时,报错ERROR: Un-support feature  Detail: The distributed capability is not supported currently.【操作步骤&问题现象】建表语句如下:CREATE  TABLE task ( username character varying(50), filename character varying(500), tasktime character varying(50), status character varying(10) ) WITH (orientation=column, compression=no) DISTRIBUTE BY HASH(username) TO GROUP group_version;【截图信息】【日志信息】
  • [系统培训] 【课程回顾】玩转PB级数仓深度调优之依“计”行事
    课程简介:      通过回顾分布式数据库的架构,全方位介绍数据仓库的分布式计划,并对计划的执行方式进行分析,最后通过实践案例进行计划的对比。通过本课程的学习,让您对分布式数据库的计划有更深入的了解,具备初步的依“计”行事的能力,可以根据计划做初步的SQL调优。课程链接: https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXD037+Self-paced/about论坛活动(火热进行中)>>【打卡互动赢大奖】DWS王者挑战赛,携手开启征战之路!参与互动,华为云定制机械键盘、双肩包、无线鼠标、旅行本套装等精美礼品等你来拿哦~扫码关注我哦,我在这里↓↓↓
  • 搭载鸿蒙OS 华为发布智慧屏S系列
    为迈向“全场景”战略,华为正加速其在大屏赛道的迭代。12月21日下午,华为在全屋智能及智慧屏新品发布会上正式对外发布华为智慧屏S系列,这也是华为在智慧屏上的又一条分支产品线。官网信息显示,智慧屏S系列采用鸿鹄芯片,4 核 CPU + 4 核 GPU 架构,可以播放 8K 超高清电影。华为消费者BG总裁余承东在现场演讲中表示,基于鸿蒙系统的底层技术,从S系列开始,智慧屏全品类可以做到十年内不过时,软硬件具备自我更新的能力。“以单模组配件的升级迭代为例,大屏上的摄像头像素、算力可以通过软件方式进行迭代更新。”鸿蒙分布式软总线技术可以打破多个硬件设备物理空间的限制,虚拟成一个个共享资源,这让智慧屏的功能不仅局限于看视频的功能,未来可与更多的华为生态中搭载鸿蒙OS的硬件设备分布式组网,搭配形成“智慧屏 + N”超级设备,从而带动外延设备及全生态能力升级。
  • [交流分享] 【悦识鲲鹏系列 第18期】Kunpeng BoostKit应用使能套件-分布式存储场景文档获取与使用
    Kunpeng BoostKit应用使能套件,围绕大数据、分布式存储、数据库、虚拟化等八大主流场景,开放高性能开源组件、加速软件包和工具/参考实现,使能应用最优性能。本期介绍分布式存储场景下应用使能相关文档资源的获取与使用。软件兼容性查询:cid:link_2鲲鹏BoostKit分布式存储使能套件介绍 在线课程:https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXK047+Self-paced/about?isAuth=0&cfrom=hwc鲲鹏BoostKit分布式存储使能套件 文档聚合:cid:link_1
  • Gartner:2021年影响基础设施和运营的六大趋势
    全球领先的信息技术研究和顾问公司Gartner强调,基础设施和运营(I&O)领导者在未来12至18个月必须开始针对六种趋势做好准备。Gartner研究副总裁Jeffrey Hewitt表示:“新冠疫情迫使IT高管调整他们的运营方式来应对不断增加的居家办公情况和无法预测的IT需求变化。但新冠疫情并非大多数I&O员工继续在家工作的唯一动力。基础设施的发展使得远程I&O团队能够有效支持新的场景、用例和技术。”Hewitt先生指出了影响I&O的最新趋势,并就如何对这些问题做出最佳响应,从而在后疫情时代取得最佳成果提出了自己的建议:趋势一:无处不在的运营Gartner预计即使在疫情之后,仍有48%的员工将居家办公,而疫情前的这一比例为30%。这一转变将迫使IT高管培养企业机构的灵活性和韧性,使员工可以在任何地点工作、让任何地点的客户可以访问服务并管理各种分布式基础设施上的业务服务部署。Hewitt先生的建议是:“就位置灵活性而言,I&O内部的传统结构化流程会让企业机构变得脆弱。通过无处不在的运营,企业机构能够将人员分散到对业务有意义的地点并在那里开始运营。由于企业机构不一定要在特定的地理位置招聘员工,这让企业机构有了更广泛的人才选择空间。”趋势二:最优基础设施Hewitt先生表示:“无处不在的运营之关键在于开发让员工能够在合适的时间和地点开展合适工作的可编程基础设施,而这是最优基础设施的核心。随着基础设施和运营朝集成和运营发展,超融合基础设施或计算存储等各类解决方案必须与最佳用例相匹配。”最优基础设施还将涉及难以衡量并会引发复杂部署的数据中心和边缘基础设施。Hewitt先生建议企业机构从业务角度出发,同时着眼于通过优化成本和工具来构建针对特定基础设施部署的用例。趋势三:运营连续性越来越多的工作需要支持地理位置分散的客户和员工。因此,无论外部因素如何,IT服务都必须保证连续性,这样才能实现自动部署和接触最少的维护。到2025年,60%的企业机构将使用自动化工具部署新的计算资源、减少部署时间和实现更高的敏捷性。Hewitt先生的建议是:“只要能够正确把握这一趋势,企业机构就可以提高效率并且加快工作部署。主要的弊端在于使用支持连续性的新工具或流程(有时还十分复杂)前需要有一个学习的过程。”趋势四:基础设施核心现代化改造为确保企业基础设施同步发展,应将核心运营维护视为一项长期流程,而非一次性项目。企业将需要协调能够最大程度减少遗留设备阻力的本地和异地基础设施。Hewitt先生的建议是:“基础设施核心现代化改造的优点在于可以减少技术债务并为使用敏捷基础设施应对日益增长的数字化业务需求打下基础。企业必须实施包含实际时间表的改造计划,而且该计划应考虑不断变化的技能要求。”趋势五:分布式云另一项主要趋势是通过分配云资源使云变得分散化,并且提供支持这一负担被转移到云服务提供商身上。这一方法将实现位置的灵活性并减少不必要的等待时间。Hewitt先生的建议是:“分布式云市场目前还不成熟,因此成本可能很高,而且模型的部署也十分复杂。但由于大多数云服务平台将在未来四年至少提供一些按需执行的分布式云服务,因此企业机构仍应将其视为云计算未来发展的一部分。”趋势六:关键技能与角色Hewitt先生表示:“随着企业机构适应新的业务环境,它们对I&O技能的要求也将继续发展。具体来说,重点已从基础设施角色转移到集体关键技能。这对归属于特定基础设施团队的传统”地域“思维构成了挑战,同时鼓励了协作。”到2022年,预计I&O领导者将至少为所在的企业机构准备12种高优先级技能。在目前IT人才市场仍是买方市场的情况下,Gartner建议招聘具备这些技能的人才;同时,Gartner也表示I&O领导者应考虑这一趋势将带来的根本性文化变革并制定相应的计划。来源:C114通信网
  • [公告] 华为云容器软件市场份额,中国第一!
    近日,全球权威咨询机构IDC发布《PRC SDC Software Market Overview, 2020H1》报告,报告显示,华为云容器软件市场份额(Container Infrastructure Software Market Size)排名中国第一。华为云在云原生领域深耕多年,一直是技术的引领者、产品的开创者和市场的领导者,今年,华为云又开创性的提出了“云原生 IN 基础设施”的理念,并围绕该理念打造了以应用为中心的云原生基础设施,开启了云原生2.0的时代。目前,华为云原生基础设施打造了云容器引擎、云容器实例、智能边缘平台、多云容器平台等8大核心容器产品,并以此为基础构建了云原生裸金属、云原生高性能计算、云原生混合云、云原生边缘计算四大解决方案,满足企业业务智能升级过程中,对高性能基础设施、分布式业务架构、完善的云原生应用生态的诉求。重定义基础设施,为应用提供更高性能的资源底座支持多元算力,满足不同应用场景的个性化算力需求,基于华为云擎天架构的深度软硬协同能力,为应用提供极致性能的云原生算力、网络和存储资源。新赋能泛在应用,为应用提供更高效的分布式架构 基于多云治理和边云协同,打造高效、高可靠的分布式泛在计算平台,并构建包括容器、裸机、虚机、函数多种资源的统一计算平台,让传统企业应用与云原生应用能更好的协同。再升级应用架构,为应用提供生态完善的创新平台以 “应用”为中心打造标准、开放的企业应用生命周期管理流程,为企业的传统IT应用、中间件应用,以及大数据、AI、边缘等创新应用,提供一键式部署、可感知应用的智能化调度、全方位监控与运维等全生命周期的管理能力,使应用的运行和管理更高效、智能,加速应用创新。华为是全球首批投身云原生产业的厂商之一,于2015年参与云原生计算基金会(CNCF)组建,是CNCF在亚洲的唯一初创成员和首个白金会员。5年来,华为云在云原生领域持续深耕,向CNCF社区贡献核心特性130+,代码贡献和Maintainer席位数均居亚洲第一,并贡献了首个云原生智能边缘项目KubeEdge和云原生批量计算项目Volcano,加速云原生与其它产业的交叉融合,此外,华为云还拥有顶尖开源社区Istio在亚洲唯一的指导委员会席位,华为云在云原生领域的突出贡献已获得各大社区的高度认可。华为云原生产品、解决方案及所开源项目已服务于泛互联网、金融、汽车、制造、能源等十多个行业的数千标杆客户,未来,华为云将秉持“云原生2.0赋能新云原生企业”的理念,以“技术+产业”双轮驱动,让每一家企业都能成为“新云原生企业”,享受云原生的技术红利。
总条数:521 到第 页
上滑加载中