当前位置: 首页 > > IBM > IBM软件 > WebSphere Message Broker和IBM Integration Bus中ESQL共享变量的使用

WebSphere Message Broker和IBM Integration Bus中ESQL共享变量的使用

2014-07-11 10:03 来源:IBM 作者:Tim Dunn 人气指数: 我要评论
本文介绍一种构建缓存的新方式,这种缓存能有效地扩展,甚至在缓存大小超过 10,000 行时仍比访问数据库更快。新的缓存结构对应用程序透明,所以您可安全地转换现有的缓存,并且显著减少响应时间和 CPU 使用量。ESQL 是 WebSphere® Message Broker 和 IBM® Integration Bus 定义的一种 SQL 扩展,用于定义和处理消息流中的数据。ESQL 共享变量常常用于缓存数据库表的内容,共享变量缓存实现为一个包含 SELECT 操作结果的数组,而搜索通过向该数组发出 SELECT 命令来执行。此方法的问题是,ESQL SELECT 操作执行顺序搜索,所以随着缓存增长,搜索会变慢。大多数用户发现,在缓存大小超出几千行时,访问数据库比使用缓存更快。本文介绍一种构建缓存的新方式,这种缓存能有效扩展,而且甚至在大小超过 10,000 行时仍比访问数据库更快。

假如有一个消息流接收包含机场编码(比如 LHR)的消息,并访问一个数据库表来获取相应的城市名称 (London)。每条消息访问一次数据库可能代价很高,所以一种常见的解决方案是在第一次访问时将这个表加载到一个 ESQL ROW 共享变量中,然后搜索该共享变量。 本文首先介绍称为标准缓存 的最常用缓存结构,然后介绍一种称为 ESQL 缓存 的更高效且可扩展的变体,这种缓存利用了 ESQL 访问其变量的方式。

标准缓存

使用 ESQL 共享变量的最常见的缓存实现包含一个共享的 ROW,其中包含对缓存的数据库表执行 SELECT 的结果:

DECLARE CACHE SHARED ROW;

假设您有一个名为 AIRPORTS 的数据库表,它包含 CODE 和 CITY 两列。此代码加载该缓存:

SET CACHE.AIRPORT[] = SELECT A.CODE, A.CITY FROM Database.AIRPORTS AS A;

CACHE 变量的内容如下所示:

CACHE.AIRPORT[1].CODE = AAA
CACHE.AIRPORT[1].CITY = Anaa
CACHE.AIRPORT[2].CODE = AAB
CACHE.AIRPORT[2].CITY = Arrabury
...
CACHE.AIRPORT[4225].CODE = LHR
CACHE.AIRPORT[4225].CITY = London
...
CACHE.AIRPORT[9185].CODE = ZZV
CACHE.AIRPORT[9185].CITY = Zanesville

此函数实现该缓存:

DECLARE CACHE SHARED ROW;
CREATE PROCEDURE getCity_v01 (IN airportCode CHARACTER) RETURNS CHARACTER
BEGIN
 -- v01: "standard" cache
 -- PERFORMANCE TEST ONLY! No ATOMIC blocks.
 -- Do not use if Additional Instances > 0.
 IF CACHE.AIRPORT.CODE IS NULL THEN
 -- load the cache
 SET CACHE.AIRPORT[] = SELECT A.CODE, A.CITY FROM
 Database.AIRPORTS AS A;
 END IF;
 RETURN THE(SELECT ITEM A.CITY FROM CACHE.AIRPORT[] AS A
 WHERE A.CODE = airportCode);
END;

为了保证可读性,显示了没有 ATOMIC 块的缓存加载,此方法仅适用于只有一个线程运行该消息流时。还有其他搜索缓存的方法,比如使用 FOR或 WHILE 循环,但使用 SELECT 是最快的。

使用标准缓存时的性能

此缓存结构的问题在于它无法扩展。一次用户跟踪显示,SELECT 按顺序扫描该表,直至找到满足 WHERE 子句的一行。随着该表不断扩大,搜索会变慢。最终,丢弃缓存而每次都访问数据库的速度更快。

在 Windows 7 64 位版本上使用 IBM Integration Server V9 和一个本地 DB2 V10.1 数据库的度量结果,显示了不断增长的缓存的影响:

