跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

这是您第一次登陆到 developerWorks,已经自动为您创建了您的概要文件。 选择您概要文件中可以公开的信息的信息(如姓名、国家/地区,以及公司),这些信息同时也会与您所发布的内容相关联。 您可以随时更新您的 IBM 账号。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

在 DB2 DPF 环境中,使用自定义 DISTRIBUTION MAP 解决数据分布不均匀问题

王富国, 软件工程师, IBM
王富国照片
王富国,IBM 中国软件开发中心 高级软件工程师,DB2 DW/BI 项目组,具有多年数据仓库、商业智能项目经验,目前从事 DB2 数据库和数据仓库相关产品的测试工作。
王婧霖, 软件工程师, IBM
王婧霖
王婧霖,IBM 中国软件开发中心 高级软件工程师,DB2 数据仓库 / 商业智能项目组,具有多年商业智能项目经验,目前从事 DB2 产品的测试工作。

简介: 在 DB2 的多分区数据库环境中,表中指定的分布键(Distribution Key)的哈希值决定了表中记录实际存放在哪个分区中。数据库管理器根据数据分布图(Distribution Map)识别数据所在的分区,如果根据默认的数据分布图不能实现数据相对均匀地分布在所有的分区中,我们可以通过人为调整数据分布图,实现数据的均衡分布。本文借助实践的手段,详细阐述了多分区数据库中数据分布的机理,并讲解了如何通过自定义分布图实现数据的均匀分布。

发布日期: 2011 年 10 月 20 日
级别: 中级
访问情况 : 1750 次浏览
评论: 


免费下载:IBM® DB2® Express-C 9.7.2 免费版 或者 DB2® 9.7 for Linux®, UNIX®, and Windows® 试用版
下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。

引言

在 DB2 的 DPF 环境中,数据库管理器根据表中指定的或默认的分布键( DISTRIBUTION KEY ),计算每条记录的哈希值,确定将该记录分布到相应的数据库分区中。DB2 默认将 32768 个哈希值依次对应到数据库的各个分区,通常情况下,如果表的分布键设计合理,分布在各个分区中的记录数就会相对比较平均。有些时候即使从业务逻辑的角度来看分布键设计合理,但是在各个分区中分布的记录数仍然相差较大,并不能达到相对均衡。即使在重新设计表的分区列后,仍有可能无法解决各分区中数据分布不均的问题。这个时候,我们该怎么办?

本文将通过实验,分析 DPF 环境中数据分布的原理,并详细阐述了如何通过自定义的数据分布图(DISTRIBUTION MAP),解决数据在分区中的分布不均衡的问题。


DB2 分区数据库的基本工作原理

DB2 中采用的数据库分区(Data Partitioning Feature,DPF)技术,为大规模数据处理、高并发数据访问提供了很好的支持。数据库分区采用的是 Share-nothing 体系结构,即数据库在一个非共享的环境中被分解为独立的分区,每个分区都具有自己的资源,例如内存,CPU 和磁盘以及自己的数据、索引、配置文件和事务日志。数据库分区称为节点或数据库节点。分区数据库的示意图如图 1 所示。


图 1. 分区数据库示意图
分区数据库示意图

在 DPF 中,负责与应用程序交互,接受应用程序的请求并向其返回结果集的数据库分区被称作协调节点(Coordinator Node),它是运行着协调代理(Coordinator Agent)的某个数据库分区,任意一个数据库分区都有可能成为协调节点。通过命令 SET CLIENT CONNECT_NODE 可以指定客户端要连接到 DPF 环境中哪个数据库分区,连接建立后该分区就是协调节点。协调节点可以自己完成应用的请求或者将工作布置给多个副代理(Subagent)处理。也就是说,当应用发出了一个查询要求,协调节点将查询请求发送给其他分区上的副代理,各个分区上的副代理将各自的结果集反馈给协调节点,协调节点把各个分区的结果集进行整合形成最终的查询结果,并将结果反馈给应用。

