WebSphere Message Broker 全局缓存简介

WebSphere Message Broker V8.0.0.1 中新的全局缓存功能支持在流程和代理之间共享一个内存型缓存。本文将介绍全局缓存,展示如何使用它,并回答一些与之相关的常见问题。

James Hart, 软件开发人员,WebSphere Message Broker 开发团队, IBM

James Hart 的照片James Hart 是英国 Hursley Park 的 IBM 软件实验室的 WebSphere Message Broker 开发团队的一名软件开发人员。他自 1999 年就效力于该团队,担任过各种技术方面的和面对客户的职位,目前他是 WebSphere Message Broker 中的缓存技术的技术领导。



2013 年 3 月 07 日

简介

本文将概述 IBM® WebSphere® Message Broker V8.0.0.1 中新的全局缓存功能。全局缓存使用 WebSphere eXtreme Scale 技术来提供可跨执行组和代理共享的内存型数据缓存。本文有三个小节组成:

编程考虑因素将在未来的文章中介绍。

全局缓存概述

为什么 WebSphere Message Broker 中需要此功能?

一项长期存在的 WebSphere Message Broker 需求是在不同流程之间共享数据的机制。此需求最容易在异步请求/回复场景的上下文中解释。在此类型的场景中,代理充当着一些客户端应用程序与一个后端系统之间的中介。每个客户端应用程序通过代理发送请求消息,这些消息中包含将包含在所有后续回复中的关联信息。代理将消息转发给端系统,然后处理来自系统的响应。要完成往返传递,代理必须将关联信息插入到回复中,并将它们路由回到正确的客户端。

当信息流包含在单个代理中时,有一些存储关联信息的选项可供选择,比如数据库或一个存储队列(以后使用 MQGet 节点来检索信息)。如果需要水平扩展此解决方案并添加代理来应对吞吐量增长,数据库将是惟一合理的选择。

但是,如果只有一个内存型缓存可用于请求和响应消息流,那么无论它们在哪些代理中运行,请求流都可以将关联信息存储在缓存中,而且回复流可以检索(并删除)它。无论回复消息通过与原始请求相同的代理进行路由,还是通过不同的代理进行路由,回复都会到达正确的客户端,如下所示:

具有全局缓存的请求/回复场景
该图显示了 4 个前端客户端通过两个代理发送到一个后端系统请求

其他针对全局缓存的常见场景包括维护一个在执行组或代理之间共享的内存型路由表,或者通过在缓存中保留频繁查询的数据的一个 “门面 (façade)” 来减少后端系统的延迟。

全局缓存的工作原理

WebSphere Message Broker 全局缓存使用嵌入式的 WebSphere eXtreme Scale (WebSphere XS) 技术来实现。通过托管 WebSphere XS 组件,嵌入在 WebSphere Message Broker 执行组的 JVM 可协作提供一个缓存。有关 WebSphere XS 的描述,请参阅 WebSphere XS 信息中心中的 产品概述。以下是 WebSphere XS 拓扑结构中的一些关键组件:

目录服务器
控制数据的布局并监视容器的健康状况。
容器服务器
一个嵌入在执行组中的组件,持有缓存数据的一个子集。在这些服务器之间,全局缓存中的所有容器服务器至少会托管所有缓存数据一次。
映射
一种将键映射到值的数据结构。一种映射是默认映射,但全局缓存可有多种映射。

每个执行组可托管一个 WebSphere XS 目录服务器、容器服务器或二者同时托管。此外,每个执行组可与缓存建立一个客户端连接,以供消息流使用。全局缓存是开箱即用的,可以采用默认设置,不需要进行配置,只需打开它即可!无需与代理一起安装 WebSphere XS,以及其他任何额外的组件或产品。

如何控制缓存的范围?

缓存的默认范围是在一个代理上。要启用此范围,可将 Message Broker Explorer 的 GlobalCache 选项卡上的代理级策略属性切换到 Default 并重新启动。这会导致每个执行组在启动时在缓存中动态地承担一种角色。要启动的第一个执行组是目录服务器和容器服务器,使用来自所提供端口范围(已为您生成了一个端口范围,但您可修改它)的前 4 个端口。有关端口范围的更多细节,请参阅下面的 常见问题。第 2、第 3 和第 4 个执行组(如果存在)将是容器服务器,每个服务器使用来自该范围的 3 个端口。任何超出第 4 个执行组的执行组都不会托管缓存组件,但会作为客户端连接到在执行组 1-4 中托管的缓存。下图显示了一个具有 6 个执行组的单代理缓存的服务器布局和客户端连接:

