简介: 在一些大型系统当中,有时我们会考虑对系统资源和负载进行管理。DB2 V9.5 当中提供了一个全新的工具 Workload management(WLM),而 DB2 的 WLM 的功能却缺少了一个重要的一点,对 CPU 资源进行限制,而这一点在实际的案例当中往往是受到重视的。可见仅仅是 DB2 的工作负载管理( WLM )功能还无法给客户在这方面一个完整的解决方案。而这篇文章主要是通过实践告诉读者,在实际场景当中我们能够如何结合 DB2 与 AIX 操作系统的 WLM 给出一个完整的解决方案,并希望以此带给读者一个真正入门的台阶。
<!--DB2 在资源负载管理方面,过去我们有 Governor 和 Query Patroller(QP),在 DB2 9.5 版本当中推出了工作负载管理 (Workload Management) 这个工具,以整合和替代过去的功能。由于本文重点在于实践,对于 DB2 WLM 的基本功能和相关概念就不再阐述。所以也希望读者在通读本文之前对于 DB2 WLM 的基本概念有一定的认识,如果读者想要补充学习 DB2 WLM 的基础知识可参考 DeveloperWorks 中 《DB2 V9.5 工作负载管理》一文。
在实际的场景当中,如果要确定一个方案,我们很关心 DB2 WLM 到底能够针对哪些资源,或者说是哪些对象进行管理和限制。我们这里简要列举一下 DB2 WLM 可以使用的阀值 (Threshold):
- estimatedsqlcost(timerons)
- sqlrowsreturned
- sqltempspace(KB、MB、GB)
- activitytotaltime(天、小时或分)
- connectionidletime(天、小时或分)
- concurrentworkloadoccurrences
- concurrentdbcoordactivities | and queuedactivities
- concurrentworkloadactivities | and queuedactivities
- totaldbpartitionconnections | and queuedconnections
- totalscpartitionconnections | and queuedconnections
这里我们可以看到 DB2 WLM 的阀值当中没有操作系统资源的相关内容。当然我们可以在创建 Service Class 的时候指定代理程序的优先级。可是优先级往往不是客户所需要的,而且我们有理由相信 10 个最低优先级的代理程序是能够比 1 个高优先级的代理程序获得更多的资源,也就是说无法通过优先级来确切地保证某些应用或者用户不会使用超过给定量的资源。
在实际场景当中,我们常常会想到,我要限制某个次要应用用户的 CPU 资源的使用率在 10% 以下,以免影响主营业务应用的高效运作。或者说某个系统有 3 个应用,我们根据这这 3 个应用的负载特征和重要程度定义 application1 占用 50%CPU 资源,application2 使用 30%CPU 资源,application3 使用 20% 的 CPU 资源。类似的需求还是很常见的,那么这里我们就需要用到 AIX 的 WLM 来实现。既然要用 AIX WLM,就得先来补充点相关的知识。
AIX WLM 主要是对操作系统的 CPU、物理内存和 I/O 资源进行管理,我们可以设定相关资源的最大值、最小值或者按照百分比进行分配。AIX WLM 与 DB2 WLM 的架构有点类似,也是通过服务类 (Service Class) 来分类管理的,同样也是两个层次:服务父类 (superclass) 和服务子类 (subclass)。服务类的资源管理和分配主要有以下两种方式:
在共享方式中我们需要定义每个服务类的资源占用比例。通过举例子来解释的话非常好理解,假设我们有 A、B、C 三个服务类,我们分别定义其 CPU 资源的为 50、30、20(注意,这里并不是百分比,这里可以使用的值范围是 1 ~ 65536)。
那么这时 A、B、C 可以使用的 CPU 比例为 50%、30%、20%。假如:
- 如果此时 C 处于非激活状态的话,那么 A 可以使用 CPU 比例为 (50/(50+30)) × 100% = 62.5%
- 如果我们添加一个新的服务类 D,share 值为 100,那么 A 可以使用的 CPU 资源为 (50/(50+30+20+100)) × 100% = 25%
在这里我们需要注意每个服务类的层次,因为服务父类和子类会影响到分配的范围和比例。
通过 limits 方式我们可以为服务类指定的限制有资源的最小和最大的百分比。具体的设置有:
- min
分配给某个服务类的最小资源百分比。缺省值为 0。
- softmax
在有冲突的情况下(这里可以理解为资源紧张时),服务类可获得的最少资源比例。在没有冲突的情况下,服务类可获得的资源可以超过该值设定的比例。缺省值 100。
- hardmax
在没有冲突的情况下,服务类可获得的最大资源比例。缺省值为 100。
使用限制的时候需要注意以下规则:
- 最小值必须小于等于最大值
- 在同一层级同一个作用范围内的所有服务类的最小值之和不能超过 100
- 同一服务类的 softmax 必须小于等于 hardmax
好了,上面我们稍稍对 AIX 的 WLM 做了下简单的介绍。那么,现在我们来看看以上两者结合使用话又是如何工作的。
两个 WLM 结合使用,关键就是要将 DB2 WLM 中的服务类与 AIX WLM 定义的服务类一个一个地关联起来,这里我们称之为映射 (Mapping)。这样在创建 DB2 WLM 的服务类的时候需要使用 OUTBOUND CORRELATOR 选项来指定关联名称。使用 DB2 WLM 将用户或者程序名字定义成服务类,然后将 DB2 WLM 的服务类与 AIX WLM 的服务类通过 Outbound Correlator 相关联,这就实现了对某个用户或者应用程序限制 CPU 的功能了。
图 -1 当中很清晰地看到,我们将 DB2 当中的父类对 AIX 的父类,DB2 中的子类对 AIX 当中的子类进行一对一的映射。
图 1. 一对一的全映射
![图 1. 一对一的全映射](http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1009huangxt/f1.gif)
在图 -2 当中,是在一台主机上存在多个数据库,而这里我们仅仅对 DB2 和 AIX 的父类进行了映射。
图 2. 对父类进行映射
![图 2. 对父类进行映射](http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1009huangxt/f2.gif)
在图 -3 中,也是多个数据库的情况,这里我们则是实现了子类的映射。
图 3. 对子类进行映射
![图 3. 对子类进行映射](http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1009huangxt/f3.gif)
其实 DB2 与 AIX 的服务类的映射可以是非常灵活的,并没有太多限制。最关键的是,设计者必须非常清楚每个服务类所能够分到的实际资源比例。因为我们是通过父类和子类来控制资源分配比例的作用范围的,所以,从 AIX 的作用域映射到 DB2 以后,其实际的作用域我们必须非常清晰。
这里有几点我们是必须要知道的。首先,在 DB2 WLM 与 AIX WLM 两者相结合的情况下,在 AIX WLM 当中我们只能够对 CPU 资源进行管理。因为,说到内存方面,在 DB2 数据库当中有专门属于某个代理(agent)的私有内存(如 statement heap),同时也存在大量的各种共享内存区,比如缓冲池 (buffer pool),所以我们很难确定某个代理程序到底使用了多少内存。I/O 也一样,一个代理程序要完成某条 SQL 指令,会导致许多其它的进程动作,比如预取进程 (prefetcher)、日志写进程 (log writer) 等等。因此只能对 CPU 资源进行管理,不必遗憾,其实完全足够了。
另外,DB2 WLM 不支持 AIX WLM 的继承(inheritance)特性。因为一旦启用了继承特性,所有的子线程或者进程都会继承成为其父线程或进程的属性。这样就导致了 DB2 WLM 当中的用标识定义的服务类失效。缺省情况下 AIX WLM 的继承特性是启用的,所以我们需要显示地禁用。
最后还有一点要知道的是,一旦使用 AIX WLM 来管理 CPU 资源,那么在 DB2 WLM 当中创建服务类的时候就不能设定其进程的优先级。既没有这个必要,在语法上也不允许。
到目前为止,我们已经初步了解了 DB2 WLM、AIX WLM 以及两者协作的原理。那么接下来我们通过一个实际案例来带大家看看我们是如何实现负载管理的目标的。
这个例子虽然比较简单,但具有一定的代表性,所以比较适合入门。
客户告诉我,他们有一个系统 A 需要开放一个只读用户给另一个系统 B 查数据,但他们希望这个只读用户的任何操作不能影响该系统的主营业务性能。这里我们稍微整理一下需求:
- 在系统 A 数据库开放一个用户 testusr 给系统 B 使用;
- 限制用户 testusr 只能读取数据;
- testusr 用户的访问不能占用过多性能影响主业务;
- 除 testusr 用户以外以他用户和程序不受限。
其实我们发现很多时候客户的需求是有些笼统的,这就需要我们来具体化。上面的四条也还是不够详细,我们接下来结合具体技术来逐步分析。
一个只读的 testusr 用户,这很简单,用权限去解决就好了。testusr 用户的访问不能影响主业务,这就比较笼统了,这需要我们更多地了解客户的实际需求,并转换为技术上很具体的东西。首先这里很容易想到使用 AIX WLM 来限制 CPU 资源,这里要注意 testusr 以外的用户是不受限的,那么我们为了简化而选择了 limits 方式没有选择 shares,原因是 shares 方式需要定义所有用户的资源分配。
CPU 资源限制了,testusr 就一定不会影响主业务了么?当然不是,还有很多方法可以占用较少 CPU 但是却能够极大程度地影响总体性能的方法 ( 或者说 SQL 语句 ),比如把磁盘带宽占光。所以这里我们通过了几个方面来进一步限制。首先是限制并发连接数,不过 DB2 WLM 不能直接限制连接数,这点要通过 Query Patroller 这个组件来实现,这里我觉得没有必要把这个简单场景的方案搞得这么复杂,所以我们退而求次选择了限制并发的活动协调代理数(CONCURRENTDBCOORDACTIVITIES)。这就是说我们允许有很大量的 testusr 用户并发连接到数据库,但是能够同时运行 SQL 命令的只有有限的数量。作为补充,我们配合的加上一个限制会话的空闲等待时间(CONNECTIONIDLETIME),这样就可以防止有过多的闲置会话浪费资源了。
对于资源占用有很重要的一点,我们知道,大多情况下很耗资源的 SQL 语句往往都是连接和排序导致的,而这两个操作都是需要用到排序区和临时表空间。那好,我们这里再加上一项临时空间的使用限制(SQLTEMPSPACE)。
将以上内容整理一下:
- 使用数据库权限管理限制用户只能查询(这点不属于 WLM 范围所以在本文后续内容将略去);
- 使用 AIX WLM 的 limits 方式限制 testusr 用户总体工作负载的总体 CPU 使用率;
- 使用 DB2 WLM CONCURRENTDBCOORDACTIVITIES 阀值控制 testusr 用户并发 SQL 语句的执行数量;
- 使用 DB2 WLM CONNECTIONIDLETIME 限制 testusr 用户会话活动之间允许的闲置时间。
- 使用 DB2 WLM SQLTEMPSPACE 限制 testusr 用户能够使用临时表空间的容量。
客户可能会问到:DB2 WLM 不是有一个阀值 ESTIMATEDSQLCOST 是限制开销的么,为什么不用这个?这里就要注意了,这个阀值的单位是 timerons,这个单位综合考虑了 CPU、I/O 等各项资源的一个总体分值。在这里的需求调查当中我们了解到,是允许 testusr 对一张大表做全表扫描的,我们知道如果只是单纯地对一张巨型的表扫描其实对整体影响并不是很大(如果磁盘配置合理的话),但是 timerons 根据表的大小它的值是可大可小的。所以对于这个阀值我个人的建议是要根据应用类型来区分,OLTP 的应用可能更容易确定其范围。
1. 首先创建 DB2 WLM 的服务父类,这里要使用 outbound correlator
db2 => create service class sc_test outbound correlator '_ScTest'; |
2. 创建 workload
db2 => create workload wl_test session_user ('TESTUSR') service class sc_test; db2 => grant usage on workload wl_test to public; |
3. 创建服务子类
db2 => create service class sc_test_queries under sc_test; |
4. 创建工作类集
db2 => create work class set wcs_queries db2 (cont.) => (work class wc_read work type read); |
5. 创建工作动作集
db2 => create work action set was_queries for service class sc_test db2 (cont.) => using work class set wcs_queries db2 (cont.) => (work action wa_read on work class wc_read db2 (cont.) => map activity to sc_test_queries); |
注意,由于我们这个例子比较的简单,所以这里定义的 work class set 和 work action set 也非常简单,在一些复杂场景当中可能会是很复杂的,切不可生搬硬套。
6. 创建各项阀值
db2 => create threshold th_conn for service class sc_test db2 (cont.) => ACTIVITIES ENFORCEMENT database db2 (cont.) => when CONCURRENTDBCOORDACTIVITIES > 2 stop execution; db2 => create threshold th_conn_idle for service class sc_test db2 (cont.) => ACTIVITIES ENFORCEMENT database db2 (cont.) => when CONNECTIONIDLETIME > 5 minutes stop execution; db2 => create threshold th_queries_tmp for database db2 (cont.) => ACTIVITIES ENFORCEMENT database partition db2 (cont.) => when SQLTEMPSPACE > 10 M stop execution; |
注意,我们这里定义的阀值仅仅只是为了测试所以都比较小,不能供生产环境作为参考。另外提醒一点,定义阀值的时候,我们需要注意每一个阀值的定义域(definition domain)和执行范围(enforcement scope)。由于篇幅原因,本文不再详细列举每个阀值的详解。
7. 现在开始的步骤是配置 AIX WLM,需要以 root 权限操作。由于 AIX 的 WLM 需要一整套配置文件,为了简便我们直接将其自带的模板拿来用。
# cd /etc/wlm # cp -r template inventory # wlmcntrl – d inventory |
这样 aix 的 wlm 就启动了,只是没有任何配置。
8. 创建 AIX WLM 的服务类。
# mkclass -a inheritance=no -c hardmax='10' aixscquery # lsclass -f -r System: memorymin = 1 Default: Shared: aixscquery: inheritance = "no" CPUhardmax = 10 |
这里我们设定了 testusr 用户仅仅能够使用 CPU 的 10%,而且是硬限制。这里我们
9. 配置 AIX WLM 的映射
# cd /etc/wlm/inventory # vi rules |
在文件尾加入
aixscquery - - - - - _ScTest |
10. 将 WLM 重启一下
# wlmcntrl -o # wlmcntrl – a |
11. 实施完成。
CPU 资源
这里是要检验 AIX WLM 能否作用在 DB2 的用户连接上面,首先要检查服务类的映射是否成功,让 testusr 用户连接上来随便做一个查询操作,然后查看 db2sysc 进程的线程信息:
# ps -m -o THREAD,class -p 254084|awk '{print $1" "$2" "$3" "$4" "$13" "$14}' |
图 4. 查看 db2sysc 进程的线程信息
![图 4. 查看 db2sysc 进程的线程信息](http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1009huangxt/r1.gif)
这里我们可以看到两个 WLM 的服务类的映射已经成功。
接下来检验 CPU 资源限制是否成功,使用 testusr 用户运行比较消耗 CPU 的命令,不管启动多少个并发(当然在这里由于我们的阀值限制了只能同时运行两个并发),CPU 始终维持在 10% 一下。
图 5. CPU 使用情况
![图 5. CPU 使用情况](http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1009huangxt/r2.gif)
(查看大图)
注意,这个测试过程当中没有其它任何负载,我们可以看到 db2sysc 进程占用的 CPU 资源也基本不超过 10%。
好了,CPU 方面已经测试通过,接下来该看看 DB2 WLM 的阀值效果了。
并发活动工作
由于这里不限制连接数,我们这里首先用 testusr 用户建立了三个会话,然后逐一运行一个比较长时间的 SQL 命令,到第三个运行时返回 SQL4712N 错误:
SQL4712N The threshold "TH_CONN" has been exceeded. Reason code = "6". SQLSTATE=5U026 |
闲置时间
闲置时间的最小颗粒是 5 分钟,如果设置的值不是 5 分钟的整数倍的话会自动选择一个最接近的 5 分钟的整数倍。当闲置时间超过 5 分钟,再次运行命令的话:
SQL1224N The database manager is not able to accept new requests, has terminated all requests in progress, or has terminated your particular request due to an error or a force interrupt. SQLSTATE=55032 |
排序空间
在运行一个少量数据的排序的话是没有问题的,但是排序空间一旦超过 10MB 的话便会报错(这里将数据删掉了)。
$ db2 "select * from db2inst1.testab order by dept,id fetch first 10 rows only" ID NAME DESC DEPT --------- ----------- ----------- -------- ... ... ... ... 10 record(s) selected. $ db2 "select * from db2inst1.testab order by dept,id" ID NAMEDESCDEPT ----- -------- ---------- ------ SQL4712N The threshold "TH_QUERIES_TMP" has been exceeded. Reason code = "10". SQLSTATE=5U026 |
总体来看,将 DB2 WLM 和 AIX WLM 结合起来以后,基本上可以满足在工作负载管理方面的绝大部分的需求。而且从效果上来说的话确实能够达到我们的要求。
原文链接:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1009huangxt/index.html
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15082138/viewspace-675099/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15082138/viewspace-675099/