讲到这里,你的脑中可能会产生下面两个疑问。在下文中,你能找到它们的答案。

  • 疑问 1. 数据库管理器是怎样做到对哪个分区中保存哪条记录了如指掌,数据记录在各个数据库分区中的分布是遵循什么原则?
  • 疑问 2. 如果各个数据库分区中存放的记录数量严重失衡,也就是说某个或者某几个数据库分区中分布着绝大多数数据记录,而其余的数据库分区中分布着相对极少的数据记录,在这种情况下数据库的性能肯定无法达到最优的效果,DB2 数据库管理器有什么办法避免和解决这个问题?

掌握数据分布的玄机

在分区数据库环境中,数据库管理器面对的首要问题就是要知道在哪个数据库分区中可以找到它想要的数据记录,如何解决这个问题?数据分布图的引入,很好的解决了这个问题。这个分布图被称作 Distribution Map,它是在数据库管理器内部创建的一个数组,在多分区数据库环境中这个数组总共有 32768 个成员对应着数据库的分区组,在单分区数据库环境中只有一个数组成员对应数据库分区组。

对于具有多个分区的数据库分区组而言,所有分区依次对应一个分布图数组成员,直至分布图的全体数组成员都有对应的数据库分区。例如,在有四个数据库分区(分区号分别为 0,1,2,3)的多分区数据库环境中,数据库默认分区组 IBMDEFAULTGROUP 的数据分布图的内容如下,其中省略号意味着将数据库的所有分区号依次排列下去。

 0 1 2 3 0 1 2 3 0 1 2 ... 1 2 3 
			

如果一个数据库分区组只包含两个数据库分区,分区号分别为 2 和 3,那么该分区组的数据分布图的内容如下,其中省略号意味着将分区号 2 和 3 依次排列下去。

 2 3 2 3 2 3 2 3 2 3 2 ... 3 2 3 
			

根据表中分布键的值,数据库管理器将其哈希得到一个范围在 0 到 23767 之间的数,这个数就是分布图中的成员索引号,找到分布图成员,数据库管理器就知道了数据记录所在的数据库分区号。例如,在有七个分区的多分区数据库环境中,其中一个分区组包含四个分区(分别为 0,1,2,6),为了与其他编号区分,把它们命名为 N0,N1,N2 和 N6。 创建包含 5 列的表 table1,其中 col3 和 col4 被指定为分布键。如图 2 所示,对于表 table1 中的第 n 条记录,数据库管理器通过哈希得到一个数 1103,这个数就是数据分布图中的第 1103 个成员,这个成员对应的数据库分区是 N2。也就是说,表 table1 中的第 n 条记录存放在数据库分区 N2 上。

使用数据分布图,可以灵活的控制数据在多分区数据库中的存放位置,如果需要在数据库分区中重新分布数据,可以借助工具 redistribute 实现。结合数据分布图和这个工具就可以实现在数据库分区中重新调节数据分布,避免数据分布不均衡。


玩转数据分布图

俗话说“实践出真知”,结合上面的理论基础,我们来动手实践一下,看看真实的情况下数据分布的机理到底是怎么回事。具体操作步骤如下:

步骤 0. 准备多分区数据库环境

搭建一个有四个分区的多分区数据库环境,分区号分别是 0,1,2,3。其中默认的数据库分区组 IBMDEFAULTGROUP 包含所有的分区。

步骤 1. 建表 t2

在默认的表空间中创建一个数据表 t2,指定 c01 和 c02 为分布键,命令如清单 1 所示。


清单 1. 创建表 t2 的语句
				
 CREATE TABLE t2(c01 INTEGER,c02 CHAR(8), c03 varchar(40)) DISTRIBUTE BY(c01, c02) 
			

步骤 2. 准备数据

准备一些实验数据,保证数据的唯一性。数据文件如清单 2 所示。


