作为一款跨平台、灵活性高的变化数据实时复制产品,IBM InfoSphere Change Data Capture(以下简称 CDC) 正被用于各种各样的越来越多的数据处理场景。IBM DB2 Universal Database™ 数据分区功能(Data Partitioning Feature,以下简称 DPF)是 DB2 的一项重要特性,通过一个 share-nothing 架构支持数据库的可扩展性。在 DB2 DPF 环境中,每个单个的大型数据库都会分布在若干个 DB2 的服务器上,相互之间通过高速的内部连接(如 TCP/IP 协议)进行信息交换,使得 DB2 在性能和可伸缩性方面得到显著改善。作为数据实时复制领域的领军产品,为最大程度保证发生故障时数据的实时完整性,CDC 早从 6.5.1 版本就已开始支持开放平台上 DB2 的 DPF 功能,并在后续版本中不断加强完善此功能。以下我们将通过实现系统级别 DB2 LUW DPF 数据实时复制模型的部署,讲解 CDC 如何实现对 DB2 分区数据库的支持。
回页首
数据库分区技术 DPF 的出现主要是为了满足企业数据量级快速增长的需求,它可以有效提高企业数据读写操作和查询操作的速度。
DPF 是一种物理数据库设计技术。不同于普通情况的一个数据库内所有数据表都位于同一台物理或逻辑机器上,DPF 是将一个或多个数据库表分布在两台以及多台物理或者逻辑机器上。然后通过并行的方式对这些分布在多台机器上的数据库表进行处理,实现对数据的快速处理。
数据库分区最大的好处就是,对于特定的 SQL 操作可以减少数据读写的总量从而缩减响应时间。DB2 的分区环境适合于统计类和分析类的应用,如一般单位的数据仓库系统。正如一位工程师所言:目前 DB2 的 DPF 特性所涉及的几乎全是海量数据仓库系统,数据量基本都是 10T 以上的,所在行业主要是移动、联通、电信的仓库分析系统,以及部分银行仓库系统,还有部分电力公司,其中最大的广东移动,数据量已突破 800T。
具有 DPF 功能的 DB2 UDB ESE 是管理 OLAP、数据仓库和数据挖掘工作负载的理想选择。对于大型 OLTP 工作负载,它也是很好的选择。
DB2 数据库分区采用 Share-nothing 体系结构,也即各个数据库分区处在独立的非共享的环境中,具有自己的资源,例如内存、CPU 和磁盘,以及自己的数据、索引、配置文件和事务日志。数据库分区(partition)也被称为节点(node),每个 node 具有独立处理单一任务的能力,每个子任务处理某一部分数据,分区之间的数据则通过高速网络进行交互。
由于分区之间独立,DB2 DPF 具有了比较佳的扩展性,只需简单的增加节点资源便可达到线性扩展节点的目的。通过跨多个既可位于同一服务器也可位于多个服务器但是能够彼此合作的实例建立单个大型数据库服务器。可以认为它把一个大的数据库分成多个独立的小的数据库,其中每一个小数据库分区拥有自己的一部分数据,从而达到节点同时并发的高效率处理能力。
比如企业客户在使用 DB2 过程中需求增加的话,可以将原本位于单个分区上的小型 DB2 UDB(ESE)数据库迁移到多分区的 DB2环境中去,高效便捷可靠。
用户可能会疑惑表中记录实际存放在哪个分区中。在 DB2 的多分区数据库环境中,表中指定的分布键(Distribution Key)的哈希值决定了上述问题。数据通过 Hash 算法均匀地散列到不同的分区内,每个分区只负责处理自己的数据。当用户发出 SQL 操作后,被连接的分区被称为 Coordinate Node,它负责处理用户的请求,并根据 Partition key 将用户的请求分解成多个子任务交由不同分区并行处理,最后将不同分区的执行结果经过汇总返回给用户,分区对应用来说是透明的。数据库管理器根据数据分布图(Distribution Map)识别数据所在的分区,当默认的数据分布图不能实现数据相对均匀地分布在所有分区中时,可以通过人为调整数据分布图以便实现数据的均衡分布。
简单的讲,数据库分区与结点关系如下:
①数据库实例目录在一台机上创建,并做 NFS 到其他主机;
②通过配置 db2nodes.cfg 实现各台主机的通信;
③各台主机需要通信,需要确定开通集群中的机器可以互相 rsh 连接。
设计数据库分区的基本原则是,尽量将大表分布在所有的分区上,提高并行处理能力;将小表放置在尽量少的分区上,一般是建议放在单一分区上;尽量减少分区间的通信。
回页首
以下将从未安装 DPF 环境的机器开始,讲解如何在 LUW 平台安装 DB2 DPF 环境。
Instance 级别的 multi-partition DB2环境分为 3 种:DB2 SMP, DB2 MPP 和 DB2 SMP Cluster,分别代表:在一台多个 cpu 的机器上建多个 partitions,在多台单个 cpu 的机器上建多个 partitions,在多台多个 cpu 的机器上建多个 partitions。并且请注意,以上三种情况的 partitions 数目皆不超过机器所拥有的 cpu 数量。
需要使用 root 用户。对于机器的要求:保证至少 2GB 磁盘,建议 1GB 内存。每台机器的操作系统必须完全相同,包括位数、小版本号和补丁。系统补丁升级、系统时间设置须一致。如果有任何一台机的操作系统版本不同,即使是细微不同,都有可能造成许多奇怪的错误。
也可以采用 vmware 装,先安好一台(装好 DB2,建好用户),再使用 clone 功能复制一台,更新各自的 ip 就好,DB2 安装路径、版本,用户和组的 ID 都必须一样,所以这样做既省事又准确。
运行时要求的特定 NFS 进程有:rpc.statd,rpc.lockd。其中 rpc.statd 这个进程实现了网络状态监控 (NSM)RPC 协议, 通知 NFS 客户端什么时候一个 NFS 服务器非正常重启动. 这个进程被 nfslock 服务自动启动,不需要用户的配置。而 rpc.lockd 是一个可选的进程,它允许 NFS 客户端在服务器上对文件加锁. 这个进程对应于 nfslock 服务。
分区数据库系统需要远程 shell 实用程序:rsh, or ssh。默认是 rsh,最好使用 openssh。配置步骤如清单 1 所示。
清单 1. rsh 的配置步骤
~#:rpm -aq |grep rsh //检查是否有 rsh server rsh-0.17-40.el5_7.1 rsh-server-0.17-40.el5 ~#:rpm -ivh rsh-server-0.17-40.el5.x86_64.rpm //若无则安装 ~#:vi /etc/xinetd.d/rsh //将参数 disable 的值改为 no ~#:/etc/rc.d/init.d/xinetd restart //重启 rsh 服务
更新.rhosts 文件以执行远程命令。这个条件在多机环境下必须配置,单机可以不配。文件路径一般为:/home/db2inst1/.rhosts,配置如清单 2 所示。
清单 2. rhosts 文件配置示例
ServerA.yourdomain.com db2inst1 ServerB.yourdomain.com db2inst1 ServerC.yourdomain.com db2inst1 ServerD.yourdomain.com db2inst1
/etc/hosts 也需要添加主机名。/etc/hosts 是配置 ip 地址和其对应主机名的文件,这里可以记录本机的或其他主机的 ip 及其对应主机名。
只要是包含 DB2 DPF 功能的 DB2 版本都可以,如 DB2 ESE。安装过程中有 3 个选件可以安装,分别是 ESE、CLIENT 和 RTCL。CLIENT 包含有 DB2 应用开发所需要的软件包,一般情况下都是需要安装的。安装全部三个选件大概需要 2GB 空间。
将 DB2 DPF 所在的软件包传到每一台需要运行 DPF 的机器上,分别解压和安装,将目录更改到产品目录,执行 DB2_install 命令安装产品。当提示输入需要安装的产品名称时,输入 ESE CLIENT。初次安装完 DB2 产品后,建议在创建实例之前安装最新补丁。
首先是建用户和组账户,配置 node 信息。依次创建:dasusr1(dasadm1), db2inst1(db2iadm1), db2fenc1(db2fadm1),在将参与分区数据库环境的每台计算机上创建完全相同的用户和组帐户。注意,必须具有 root 用户权限才能创建用户和组。如表 1 和清单 3 所示。
表 1. 需创建的用户类型
必需的用户 | 用户名 | 组名 |
---|---|---|
实例所有者 | db2inst1 | db2iadm1 |
受防护的用户 | db2fenc1 | db2fadm1 |
管理服务器用户 | dasusr1 | dasadm1 |
清单 3. 用户的属性及分组信息
mkgroup id=999 db2iadm1 mkgroup id=998 db2fadm1 mkgroup id=997 dasadm1 --------- mkuser id=1004 pgrp=db2iadm1 groups=db2iadm1 home=/db2home/db2inst1 core=-1 data=491519 stack=32767 rss=-1 fsize=-1 db2inst1 mkuser id=1003 pgrp=db2fadm1 groups=db2fadm1 home=/db2home/db2fenc1 db2fenc1 mkuser id=1002 pgrp=dasadm1 groups=dasadm1 home=/home/dasusr1 dasusr1
更新节点配置文件,路径一般为:/export/home/db2inst1/sqllib/db2nodes.cfg。分区数据库环境中的每个实例都有一个 db2nodes.cfg 文件。配置如清单 4 所示。
清单 4. db2nodes.cfg 文件配置示例
0 rac1.localdomain 0 1 rac1.localdomain 1 2 rac1.localdomain 2 3 rac1.localdomain 3
用来处理数据库分区服务器之间的通信的功能部件。
清单 5. services 文件配置示例
# Local services # DB2c_db2inst1 60000/tcp DB2_db2inst1 60001/tcp DB2_db2inst1_1 60002/tcp DB2_db2inst1_2 60003/tcp DB2_db2inst1_3 60004/tcp DB2_db2inst1_END 60009/tcp db2_conn 50000/tcp
设置 TCP/IP 通信,配置如清单 6 所示。输出示例如图 1 所示。
清单 6. tcp/ip 通信配置示例
[db2inst1@rac1 ~]$ db2start [db2inst1@rac1 ~]$ db2set DB2COMM=tcpip [db2inst1@rac1 ~]$ DB2® terminate [db2inst1@rac1 ~]$ DB2® update dbm cfg using SVCENAME DB2c_db2inst1 [db2inst1@rac1 ~]$ db2stop force [db2inst1@rac1 ~]$ db2start
图 1. 配置 tcp/ip 通信信息
点击查看大图
关闭 [x]
安装完毕之后,可以通过建表的方式验证 DB2 DPF 环境是否搭建成功。先用以下语句建表:
DB2 => create table zm11 ( id char not null, pkcol varchar(4) not null with default 'abc')。要验证是否已将数据分发至数据库分区服务器,在 DB2 命令窗口中输入下列命令:DB2 => select distinct dbpartitionnum(id) from zm11 和 DB2 => select distinct dbpartitionnum(pkcol) from zm11,输出将列示 zm11 表使用的数据库分区。
至此,LUW 平台 DB2 DPF 环境已经搭建完毕。
回页首
以下将通过实现系统级别 DB2 LUW DPF 数据实时复制模型的部署,讲解 CDC 如何实现复制 DB2 分区数据库环境中的数据。
源端计划使用的 DPF 场景为:两个物理节点(physical nodes),每个物理节点上各有四个逻辑节点(logical nodes),也即共有 8 个分区(partitions),依次标记为 P0,P1,P2,P3,P4,P5,P6 和 P7。我们会创建 5 个分区组(partition group,简记为 PG),分组情况如下:
针对每个 partition group 建立一个 tablespace。最后,创建 200 个表,随机的分布在 5 个 tablespaces 之上。如图 2 所示。目标端可采取任何 InfoSphere CDC(V6.x 和更高版本)产品,包括 DPF 环境,在此不再赘述。
图 2. 系统级别 DPF 场景
点击查看大图
关闭 [x]
需要依次创建 database(如清单 7 所示),建 partition group(如清单 8 所示),针对每个 partition 建各自的 bufferpool(如清单 9 所示)或者创建统一的 bufferpool(如清单 10 所示),建 tablespace(每个 PG 上面都得建一个 tablespace,如清单 11 所示),创建完毕就可以建 table 了,表就会自动分散的建在几个 tablespaces 里面了,如果想对参数调整那么需要使用 db2_all 命令(如清单 12 所示)。
清单 7. 创建 database 操作示例
[db2inst1@rac1 ~]$ db2start //这样把所有的 nodes 都启动起来 DB2 => create database DBZM01 using codeset utf-8 territory us DB2 => update db config for DBZM01 using logarchmeth1 logretain [db2inst1@rac1 ~]$ db2_all "DB2 backup database dbzm01 to /dev/null" DB2 => connect to DBZM01 DB2 => create bufferpool bufferpool32 immediate pagesize 32 K DB2 => create user temporary tablespace tablespace32 pagesize 32 K managed by automatic storage bufferpool bufferpool32
清单 8. 创建 partition groups 操作示例
DB2 => create database partition group pgall on all dbpartitionnums DB2 => create database partition group pg1 on dbpartitionnums(0,1) DB2 => create database partition group pg2 on dbpartitionnums(5,6,7) DB2 => create database partition group pg3 on dbpartitionnums(1) DB2 => create database partition group pg4 on dbpartitionnums(0,1,2,3,4,5,6,7) DB2 => create database partition group pg5 on dbpartitionnums(0,1,5,6,7) //即 (pg1,pg2)
清单 9. 创建 bufferpool 操作示例
DB2 => create bufferpool bpool_1 immediate database partition group pg1 size 10000 pagesize 32 k DB2 => create bufferpool bpool_2 immediate database partition group pg2 size 10000 pagesize 32 k DB2 => create bufferpool bpool_3 immediate database partition group pg3 size 10000 pagesize 32 k DB2 => create bufferpool bpool_4 immediate database partition group pg4 size 10000 pagesize 32 k DB2 => create bufferpool bpool_5 immediate database partition group pg5 size 10000 pagesize 32 k
清单 10. 创建统一的 bufferpool 操作示例
DB2 => create bufferpool pool_32k immediate all dbpartitionnums size 98304 pagesize 32k
清单 11. 创建 tablespace 操作示例
DB2 => create tablespace tszm01 in database partition group pg1 pagesize 32k managed by system using ('./tbspzm/tszm01') bufferpool bpool_1 DB2 => create tablespace tszm02 in database partition group pg2 pagesize 32k managed by system using ('./tbspzm/tszm02') bufferpool bpool_2 DB2 => create tablespace tszm03 in database partition group pg3 pagesize 32k managed by system using ('./tbspzm/tszm03') bufferpool bpool_3 DB2 => create tablespace tszm04 in database partition group pg4 pagesize 32k managed by system using ('./tbspzm/tszm04') bufferpool bpool_4 DB2 => create tablespace tszm05 in database partition group pg5 pagesize 32k managed by system using ('./tbspzm/tszm05') bufferpool bpool_5
清单 12. 创建 tablespace
DB2 => create table dpfzm1 (id integer not null, name char(20) not null) in tszm01 ~#:db2_all "DB2 update db cfg for db2dpf using logfilsiz 10000"
DB2 DPF 既可作为 CDC source 端,又可作为 target 端。具体版本表现为,InfoSphere CDC for DB2 LUW V6.5.1 及更高版本支持将更改数据从源系统上的 DPF 环境复制到任何 InfoSphere CDC V6.5.1 或更高版本目标部署;同时,InfoSphere CDC 支持将更改数据从任何 InfoSphere CDC 源(V5.x 和更高版本)复制至目标 DPF 环境。
当 CDC 用于 DPF 环境时,它的安装与普通环境下 CDC 的安装并无区别。只需将 CDC 所在的软件包传到其中任意一台需要运行 DPF 的机器上(物理节点),解压和安装即可。在安装完毕之后配置 instance 时,只需在连接数据库时选择已经建好的 DPF 分区数据库即可。具体步骤可参见 CDC 的 Knowledge Center,有详细描述,此处不再赘述。
CDC 要求 DB2 DPF 启用数据库日志保留时间,所以需要在 DB2 LUW 中使用 logretain 参数对要用于复制的每个数据库都启用日志保留:DB2 => update db config for DBZM01 using logarchmeth1 logretain 这一步在上一部分建 database 的时候已经完成。这里单独列出只是显示其必要性。
当在 DPF 环境中新添加分区时,也必须在 InfoSphere™ CDC 源系统上对 DPF 环境中新添加的分区使用 logretain 参数来启用日志保留。本文后续部分会提到。
值得指出的是包含了 LOB 或 XML 数据类型的表。当刷新至 DPF 环境时,必须把 InfoSphere™ CDC 目标系统上的快速刷新装入器目录(fast refresh-loader directory)设置为 DPF 所有分区皆可访问。快速刷新装入器目录默认即产品的安装目录。用户可以通过设置 NFS(网络文件系统)或 SAN(存储区域网络)设备来使装入目录可供所有分区访问。
至此,CDC for DB2 DPF 环境系统级别部署已经初步完成!您可以在 CDC 产品的管理控制台(Management Console)中使用已建好的 cdc instance,连接它并建立自己需要的 datastore 和执行特定表之间复制功能的 subscription,开始复制数据并实时捕捉数据变化!
回页首
用户如果希望将数据分布在所有分区中或者想对数据分布状况不佳的表进行重新平衡时,可以使用 DB2 for LUW 中的 redistribute database partition group 命令,注意使用 not rollforward recoverable 选项。
另外在配置 CDC instance 的时候,CDC 将主动确定检测 DPF 数据库中的更改所需的所有分区。如果用户想临时更改源 DPF 数据库的分区配置,需要遵循下面叙述的一些设置方法。
注意,添加或者删除分区之后都要使用 redistribute database partition group 命令使改动生效。
可以在源 DPF 环境中根据需要添加一个分区。当 InfoSphere CDC 重新启动的时候,CDC 实例能够检测到用户对源端 DPF 环境分区配置所作的更改。
注意,在添加分区之前,需要确保 InfoSphere CDC 已经成功将源端 DPF 数据库中的所有更改复制到目标端,并且停掉 InfoSphere CDC 实例(即不得处于运行状态)。另外在修改 DPF 分区期间,不能修改 CDC 实例其他的任何配置。
具体操作步骤为:首先通过使用"预订结束" - "立即"选项结束针对所有预订的复制,此选项将在源数据库日志中的当前源系统时间结束复制。然后使用 dmshutdown 命令关闭所有 InfoSphere CDC 实例。
在 源端 DPF 环境中添加好分区之后,在 DB2 LUW 中执行 redistribute database partition group 命令以重新分布数据(注意使用 not rollforward recoverable 选项)。另外使用 logretain 参数在 DB2 for LUW 中启用日志保留,并对分区上的数据库进行完全备份。这是都是 InfoSphere CDC 在添加分区时所要求的必要操作。
添加新分区结束后,必须先启动 InfoSphere CDC 实例,然后用户才能在数据库中进行正常的 DML 复制。
同样可以删除源端 DPF 环境中的一个分区。当 InfoSphere CDC 重新启动的时候,CDC 实例能够检测到用户对源端 DPF 环境分区配置所作的更改。
注意,在删除分区之前,也需要确保 InfoSphere CDC 已经成功地将源端 DPF 数据库中的所有更改复制到目标端,并且停掉 InfoSphere CDC 实例(即不得处于运行状态)。另外在修改 DPF 分区期间,不能修改 CDC 实例其他的任何配置。
具体操作步骤为:首先通过使用“预订结束”-“立即”选项结束针对所有预订的复制,此选项将在源数据库日志中的当前源系统时间结束复制。需要注意的是,在删除分区之前,需要确保已将该分区上的数据库日志中的所有更改复制到目标。因为 InfoSphere CDC 是依靠数据库日志进行复制更改任务的,如果在删除分区时日志被除去,那么 InfoSphere CDC 就无法复制更改了。可执行 dmshowlogdependency 命令确保 InfoSphere CDC 不需要用户打算删除的分区上的任何数据库日志。只有当用户确定 CDC 不依赖于某个分区上的数据库日志时,才能删除该分区。然后使用 dmshutdown 命令关闭所有 InfoSphere CDC 实例。
最后同样,在删除分区之后,在 DB2 for LUW 中执行 redistribute database partition group 命令以重新分布数据(注意使用 not rollforward recoverable 选项)。
回页首
接下来阐述一下在 DPF 环境中有哪些用户需要了解的关于 InfoSphere CDC 行为的信息。
最主要的由于 DPF 环境中数据库日志记录的局限性,对 CDC 的复制会发生一些影响。比如当某个事务对多个分区中的行产生影响时,数据库日志将维护每个分区中的操作顺序,但不维护跨分区的相对顺序。另外对于将行从一个分区移到另一个分区的更新(对分区键所作的更新),数据库将这种更新作为单独的删除和插入操作进行日志记录。
具体示例用户可以参考 InfoSphere Data Replication V11.3.3 Knowledge Center 中所列举的对 LiveAudit 表映射的影响和当目标表中存在唯一约束时的例子。
回页首
根据作者在 DPF 环境中部署 InfoSphere™ CDC 的经验,可以考虑以下最佳实践:
回页首
DPF 作为支持 DB2 数据库可扩展性的重要功能,已经得到了广泛应用。CDC for DB2 LUW DPF 应用的实现,无疑为复制 DPF 环境中的数据提供了极大的方便,进一步保证了发生故障时数据的实时完整性。