具有默认策略的单代理缓存
该图显示了一个代理,它有 6 个执行组,共同协作提供一个缓存。

您可以使用一个缓存策略文件将缓存扩展到多个代理。产品安装中包含 3 个示例策略文件,它们位于 sample/globalcache 目录中。简单地修改这些策略文件,就可以包含您希望在单个缓存中协同使用的所有代理,然后将代理级缓存策略属性指向此文件。以下是 Message Broker Explorer 中的这一设置:

在 Message Broker Explorer 中配置一个缓存策略文件
在 Message Broker Explorer 中配置一个缓存策略文件

该文件允许您提名每个代理来托管 0、1 或 2 个目录服务器,以及每个服务器应为它的缓存组件使用的端口范围。下图显示了一个双代理缓存,其中两个代理均被配置为包含目录服务器:

由策略文件控制的双代理缓存
该图显示了两个代理如何协作提供一个缓存,该缓存可供二者使用。

您还可以为每个执行组配置特定的缓存角色,而不是在启动时动态分配它们,方法是将代理缓存策略属性更改为 none,这会启用一组详细的执行组属性。有关的详细信息,请参阅下面的 缓存拓扑结构考虑因素

由于缓存的数据仍然托管在执行组流程内,所以全局缓存比其他缓存更适合某些解决方案。例如,存储短暂的关联信息或路由表显然是该技术的一种不错的用途。使用它作为数据库门面的适用性很大程度上取决于将在缓存中保存的数据量。不推荐在少量执行组的 JVM 堆中托管几 GB 的数据。另一个考虑因素是对 WebSphere XS 的高级功能的需求。如果已确定需要利用 API 而不是简单的 ObjectMap 接口,或者需要自定义底层的 WebSphere XS 网格配置 XML 文件,那么独立一个 WebSphere XS 或 XC10 安装可能更适合。本文不会介绍从 WebSphere Message Broker 到一个远程 WebSphere XS 安装的连接。

如何与缓存进行交互?

消息流开发人员拥有新的、简单的工件来处理全局缓存,而且无法直接了解底层的 WebSphere XS 技术或拓扑结构。具体来讲,Java Compute 节点接口有一个新 MbGlobalMap 对象,它提供了访问全局缓存的能力。此对象处理与全局缓存的客户端的连接,提供多种方法来处理缓存中的映射。可用的方法类似于您在常规 Java 映射上找到的方法。各个 MbGlobalMap 对象是使用 MbGlobalMap 类上的一个静态 getter 方法来创建的,这个类充当着一种工厂机制。您可以同时处理多个 MbGlobalMap 对象,匿名(使用 WebSphere XS 中隐含的预定义的默认映射名称)或使用您选择的任何映射名称来创建它们。在下面的示例中,defaultMap 将使用全局缓存中的系统定义的默认映射。myMap 将使用一个名为 myMap 的映射,如果缓存中不存在此映射,则会创建此映射。

示例 MbGlobalMap 对象
MbGlobalMap defaultMap = MbGlobalMap.getGlobalMap();
MbGlobalMap myMap = MbGlobalMap.getGlobalMap(“myMap”);

如何管理缓存?

要跟踪一个给定执行组与全局缓存的交互,可以使用资源统计数据,以及一个记录目录或容器服务器在该执行组中的启动的活动日志。该日志随后会记录在该执行组内执行的每个 put、get、update、remove 或 containsKey 调用,哪个流和节点执行了调用,使用了哪个映射和键,以及处理中的任何异常的详细信息。下图显示了连接全局缓存、检查一个条目是否存在,然后将一些数据放入缓存中的过程。

示例活动跟踪输出
该图显示了一组与全局缓存的交互相关的活动跟踪条目。

因为资源统计数据和活动跟踪只能提供来自每个执行组的隔离视图,所以还可以使用 mqsicacheadmin 命令,它提供了有关整个全局缓存的信息。它有许多子命令。listHostsshowPlacement 命令可帮助验证您的全局缓存的条件,比如它是否拥有您想要的主机数量,它是否拥有正确的容器数量,以及各个碎片是否均匀地分散在这些容器上。showMapSizes 逐个映射地显示您的全局缓存的总大小,而 clearGrid 支持您从一个特定映射清除数据,在特定映射变得太大而需要擦除数据时,这很有用。

常见问题