图 1. 不同缓存大小每条消息需要的毫秒数(无缓存与标准缓存对比)


点击这里给我发消息

该测试包括发出 10,000 条消息来随机访问缓存中的前 1000、2000、3000(依此类推)行,进而模拟不同的缓存大小。缓存的总大小为 9185 行。该图表显示了处理一条消息所花的时间(以毫秒为单位)。数据库响应时间(大约 0.8 毫秒)是不变的(标签 NO_CACHE)。

在此配置中,至不超过 3000 行时,缓存比数据库更快。对于更大的缓存,缓存比数据库访问更慢。(其他配置的结果将不同,比如远程访问数据库,或者使用内存型数据库。)

ESQL Cache

ESQL Cache 将每个键和值(在我们的示例中为机场编码和城市名称)存储为名称/值对:

CACHE.AAA = Anaa
CACHE.AAB = Arrabury
...
CACHE.LHR = London
...
CACHE.ZZV = Zanesville

没有数组。要返回给定机场编码对应的城市名称,缓存搜索函数只需引用适当的变量:

RETURN CACHE.{airportCode};

以下是实现新缓存结构的函数:

CREATE PROCEDURE getCity_v02 (IN airportCode CHARACTER) RETURNS CHARACTER
BEGIN
   -- v02: "ESQL" cache   
   -- PERFORMANCE TEST ONLY! No ATOMIC blocks. 
   -- Do not use if Additional Instances > 0.
   IF FIELDNAME(CACHE.*[1]) IS NULL THEN
	-- load the cache
	DECLARE TEMPCACHE ROW;
	SET TEMPCACHE.AIRPORT[] = SELECT A.CODE, A.CITY 
    FROM Database.AIRPORTS AS A;
	    FOR cacheline AS TEMPCACHE.AIRPORT[] DO
		CREATE LASTCHILD OF CACHE 	NAME cacheline.CODE 
VALUE cacheline.CITY;
	    END FOR;
   END IF;	
   RETURN CACHE.{airportCode};
END;

要按新结构组织缓存,该函数会导航数据库 SELECT 返回的每一行。在此示例中,每行包含一个机场编码(比如 JFK)和城市 (New York)。这个名称/值对用于向缓存添加一个变量,其中变量名称为编码,它的值为城市 (CACHE.JFK='New York')。

为了保证可读性,显示的缓存加载不包含 ATOMIC 块。上述代码仅适用于没有额外的线程时。以下是填充一个缓存行的语句:

SET CACHE.{cacheline.CODE} = cacheline.CITY;

当且仅当该键(在本例中为 CODE)只有一个实例时,SET 和 CREATE 才等效。在该键存在多个实例时使用 SET,缓存中将只有一个实例(最后一个)。

ESQL Cache 的性能

因为搜索功能直接访问该变量,所以它快得多且能更好地扩展。下面的图表比较了 ESQL Cache 与标准缓存的响应时间。图 2 显示了最多 9000 行的缓存大小的每条消息的毫秒数:

图 2:不同缓存大小每条消息需要的毫秒数(ESQL Cache 与无缓存对比)


WebSphere Message Broker和IBM Integration Bus中ESQL共享变量的使用

对于所有缓存大小,ESQL Cache(每条消息的平均花时为 0.21 毫秒)都比访问数据库快得多。它也比标准缓存快得多,如图 3 中所示:

图 3. 不同缓存大小每条消息需要的毫秒数(ESQL Cache 与标准缓存对比)


WebSphere Message Broker和IBM Integration Bus中ESQL共享变量的使用

对于所有缓存大小,ESQL Cache 都比标准缓存更快。该图表隐藏了每条消息的 ESQL Cache 用时并非真正不变、而在非常缓慢地增长的事实。这一增长在图 4 中的图表中很明显,其中仅显示了 ESQL Cache:

图 4:不同缓存大小每条消息需要的毫秒数(ESQL Cache)


WebSphere Message Broker和IBM Integration Bus中ESQL共享变量的使用

响应时间会从缓存大小为 1000 个条目时的每条消息 0.2 毫秒,增长到缓存大小为 9000 个条目时的每条消息 0.23 毫秒,增幅约为 15%。ESQL Cache 何时变得比数据库访问更慢?尽管作者没有通过实验验证这一点,但线性投影表明,对于所测试的配置,直到 80,000 个条目,ESQL Cache 都仍然比数据库访问更快。