清单 2. 数据文件 t2.del
				
 1,A,AAAAA 
 2,B,BBBBB 
 3,C,CCCCC 
 4,D,DDDDD 
 5,E,EEEEE 
 6,F,FFFFF 
 7,G,GGGGG 
 8,H,HHHHH 
 9,I,IIIII 
 10,J,JJJJJ 
 11,K,KKKKK 
 12,L,LLLLL 
 13,M,MMMMM 
 14,N,NNNNN 
 15,O,OOOOO 
 16,P,PPPPP 
 17,Q,QQQQQ 
 18,R,RRRRR 
 19,S,SSSSS 
 20,T,TTTTT 
 21,U,UUUUU 
 22,V,VVVVV 
 23,W,WWWWW 
 24,X,XXXXX 
 25,Y,YYYYY 
 26,Z,ZZZZZ 
			

步骤 3. 导入数据

把数据文件 t2.del 导入表 t2 中,命令如清单 3 所示。


清单 3. 导入数据的命令
				
 db2 "import from t2.del of del insert into t2"
 SQL3109N  The utility is beginning to load data from file "t2.del". 

 SQL3110N  The utility has completed processing.  "26" rows were read from the 
 input file. 

 SQL3221W  ...Begin COMMIT WORK. Input Record Count = "26". 

 SQL3222W  ...COMMIT of any database changes was successful. 

 SQL3149N  "26" rows were processed from the input file.  "26" rows were 
 successfully inserted into the table.  "0" rows were rejected. 


 Number of rows read         = 26 
 Number of rows skipped      = 0 
 Number of rows inserted     = 26 
 Number of rows updated      = 0 
 Number of rows rejected     = 0 
 Number of rows committed    = 26 
           

步骤 4. 查看数据的分布情况

现在,表 t2 中已经有了数据,我们来看一下这些数据在这个分区数据库环境中是怎么分布的。通过下面命令得到的结果集中(如清单 4 所示),第一列是数据库的分区号,第二列是该分区上的记录数。可以看到,数据在分区中分布的并不均衡,分区 0 和 1 上存放了约 73% 的数据,而分区 2 和 3 上只存放了约 27% 的数据。


清单 4. 查看数据分布的命令
				
 db2 "select dbpartitionnum(c01),count(*) from t2 
      group by dbpartitionnum(c01) 
      order by dbpartitionnum(c01)"
 1              2 
 ----------- ----------- 
          3           4 
          2           3 
          1          10 
          0           9 

  4 record(s) selected. 
           

步骤 5. 获取数据分布图

现在很好奇,达到上面分布效果的数据分布图会是什么样的?我们可以通过工具 db2gpmap 把指定表的数据分布图抽取出来,并保存到指定的文件中。命令如清单 5 所示。


清单 5. 获取数据分布图的命令
				
 db2gpmap -d testdb -m /home/wangfg/t2.map -t t2 
 Connect to testdb. 
 Successfully connected to database. 
 Retrieving the partition map ID using table T2. 
 The partition map has been sent to /home/wangfg/t2.map. 
           

打开生成的文件 t2.map,看到分布图的内容(截取部分)如下:

 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 
 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 
 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 
 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 

      . . .         . . .         . . . 

 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 
 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 
 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 
 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 

步骤 6. 查看每条记录在分区中的分布情况

现在你想知道具体每条记录,它是分布在哪个分区中的,还有它的哈希值到底是多少吗?我们可以通过下面的命令看的清清楚楚。如清单 6 所示,返回的结果集中,第一列是哈希值,第二列是数据库的分区号。


清单 6. 查看数据分布情况的命令
				
 db2 "select hashedvalue(c01),dbpartitionnum(c01), c01, c02 
       from t2 
      order by dbpartitionnum(c01),c01,c02"

 1              2             C01           C02 
 ----------- ----------- ----------- -------- 
      23952              0            11  K 
       1080              0            12  L 
      28216              0            13  M 
      10452              0            15  O 
       3052              0            17  Q 
       9256              0            20  T 
      24460              0            21  U 
      16980              0            22  V 
      22200              0            23  W 
      16941              1             2  B 
      29229              1             4  D 
       8181              1             5  E 
      10429              1             6  F 
      32485              1             7  G 
       4697              1             8  H 
       7173              1             9  I 
      23673              1            16  P 
       5281              1            18  R 
      23385              1            24  X 
      12834              2             3  C 
      32734              2            19  S 
      11646              2            26  Z 
      543             3          1  A
        395              3            10  J 
      30995              3            14  N 
      13919              3            25  Y 

  26 record(s) selected. 
           


