2023年11月30日发(作者:)

DB2pureScale性能监控和调优

DB2 pureScale 集群⼯作⽅式介绍

DB2 pureScale 是同时兼备⾼扩展性和⾼可⽤性的数据库集群,同时对于应⽤是透明的。⽆论是连接到数据库的哪个成

员,应⽤都⽆需任何更改,对于应⽤来说,可以认为它仅仅是连接到单个的数据库。DB2 pureScale ⼯作负载均衡特性

帮助数据库更好的充分利⽤资源。但是毕竟 DB2 pureScale 是⼀个数据库集群,运⽤的技术远⽐单机版数据库复杂。

同时新技术的运⽤对性能带来什么样的影响,以及如何去监控和应对,都是⽤户在使⽤ DB2 pureScale 集群后亟需解

决的问题。

⾸先从 DB2 pureScale 集群的架构出发,下⾯这张图显⽰了 DB2 pureScale 集群所使⽤到的产品和⽐较重要的技术。

DB2 pureScale 使⽤了 IBM TSATivoli System Automation)集群软件整合所有资源,并⾃动化所有资源的⾏为,

从⽽搭建整套的集群环境。

1. DB2 pureScale 集群的架构

DB2 pureScale 集群成员

DB2 pureScale 集群可以有多个成员(member)组成,每个成员都可以看成是⼀个能够提供完全数据库服务的节点。

任何应⽤只需要连接到⼀个成员即为连接到整个数据库,所以在 DB2 pureScale 集群⾥⾯有多少成员对于应⽤是透明

的。

DB2 pureScale 集群的⾃动⼯作负载均衡能将⼯作负载均衡到多个数据库成员上,从⽽充分利⽤成员的硬件资源,满⾜

⾼性能的需求。DB2 pureScale 集群的⾼扩展性能够帮助⽤户通过增加成员来满⾜更⾼性能的需求。

DB2 pureScale 集群 CF

DB2 pureScale 集群⾥⾯,成员之间的协作是由 CFCluster Caching Facility)帮助完成的。在数据库成员和 CF

之间有⾼速⽹络相连(Infiniband ⽹络),成员和 CF 之间通过 RDMA(远程内存直接访问)的⽅式交互数据,这种技

术跳过了⽹络协议所需要的交互,是⾮常快的。CF 主要管理整个数据库集群的通信,控制全局锁和全局缓冲池等。可

以说 CF 就是 DB2 pureScale 集群的⼤脑,它对于性能会有很⼤的影响。

DB2 pureScale 集群⽹络

DB2 pureScale 集群⾥⾯,成员和 CF 需要两种⾼速⽹络互联:Infiniband ⽹络和⾼速以太⽹。如果⽹络出现问题或

者拥挤,会对性能有影响。

DB2 pureScale 集群共享存储

DB2 pureScale 是使⽤共享存储的数据库集群。所有数据库的存储需要连接到所有成员和 CFDB2 pureScale 会在存

储上创建 GPFS ⽂件系统。GPFS ⽂件系统是⼀种⾼速的共享⽂件系统,它同样是⼀个⽂件系统集群,具有⾼可⽤性和

易扩展性,易管理性等。成员的 CPU,内存等可以通过增加新的硬件资源或者增加成员等⽅式来满⾜。但是存储这边

就没有那么简单,所以需要监控存储的利⽤率确定是否遇到瓶颈⽽导致性能问题。

关于硬件资源的所带来的性能影响,例如内存不够,⽹络拥挤,磁盘 IO 瓶颈等,这些可以通过系统的监控⼯具来确

定。⾮集群 DB2 数据库可能遇到的性能问题和解决⽅法,在 DB2 pureScale 集群同样适⽤。下⾯会就 DB2 pureScale

集群本⾝的特点所带来的性能问题做⼀些探讨。

探讨数据库成员的⼯作负载

DB2 pureScale ⾃动⼯作负载均衡是数据库集群⾥⾯对性能⾮常有帮助的⼀个特性。DB2 pureScale ⽀持连接级别和事

务级别的⼯作负载均衡。这个两种级别的负载均衡可以在 DB2 客户端配置启⽤,DB2 客户端就会从数据库集群获取所

有成员的负载信息,然后根据负载信息来确定下⼀个连接或者事务运⾏到负载低的数据库成员上,从⽽达到负载均衡的

效果。所以 DB2 pureScale 性能课题之⼀就是如何⽤好⾃动负载均衡特性,解决成员节点出现瓶颈的性能问题。

2. ⾃动⼯作负载均衡

监控 DB2 pureScale 集群成员负载信息

DB2 提供了⼯具直接查看 DB2 pureScale 集群成员的负载信息。db2pd DB2 提供的⼀个功能强⼤和丰富的⼯具,占