问题:一个全局缓存可在多个代理之间共享吗?
答案:可以!尽管默认的缓存策略提供了一个单代理缓存,但可以使用一个缓存策略文件创建一个多代理缓存。产品安装中包含 3 个示例策略文件。只需修改策略文件,使之包含您希望在单个缓存中协调的所有代理,就可以将代理级缓存策略属性指向此文件。该文件支持您提名每个代理托管 0、1 或 2 个目录服务器,以及每个代理应对其缓存组件使用的端口范围。请确保策略文件中每个代理的 listenerHost 属性与该代理的 listenerHost 属性匹配。该属性会与代理名称一起供每个代理用于在策略文件中标识自身。

问题:如果我关闭托管一个目录服务器的一个执行组,会发生什么?
答案:如果它是惟一的目录服务器,那么您的缓存会消失。但是,如果您将缓存配置为拥有多个目录服务器,并且它们在启动时成功地进行了握手,那么剩余的一个(或多个)目录服务器会继续无中断地运行缓存。在重新启动执行组时,该目录服务器将重新加入拓扑结构中。

问题:在多代理缓存汇总,如果我的一个代理失败,那么我的数据会出现什么变化?
答案:只要您在不同机器上运行多个目录服务器,您的数据仍然可以提供给剩余的代理。缓存中的每部分数据拥有一个主要版本(主要片段)和一个副本。如果您在不同机器上拥有多个目录,那么需要确保任何数据部分的副本位于与主要版本不同的机器上。如果托管一些数据的主要片段的代理发生了故障,那么副本碎片会自动变成主要版本,并在其他地方创建一个新副本。这种行为是由 APAR IC88062 启用的,这可保证主要版本和副本碎片位于不同的机器上。在没有此 APAR 的情况下,如果一个代理发生故障,则有可能同时丢失两种碎片。如果只有一个目录服务器,或者只有一个包含目录服务器的主机,那么主要版本和副本碎片可能位于同一个机器上。

问题:是否有一种方法可将缓存配置为在一定时长后数据会过期?
答案:目前,无法在嵌入式缓存中启用过期功能。所有数据的生命周期都必须编码到消息流中。

问题:我能否确保一个特定的执行组始终可以托管一个目录服务器?
答案:可以,通过从一个默认/文件代理策略更改为 none,还可以通过单独设置每个执行组的缓存属性来实现此操作。有关此主题的更多细节,请参阅下面的 缓存拓扑结构考虑因素

问题:我正在我的笔记本电脑上试用全局缓存,但在我的 IP 地址发生更改时遇到了问题。如何解决?
答案:对于单机器拓扑结构,您可以将代理的 listenerHost 属性(位于 Message Broker Explorer 中代理的 GlobalCache 选项卡上)更改为 localhost。如果扩展缓存以涵盖多个机器,localhost 会失效,但它适用于这种简单、面向笔记本电脑的 DHCP 用法。

问题:全局缓存适用于多实例代理吗?
答案:如果一个活动代理发生故障,而且一个备用代理开始在一个不同机器上接管它的工作,那么该代理中的目录和容器将无法启动(因为它们与错误的主机名绑定)。但所有执行组都能够与全局缓存建立客户端连接,假设一个目录仍在另一个代理中运行。则需要对原始的活动代理进行还原,然后该代理中的缓存组件(目录和容器)才能重新启动并重新加入缓存中。

问题:是否有一种方法能将数据持久化到文件系统或数据库中?
答案:目前没有一种对全局缓存这么做的自动方法。

问题:与全局缓存的交互是事务性的吗?
答案:与全局缓存的每次交互实际上是一个事务。WebSphere XS 悲观锁会在每次操作期间使用,控制权仅在操作提交到数据的主要和副本版本后才返还给用户。但全局缓存交互没有与消息流事务集成,所以如果一个消息流在将一些数据放入缓存中后回滚,那么不会删除该数据。在设计消息流时请记住这一事实,尝试尽可能晚地在流程中执行缓存放入、更新和删除操作。产品中的 Coordinated Request Reply 示例演示了这一技术,该示例仅在消息流的 MQOutput 节点成功放入一条消息后才将关联信息存储在缓存中。

问题:全局缓存可从一个 Java Compute 节点外部访问吗?
答案:可以。可以为常见的全局缓存任务(比如从一个给定映射获取一个字符串值)创建静态 Java 包装器。然后可以从 ESQL 和 Mapping 节点内调用这些 Java 方法。使缓存可从各个编程接口本地提供是长期目标。