自定义 DISTRIBUTION MAP 调整数据分布数据分布图

搞清楚了数据分布的记录,看清出了数据分区图中的内容,我们就通过自定义的分布图,或者修改已有的分布中,达到调整数据分布的目的。来做个实验吧,根据清单 6 中的结果,可以看到数据行(1,A,AAAAA)的哈希值是 543,它分布在分区 3 上。我们尝试一下把这行数据(1,A,AAAAA)从分区 3 移动到分区 2 上。具体步骤如下:

步骤 1. 自定义分布表

我们直接使用已有的分布图文件 t2.map,修改其中的第 543 个成员的值,把原值 3 改为 2。保存数据分布图文件 t2.map。

步骤 2. 重新分布数据

使用工具 redistribute,指定分布图文件 t2,把数据在分区中重新分布一遍。命令如清单 7 所示。


清单 7. 重新分布数据的命令
				
 db2 "REDISTRIBUTE DATABASE PARTITION GROUP IBMDEFAULTGROUP 
            USING TARGETMAP /home/wangfg/t2.map TABLE (t2) ONLY"
 DB20000I  The REDISTRIBUTE NODEGROUP command completed successfully. 
           

步骤 3. 查看数据分布情况

上述命令执行成功后,我们再来查看数据在分区中的分布情况,看看是否达到了我们的目的,只移动数据行 (1,A,AAAAA)到节点 2,其余数据保持原来位置不变。命令如清单 8 所示。


清单 8. 查看数据分布情况的命令
				
 db2 "select hashedvalue(c01),dbpartitionnum(c01), c01, c02 
       from t2 
      order by dbpartitionnum(c01),c01,c02"

 1           2           C01         C02 
 ----------- ----------- ----------- -------- 
      23952           0          11 K 
       1080           0          12 L 
      28216           0          13 M 
      10452           0          15 O 
       3052           0          17 Q 
       9256           0          20 T 
      24460           0          21 U 
      16980           0          22 V 
      22200           0          23 W 
      16941           1           2 B 
      29229           1           4 D 
       8181           1           5 E 
      10429           1           6 F 
      32485           1           7 G 
       4697           1           8 H 
       7173           1           9 I 
      23673           1          16 P 
       5281           1          18 R 
      23385           1          24 X 
      543           2         1 A
      12834           2           3 C 
      32734           2          19 S 
      11646           2          26 Z 
        395           3          10 J 
      30995           3          14 N 
      13919           3          25 Y 

  26 record(s) selected. 
           

通过 清单 8的结果集,我们可以看到,数据行 (1,A,AAAAA)现在已经被分布在分区 2中了,而其余的数据位置并没有发生变化。


结束语

本文通过实际操做,深入解析了分区数据库中数据分布的机制,并以移动数据的实例说明了如何通过自定义的分区图实现数据的重新分布。面对数据分布不均衡问题,你不会再无所适从了吧?动手吧!试着解决它。


参考资料

学习

获得产品和技术

讨论

作者简介

王富国照片

王富国,IBM 中国软件开发中心 高级软件工程师,DB2 DW/BI 项目组,具有多年数据仓库、商业智能项目经验,目前从事 DB2 数据库和数据仓库相关产品的测试工作。

王婧霖

王婧霖,IBM 中国软件开发中心 高级软件工程师,DB2 数据仓库 / 商业智能项目组,具有多年商业智能项目经验,目前从事 DB2 产品的测试工作。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=766804
ArticleTitle=在 DB2 DPF 环境中,使用自定义 DISTRIBUTION MAP 解决数据分布不均匀问题
publish-date=10202011