使用多个键

ESQL Cache 可轻松地支持多个键,以满足 SELECT ...WHERE KEY1=value1 AND KEY2=value2 的等效需求。以下是它的结构:

CACHE.aa.aa = xxx
CACHE.aa.bb = yyy
CACHE.xx.yy = zzz

返回一个值:

RETURN CACHE.{key1}.{key2};

ESQL Cache 与 Global Cache 之对比

WebSphere Message Broker V8 引入了 Global Cache。它使用执行组的 JVM 堆来存储数据,提供 Java API 来向缓存存储和从中获取数据。它很容易实现,而且在众多缓存大小上提供了一致的性能。Global Cache 相较 ESQL 共享变量的一个优势是,缓存可在消息流、集成、执行组和集成总线或消息代理之间共享,而 ESQL 共享变量的范围仅限于消息流。图 5 比较了 Global Cache 和 ESQL Cache:

图 5. 不同缓存大小每条消息需要的毫秒数(ESQL Cache 与 Global Cache 对比)


WebSphere Message Broker和IBM Integration Bus中ESQL共享变量的使用

对于所测试的所有缓存大小,ESQL Cache(每条消息 0.21 毫秒)比 Global Cache(平均每条消息 0.43 毫秒)更快。但是,对于更大的大小,Global Cache 将更快。之前使用的同样的线性投影表明,达到大约 40,000 个条目时,ESQL Cache 就会变得比 Global Cache 更慢。

结束语

我们提出的缓存结构会为带 ESQL 共享变量的缓存带来显著的性能改进。实现这种新缓存的逻辑非常简单,所以转换现有的标准缓存结构也很简单。

我们还未度量超过 9000 行的缓存大小,但该趋势表明,包含 80,000 个条目的缓存仍比访问数据库更快。准确的分界点将依赖于您具体的硬件和软件配置,但在任何情况下,ESQL Cache 都在当前几千个条目的分界点基础上带来了显著的改进。

对于更大的缓存大小,可考虑使用 IBM Integration Bus Global Cache,它提供了始终不错的性能且容易实现。如果需要跨消息流、集成、执行组或集成总线/消息代理而共享缓存,那么 Global Cache 是惟一的选择,因为 ESQL 共享变量的范围仅限于消息流。

致谢

感谢来自南非开普敦的 Amanda Erlank 和来自南非 Standard Bank 的 Johannes Wagener 审阅本文的初步草案。

大家感兴趣的内容
小伙伴最爱的新闻
小伙伴还关注了以下信息
小伙伴关注的焦点

小伙伴都在关注的热门词

芈月传 老司机玩法 萌乐网 黑科技 坐骑揭秘 三国令 铁血皇城 竞技场攻略 书剑恩仇录 披风玩法 装备强化攻略 野外BOSS玩法 全网曝光 赤壁传说 半回合制国 ACT 哥们网 天书世界 奇珍商城 热血战歌 传奇宝藏抽奖 门徒 范伟打天下 打开方式 门徒获取玩法 三大萌宠简介 新手攻略 挂机系统简介 材料副本 大海战 鸵鸟 大黑 激情玩法 门徒战力提升 万世 强化属性 上古降魔 提升战力 装备攻略 九阴绝学 品质推荐 老干妈 激战来袭 大黑游戏 新服亮点 福利多多 画江山 资料片 玩家 九阴真经 江湖儿女 真实场景 现实 虚拟 随机副本 风色轨迹 听天由命 ppwan 神助攻 武林秘药 激活八大脉门 九天劫变 猎命格 天问 大型PVP 花千骨 激战更尽兴 网易mumu 手游玩家 安卓模拟器 安卓 单挑群战 武侠传说 女神 孙尚香专访 胸猛抱团 新游 占山为王 跨服城战 蜀山战纪 剑雨江湖 攻略 实时VR交互 七大女神代言 酷炫走江湖 世界四大杀手 玩家专访 三国经典 大制作 好玩网页游戏 盘点 宇宙霸主 境界玩法 莽荒纪 勇闯难关 镜像副本 荒漠霸主 装备精通 三大战役 鹌小彦奇谈