⽤资源少,速度快。db2pd 可以查看数据库级别的负载信息。

清单 1. 查看 DB2 pureScale 集群成员的负载信息

如清单中所⽰,当前有连个数据库成员 TESTDBM0 TESTDBM1,它们提供了 Non-SSL 端⼝连接,每个成员的负载

信息是看 Priority 这⼀项。这个数值越⼤,这个成员上的负载就越轻。如果这个成员出现异常不能⼯作,那么它的

Priority 就会是 0

清单 2. 异常成员的负载信息

数据库成员 TESTDBM0 被终⽌后,它的 Priority 值变为 0. 如果其他的成员 Priority ⽐较⼩,⽽某个成员的 Priority

100,说明这个成员是完全空闲的。

分配 DB2 pureScale 集群成员负载

分配应⽤⼯作负载均衡到 DB2 pureScale 集群各成员有两种⽅式,⼀种是使⽤⾃动⼯作负载均衡特性,另⼀种是⾃定

义应⽤连接到指定的数据库成员。

如何启⽤⾃动⼯作负载均衡特性可以参考作者的另外⼀篇⽂章《如何部署 DB2 pureScale ⼯作负载均衡特性》或者其

他资料。这⾥探讨⼀下在使⽤了⾃动⼯作负载均衡之后的⾏为。数据库的负载信息⼀直在变化,客户端什么时候会感受

到这个变化呢?客户端从数据库服务器获取了服务器列表的负载信息,然后储存在本地。⼀段时间间隔后,客户端会重

新获取当前的服务器负载信息,更新本地的服务器列表。这个时间间隔如果⽐较长,那么客户端对服务器负载信息的反

应就不会很敏捷,⾃动⼯作负载均衡的效果就会受到⼀定的影响。但是如果这个时间间隔设置的太短,那么收集服务器

负载信息的⼯作就会变的频繁,相应的开销也会变⼤。所以这⾥需要考虑的是估算⼀个⽐较合适的时间间隔。这个时间

间隔由客户端配置参数 maxRefreshInterval 控制。

清单 3. maxRefreshInterval

DB2 客户端可以使⽤ 配置⽂件来配置 maxRefreshInterval 参数。对于 JAVA 应⽤,JDBC 驱动⾥⾯也

有这个参数。这个参数的默认配置是 30 秒,也就是 DB2 客户端每 30 秒从数据库服务器获取负载信息并更新本地保存

的服务器列表。

另⼀种⽅式就是不使⽤⾃动的负载均衡,⽽是应⽤指定使⽤哪个数据库成员。客户端偏好设置(Client Affinity)就是这

样⼀种⼯作⽅式。如果⽤户了解⾃⼰的应⽤负载状况,那么就可以合理的安排应⽤去连接数据库成员,从⽽利⽤所有成

员的资源。例如⽤户可以把负载⾼的成员上的应⽤连接到其他负载低的成员。这种⽅式对⽤户要求⽐较⾼。

探讨 DB2 pureScale 集群全局缓冲池(GBP)技术

DB2 pureScale 集群⾥⾯ CF 扮演了很重要的⾓⾊,其中之⼀就是引⼊了全局缓冲池的概念。全局缓冲池是 CF 加载的

⼀部分内存区,顾名思义是缓冲整个集群的数据库数据。那么与此对应,每个数据库成员⾃⼰的缓冲池就称为本地缓冲

池(LBP)。下⾯通过⼀个例⼦来看 LBP GBP 的关系。