问题:在使用全局缓存时,执行组流程的大小是否有任何影响?
答案:启用一个目录或容器服务器后,一个执行组内的 JVM 的堆大小将增加至少 30 MB。托管一个缓存组件对执行组内的消息流性能没有影响,但全局缓存中的所有数据都将托管在您的执行组流程中,这些流程的大小也会相应地增加。如果创建持续写入缓存而从不删除数据的流,那么您的流程的大小将持续增长,直到它们导致内存不足错误。您应考虑有多少数据可能放在缓存中,请参阅 WebSphere XS 产品文档,获取 JVM 堆大小设置的指南。

问题:为什么默认的缓存策略不支持多于一个目录服务器?
答案: 尽管推荐运行多个目录服务器,但这会带来一定的开销。当拥有多个目录时,请确保大部分目录几乎同时启动,在缓存可用之前,这些目录有 60-90 秒的时间进行握手。具有一个目录的默认单代理缓存仍将提供跨执行组的数据共享,而且可以快速启动。

问题:如果我修改了缓存策略文件,那么我需要重新启动所有代理吗?
答案:这取决于您修改的内容。如果您添加、删除或修改了托管一个目录服务器的一个代理,那么需要重新启动所有代理。所有目录服务器在启动之前都需要了解彼此,而且不能在其他目录服务器正在运行时动态添加新的目录服务器。但是,如果添加一个步包含目录服务器的代理,那么只需重新启动这一个代理即可。此代理中的容器服务器和客户端连接将使用策略文件中已有的信息来连接到网格,其他组件不需要知道此更改。

问题:为什么需要一个端口范围,这个范围应多大?
答案:缓存中的目录服务器和容器服务器组件都需要一些端口来进行通信。托管目录服务器(或目录和容器)的执行组需要 4 个端口。仅托管容器服务器的执行组需要 3 个端口。单纯用作客户端的执行组不需要任何端口。WebSphere Message Broker 要求您提供至少 20 个端口的端口范围。目前,每个代理实际上最多使用 13 个端口(对于默认缓存策略)或 14 个端口(对于通过策略文件定义的双目录代理)。

问题:是否每个容器都有缓存的完整副本?
答案:否。每个容器都托管缓存中的数据的一个子集。每个数据部分有一个主要副本和一个复制副本。缓存中的 WebSphere XS 组件可确保这些主要副本和复制副本(碎片)分散在可用的容器上。

缓存拓扑结构考虑因素

什么是缓存拓扑结构?

缓存拓扑结构是协作构成一个全局缓存的一组目录服务器、容器和客户端连接。在使用默认策略时,要启动的第一个执行组将承担目录服务器和容器服务器的角色(称为 Role1)。要启动的接下来 3 个执行组承担容器服务器的角色(Role2、3 和 4)。其他任何执行组都不会托管目录或容器,但所有执行组(包括承担 Roles1、2、3 和 4 的执行组)都托管与全局缓存的客户端连接。在重新启动代理时,执行组可按不同的顺序启动,这时不同的执行组可能承担 Roles1、2、3 和 4。缓存拓扑结构仍然包含一个目录服务器、至多 4 个容器和多个客户端,但这些角色在执行组上的分布将不同。

缓存策略文件在这方面有何帮助?

策略文件可用于定义您跨一个或多个代理的缓存拓扑结构的形状。如果创建一个具有两个代理的策略文件,而且其中每个代理托管一个目录服务器,那么您实际上已将两个默认缓存连接在一起。每个代理将拥有上述相同的 Roles1、2、3 和 4,但它们都知道自己是一个多目录缓存的一部分,并会相应地设置它们的属性。

但是,也可以使用策略文件定义具有两个目录服务器的单代理缓存。在这种情况下,上述的 Role2 将成为第二个目录服务器,还有一个容器服务器。

您还可以指定让一个特定的代理应包含 0 个目录服务器,这在分布于多个代理上的缓存中很有用。目录服务器数量是一个小素数时,这会带来最优的可用性和性能。所以在一个分布在 6 个代理上的缓存中,您可能希望其中 3 个代理(举例而言)托管目录。有关何时必须在更改策略文件后重新启动代理的讨论,请参阅上面的 常见问题

何时应使用策略 none 并单独控制每个执行组?

  • 当您希望准确知道每个执行组在拓扑结构中承担何种角色时,而且在代理重新启动时保持此设置不变。
  • 当您大量使用缓存且需要调节 JVM 堆大小,因此需要知道要调节哪些执行组时。
  • 当您希望隔离目录服务器,以便您可单独管理该执行组的生命周期时。
  • 当您大量使用缓存,而且不希望目录服务器与容器共存于一个 JVM 中时,因为目录执行的工作可能影响该容器的性能。
  • 当您希望在一个代理中创建比任何策略选项所提供数量更多的容器服务器或目录服务器时。
  • 当您希望单独配置每个端口,而不让代理从一个范围中挑选端口时。

已将策略设置为 none,接下来做什么?

当选择了代理策略设置 none 时,一组在以前只读的执行组属性将变得可用。这些属性可在 Message Broker Explorer 中执行组的属性的 GlobalCache 选项卡上看到,也可以通过执行组内的 ComIbmCacheManager 资源从命令行看到:

mqsireportproperties <broker> -e <EG> -o ComIbmCacheManager -r

当从一个策略(默认或策略文件)切换到 none 时,由策略动态设置的这些属性的最新值将保留为自定义的起点。对您不希望其托管目录服务器的执行组的属性的自定义相对比较简单:

  • 需要 3 个端口:listenerPort、haManagerPort 和 jmxServicePort。
  • 可禁用 JMX(将 enableJMX 设置为 false),但 mqsicacheadmin 命令仍然无法找到此执行组中的组件。
  • connectionEndPoints 必须设置为一个逗号分隔的目录服务器列表,其中每个目录服务器使用格式 listenerHost:listenerPort 描述。此属性由此执行组中的容器服务器(如果已启用)和客户端连接用于与缓存通信。
  • catalogClusterEndPoints 属性不需要设置。

制定您希望用来托管目录服务器的执行组的属性稍微有点困难。除了上述步骤之外,还必须设置 catalogClusterEndPoints 属性:

  • 每个要托管一个目录服务器的执行组都必须有一个相同的 catalogClusterEndPoints 值。
  • 此属性不仅包含此执行组的目录的详细信息,还包含拓扑结构中其他每个目录服务器的详细信息。
  • 每个端点都具有以下格式:ServerName:listenerHost:CatalogPeerPort:haManagerPort
  • CatalogPeerPort 是第 4 个端口,仅用于目录服务器,而且不会在属性中的其他地方引用。
  • listenerHosthaManagerPort 是在此执行组的属性中指定的相同值。
  • 服务器名称为 BrokerName_listenerHost_listenerPort。下面是一个示例:
    • 您希望这个执行组托管一个目录服务器,而且您将 listenerPort 设置为 2800,将 haManagerPort 设置为 2801,将 jmxServicePort 设置为 2802。
    • 您希望第 4 个端口 (CatalogPeerPort) 被设置为 2803。
    • 代理名为 MB8BROKER。
    • listenerHost 被设置为 mybrokerbox
    • 此目录服务器的 catalogClusterEndPoint 将是 MB8BROKER_mybrokerbox_2800:mybrokerbox:2803:2801
    • 此执行组的 catalogClusterEndPoints 需要设置为上述端点和所有其他目录服务器的一个逗号分隔列表。

由于设置目录服务器属性的复杂性,以下是设置各个执行组属性的一些备用方法:

  • 首先从一个缓存策略开始。基于您希望执行组承担角色,按照正确的顺序调出它们。切换到 none,以便固定这些角色。然后还可以修改设置,无需从头设计它们(例如,将 enableContainerService 切换为 false,以实现一个隔离的目录服务器)。
  • 再次申明,要从一个缓存策略开始。基于上面关于拓扑结构中的角色的讨论,您可考虑让每一组执行组属性构成一个角色定义,该定义并没有与任何执行组紧密关联。使用 mqsireportproperties 创建这些角色定义的一个快照。现在可切换到 none,并使用 mqsichangeproperties 将这些角色分配给特定的执行组。例如,在默认策略下 EG1 可承担 Role1,但您实际上想让一个名为 CATCONT1 的专用执行组来承担该角色。您可以报告 EG1 的属性,并使用这些准确的值来设置 CATCONT1。如果使用此方法,请确保反复检查了 EG1 的属性,以确保它现在拥有正确的角色(即使这仅涉及到将 enableCatalogServiceenableContainerService 设置为 false)。

参考资料

学习

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


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


忘记密码?
更改您的密码

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

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

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

选择您的昵称



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

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

标有星(*)号的字段是必填字段。

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

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

 


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


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=860827
ArticleTitle=WebSphere Message Broker 全局缓存简介
publish-date=03072013