3. 查询数据(GBP LBP

上图所⽰,在 member 1 上有个应⽤想要访问 page 501 ⾥⾯的数据,这个时候 member 1 的本地缓冲池并没有这个数

据,但是 CF 的全局缓冲池⾥⾯是有的。那么 Member 1 就会通过 RDMA 的⽅式直接访问 CF 获取这个数据,并放置到

据,但是 CF 的全局缓冲池⾥⾯是有的。那么 Member 1 就会通过 RDMA 的⽅式直接访问 CF 获取这个数据,并放置到

本地缓冲池中。在上⾯这个例⼦中,如果 CF 的全局缓冲池没有 page 501,那么 member 1 需要从本地磁盘读取。因为

RDMA 是直接物理访问对⽅内存,⽐从本地磁盘读取还要快很多。所以如果需要访问的数据能在全局缓冲池⾥找到,那

么访问的性能会更好。

监控全局缓冲池的性能指标

本地缓冲池有命中率的概念,命中率越⾼,那么说明需要访问的数据在内存⾥发现的⽐率越⾼,相应的性能就会越好。

对于全局缓冲池来说也是⼀样,成员需要访问的数据在 GBP ⾥⾯发现的次数越多,说明从磁盘读取的次数越少,也是

性能会更好。所以监控 GBP 就是监控它的命中率。DB2 提供了 MON_GET_BUFFERPOOL 表函数提供这些信息。

清单 4. 使⽤ MON_GET_BUFFERPOOL 的⽅法

使⽤ db2 命令运⾏上⾯的语句,会得到所有缓冲池有关 GBP 的命中率。

4. 调⽤ MON_GET_BUFFERPOOL 表函数结果

从上⾯的命令输出结果来看,GBP 的命中率都⽐较低。如果是因为 GBP 的内存不够⼤⽽引起很多的 paging,那么增

GBP 的⼤⼩会有助于提⾼缓冲池的命中率,从⽽提⾼查询的性能。

探讨 DB2 pureScale 集群全局锁管理(GLM)技术

DB2 pureScale 集群⾥数据库成员之间的锁机制是由 CF GLM 管理的。与缓冲池类似,数据库成员本地是有锁机制

的,也就是内存⾥的 LockList 块。但是本地锁只能管理本地资源的交互。如果多个数据库成员同时需要更改同⼀页内的

数据,就会产⽣竞争,为了保持数据的⼀致性,这种⾏为就需要锁的控制。来看⼀个例⼦。

5. 更新数据(GBP GLM

在这个例⼦中,所有 4 member LBP 中都有 page 501. 这个时候 member 1 想要更改 page 501 ⾥⾯的数据。它就

需要向 CF GLM 请求这个 page 的锁。member 1 更新完这个数据,显然其他 member LBP ⾥⾯的 page 501 就过

时了,CF 会⾃动的使⽤ RDMA 技术把所有其他 member LBP ⾥的 page 501 设置为⽆效。这样⼀旦其他 member

还需要访问这个 page 的数据,就不会使⽤⽆效的 LBP 的内容,⽽是从 CF 获取更改过的新的内容。整个过程,GLM

的锁机制保持了数据⼀致性。如果 member 1 GLM 获得了关于 page 501 的锁并没有释放,其他 member 还要更改

page 501 ⾥的其他内容的话,也需要向 CF 申请锁,CF 就会告知此 page 锁已被 member 1 使⽤,请等待 member 1

释放。这个时候就会出现锁等待。这是需要监控的性能指标之⼀。如果 member 1 ⼀直不释放锁,那么其他 member

的应⽤会因为⼀直等不到这个锁⽽产⽣锁超时⽽失败。锁超时的次数也是需要监控的。member 之间的锁是 page 这个

级别的,如果 GLM ⽐较⼩,同⼀ table page 锁需求⼜⽐较多,就可能引起锁升级,也就是这张表的所有 page 锁升

级成整张表的表级锁,其他的 member 甚⾄⽆法访问其他 page 的数据,这会影响并发性,带来更差的性能。所以全局

锁的锁升级次数也是需要关注的。

监控全局锁管理(GLM)的性能指标

正如上⽂所述,我们需要监控与全局锁管理相关的锁等待,锁超时,锁升级等相关性能指标。DB2 提供了多个表函数可

以列出全局锁管理的这些监控元素。这⾥使⽤其中⼀个表函数 MON_GET_PKG_CACHE_STMT 来⽰范。这个表函数

会收集当前数据库的 PACKAGE CASH ⾥⾯的信息,返回为⼀张表,可以被 SQL 语句直接调⽤。

清单 5. 调⽤ MON_GET_PKG_CACHE_STMT 表函数

在调⽤ MON_GET_PKG_CACHE_STMT 返回的众多信息中,案例⾥⾯查询了

LOCK_WAITS_GLOBALLOCK_WAIT_TIME_GLOBAL,LOCK_TIMEOUTS_GLOBAL,LOCK_ESCALS_GLOBAL

与全局锁管理相关的监控元素。

LOCK_WAITS_GLOBAL:因为锁被其他 member 占⽤⽽等待的次数。次数越多说明并发性受影响越⼤。

LOCK_WAITS_GLOBAL:因为锁被其他 member 占⽤⽽等待的次数。次数越多说明并发性受影响越⼤。

LOCK_WAIT_TIME_GLOBAL:等待其他 member 占⽤的锁的时间。时间越多说明并发性受影响越⼤。

LOCK_TIMEOUTS_GLOBAL:因为等待其他 member 占⽤的锁⽽产⽣的超时次数。事务会因此失败⽽回滚。

LOCK_ESCALS_GLOBAL:全局锁升级的次数。锁升级会导致并发性的严重降低。

这个表函数对于在查询当前⼀段时间的系统性能问题是否是因为全局锁⽽引起⾮常有效。因为 Package Cache 的⼤⼩

是有限的,所以早些时间运⾏的 SQL 语句可能已经被挤出这个内存块,就不会被这个表函数返回。DB2 还提供了其他

⼀些针对不同对象的表函数,也能反馈这些全局锁的信息。例如

MON_GET_CONNECTIONMON_GET_WORKLOADMON_GET_UNIT_OF_WORK 等等。

解决全局锁的性能问题

已经从上⽂中获取到了引起全局锁问题的 SQL 语句,相应的也定位到了相关的应⽤。现在的问题是已什么样的思路去

解决性能指标所⽰的这些问题。

⾸先还是从全局锁的产⽣原因来看。全局锁是 member 之间的锁,也就是在不同的 member 上运⾏的应⽤需要访问同⼀

个表的相同 page 内的数据。⼀种解决的⽅式就是将这些应⽤安排到同⼀个 member 上运⾏,就不存在 member 间竞争

的问题。这种⽅式可以通过设置客户机偏好的⽅式。前提是定位到是哪些应⽤有冲突,单个 member 的系统资源是否⾜

以运⾏这些应⽤。

另外⼀种⽅式是在应⽤的事务中加⼊更多的 Commit。提交越频繁,锁就释放的⽐较快,相应的减少锁冲突的⼏率。

如果某些全局锁⽆法避免,但是应⽤会经常因为锁超时⽽回退。这对终端⽤户会有很⼤的影响。这个时候可是适当增加

锁超时设置的时间。这个时间可以通过更改数据库参数 LOCKTIMEOUT。这个值如果是 -1,将永不超时。

最后看看全局锁升级的问题。全局锁升级的原因⼀般是因为全局锁使⽤的内存不够,只能把多个页级别的锁升级为单个

表级别的锁来减少内存开销。所以解决全局锁升级的办法是适当增加 CF ⾥⾯这个内存的⼤⼩。这个⼤⼩由数据库参数

CF_LOCK_SZ 控制。

探讨 DB2 pureScale 集群 Page Reclaiming ⾏为

上⼀章节描述了多个 member 访问同⼀ page 会产⽣锁等待的问题。现在来讨论与此相关的数据库的另外⼀个⾏为 -

Page Reclaiming(数据页回收)。先通过⼀个例⼦来了解 Page Reclaiming 是如何发⽣的:

假设有两个数据库成员 M1 M2M1 M2 想要同时去更⾏相同数据页⾥⾯的两个不同的⾏。

1. M1 正在更新数据页 P1 ⾥⾯的⾏ R1. 它被授以 P1 的独占锁。

2. M2 想要更新 P1 ⾥⾯的⾏ R2。它像 CF 请求相同的数据页 P1 上的独占锁并等待。

3. CF 看到 M1 已经占⽤了这个数据页的独占锁,CF 会向 M1 发送⼀个回收此页的请求。在此期间,M2 ⼀直等待。

4. M1 处理这个数据页回收请求并把数据页写回到 CF GBP 中,然后释放这个数据页。这个时候 M1 仍然占⽤着它原

有的关于这个表的⾏级锁。

5. CF 授权 M2 能使⽤这个数据页。M2 GBP ⾥⾯把这个数据页读到本地并继续处理。

M2 申请数据页到从 GBP 获取到它,这个时间会被计算到应⽤的运⾏时间⾥⾯,也是数据库性能中重要的⼀块。我

们需要监控这种⾏为对性能带来的影响。

监控 Page Reclaiming ⾏为

DB2 提供了 MON_GET_PAGE_ACCESS_INFO 表函数来提取相关的信息。这⾥需要关⼼的是什么表经常发⽣这样的

DB2 提供了 MON_GET_PAGE_ACCESS_INFO 表函数来提取相关的信息。这⾥需要关⼼的是什么表经常发⽣这样的

⾏为,这种⾏为消耗了多少时间。这种⾏为发⽣在哪个数据库成员上。

清单 6. 调⽤ MON_GET_PAGE_ACCESS_INFO 表函数

上述的这个⽅法可以找出数据页回收⽽消耗的时间最多的表。RECLAIM_WAIT_TIME 返回等待的时间,单位是毫秒。

解决 Page Reclaiming 性能问题

Page Reclaiming 其实还是全局锁的问题。解决的思路和前述的解决全局锁问题差不多。对于 Page Reclaiming 的监控

能够更直观的发现时间消耗了多少,从⽽定位系统的性能问题多⼤程度与此相关。

DB2 pureScale 集群环境性能调优总结

我们已经讨论了相对于单节点的数据库,DB2 pureScale 集群环境⾥⾯⽤到的新的技术和事务的处理过程。探讨了这些

新的数据库内容对于性能所带来的影响以及怎么去应对。但是数据库集群的性能问题受多⽅⾯因素影响,⽤户需要不仅

DB2 pureScale 集群环境新的技术⾓度,还是要从系统资源的⾓度,从单数据库节点调优的⾓度去处理数据库的性

能问题。