跳转到内容

XQuery/eXist 复制

来自维基教科书,为开放世界提供开放书籍

本文件已过时,应更新或删除。

请查看 GitHub 上的页面以获取最新信息。


您希望配置两个或多个 eXist 实例,以便它们协同工作,自动同步特定于集合的数据集。这使您可以扩展 eXist 服务器的容量。例如,通过配置多个 eXist 服务器以同步,如以下所述,您可以添加负载均衡器以在服务器池中分配传入查询的负载,同时仍保持高性能。

我们将使用 eXist-db 2.1dev(最新版本)开发版中独有的新 eXist 集群选项。此功能基于使用集合触发器来触发来自主服务器到一个或多个远程主机上的从系统的“更新”消息。

注意:此页面正在开发中。

从长远来看,eXist 集群系统可能会有很多不同的配置方式。在本教程中,我们将仅介绍从单个主服务器到多个从系统的基于集合的复制。下图描述了此复制配置中节点之间的关系。

我们将在此文件中使用以下术语

  • 主服务器 - 特别配置的 eXist 实例,在该实例中对文档和集合进行活动更改。例如,XML 更新、文档正在存储、更新或删除。主服务器被认为是更改事件的“发布者”。这也必须是运行 ActiveMQ 服务器的服务器。
  • 从服务器 - 一组一个或多个特别配置的 eXist 实例,当主服务器发生更改时,它们会自动接收更新。每个从服务器被认为是主服务器上更改事件的“订阅者”。
  • 消息存储 - 主服务器 eXist 实例外部的位置,用于存储所有更新事件,并在远程系统准备好接收更新事件时将这些事件转发到远程系统。尽管在我们的例子中经常使用术语“消息队列”,但我们将使用“主题”,而不是“队列”,来将消息分发到远程系统。ActiveMQ 在主服务器上提供此功能。

当配置的集合上的任何文档发生更改时,更新将被放置到消息队列中。更新将保留在该消息队列中,直到所有订阅者都收到更新消息。

注意:需要与开发人员确认:任何系统上的任何集合都可以被配置为主服务器或从服务器,以其他系统上的其他集合。

注意:一旦“持久”消息实现,从系统就不需要在更改时运行。当从服务器关闭时,它会自动收到自上次与主服务器通信以来的所有更改通知。

复制工作原理

[编辑 | 编辑源代码]

集群复制配置使用基于 Java 消息系统标准 (JMS) 的标准兼容消息系统。eXist 使用的实现基于 Apache ActiveMQ 系统。ActiveMQ 广泛用作“中间件”来帮助应用程序以可靠的方式进行通信。

配置步骤

[编辑 | 编辑源代码]

下载和配置 Apache ActiveMQ

[编辑 | 编辑源代码]

  1. https://activemq.apache.ac.cn/download.html 下载 ActiveMQ 的最新版本。请注意,TGZ 文件具有额外的 Unix(Linux、Mac OS X)支持,ZIP 文件适用于 Windows。
  2. 将内容解压缩到磁盘,称为 $ACTIVEMQ_HOME
  3. 将 $ACTIVEMQ_HOME/activemq-all-X.Y.Z.jar 文件复制到 $EXIST_HOME/lib/user

为了测试,我使用了 activemq-all-5.6.0.jar。

创建带有集群配置的 eXist

[编辑 | 编辑源代码]

注意:集群的当前工作是在 eXist-db 子版本库的分支中完成的。要构建此分支,请使用子版本客户端检出以下 URL

  https://exist.svn.sourceforge.net/svnroot/exist/branches/dizzzz/clustering

此代码将在将来某个时间点移入主干。

请注意,extensions/local.properties 中包含以下行,该行尚未在主干中

  # Clustering extenstion for reliable document replication
  include.feature.clustering = true

然后,您可以使用 $EXIST_HOME/build.sh 或 build.bat 构建 eXist。

构建完成后,您将看到以下文件

 $EXIST_HOME/lib/extensions/exist-clustering.jar

配置主服务器

[编辑 | 编辑源代码]

为必须分发其内容的目录添加一个 collection.xconf 文件,例如,对于 /db/mycollection/,.xconf 文件必须存储在 /db/system/config/db/mycollection/ 中。

创建集合 '/db/mycollection'

填写 activemq 消息代理的主机名(此处为“server.local:61616”)。

文件:/db/system/config/db/mycollection/collection.xconf

  <collection xmlns="http://exist-db.org/collection-config/1.0">
    <triggers>
      <trigger class="org.exist.replication.jms.publish.ReplicationTrigger">
      <parameter name="java.naming.factory.initial" value="org.apache.activemq.jndi.ActiveMQInitialContextFactory"/>
      <parameter name="java.naming.provider.url" value="tcp://127.0.0.1:61616"/>
      <parameter name="connectionfactory" value="ConnectionFactory"/>
      <parameter name="destination" value="dynamicTopics/eXistdb"/>
      <parameter name="client-id" value="id1"/>
    </trigger>
</triggers>
</collection>

在下面的示例中,集合名为“mycollection”

Location of collection trigger configuration
集合触发器配置的位置

配置从服务器

[编辑 | 编辑源代码]

对于每个“从服务器”,必须通过 conf.xml 启动作业;作业名称必须与“主服务器”配置的作业名称匹配

<!--
Start JMS listener for clustering feature. 
   Parameters:
      java.naming.factory.initial  Initial context provider
      java.naming.provider.url     URL of message broker
      connectionfactory            Name of connection factory
      destination                  Name of destination (Topic or Queue)
      client.id                    (optional) ClientID. Leave out or set ""
                                             for default behaviour
-->
<job type="startup" name="clustering"  class="org.exist.replication.jms.subscribe.MessageReceiverJob">
        <parameter name="java.naming.factory.initial" value="org.apache.activemq.jndi.ActiveMQInitialContextFactory"/>
        <parameter name="java.naming.provider.url" value="tcp://127.0.0.1:61616"/>
        <parameter name="connectionfactory" value="ConnectionFactory"/>
        <parameter name="destination" value="dynamicTopics/eXistdb"/>
        <parameter name="client-id" value="id2"/>
        <parameter name="subscriber-name" value="sub_name"/>
</job>

启动服务器

[编辑 | 编辑源代码]

启动 ActiveMQ 服务器

[编辑 | 编辑源代码]

启动 ActiveMQ 服务器

   cd ACTIVEMQ_HOME
   ./bin/activemq start 
   (for mac, use the bin/macosx wrapper)

在从服务器和主服务器上启动 eXist-db 服务器

[编辑 | 编辑源代码]

在每个从服务器上启动 eXist,并创建将镜像从服务器的集合

   cd EXISTSLAVE_HOME
   ./bin/startup.sh
   Create receive collection '/db/mycollection'

启动主服务器

   cd EXISTMASTER_HOME
   ./bin/startup.sh
   (No need to create the collection, since we already created above)

测试文档分发

[编辑 | 编辑源代码]

ActiveMQ 队列

[编辑 | 编辑源代码]

当使用动态主题或动态队列时,您可以通过访问 https://127.0.0.1:8161/admin/topics.jsp 来查看主服务器或从服务器是否已检查队列。请记得使用 F5 键刷新页面。

在“主服务器”上,在 /db/mycollection/ 中创建文档(例如,使用 Java 客户端或 eXide;以管理员身份登录)。该文档将自动复制到系统中的所有从服务器。

使用 eXide,我们可以将一个约 50k 的 XML 文档上传到从服务器,例如,/db/mydoc.xml。然后,当我们执行以下查询时,服务器上将创建 2000 个文件(mydoc1000.xml 到 mydoc3000.xml),并复制到从服务器。

 let $doc := doc('/db/mydoc.xml')
 for $i in (1000 to 3000)
 return
   xmldb:store('/db/mycollection', concat('mydoc', $i , ".xml"), $doc)

调试技巧

[编辑 | 编辑源代码]

将 Log4j 系统配置为调试模式。

在主服务器系统上,您应该看到以下行

 2012-06-19 13:26:43,406 [eXistThread-90] DEBUG (Collection.java [storeXMLInternal]:1339) - document stored. 
 2012-06-19 13:26:43,406 [eXistThread-90] DEBUG (ClusterTrigger.java [afterCreateDocument]:63) - /db/mycollection/mydoc1000.xml 
 2012-06-19 13:26:43,406 [eXistThread-90] DEBUG (NativeSerializer.java [serializeToReceiver]:112) - serializing document 1430 (/db/mycollection/mydoc1000.xml) to SAX took 0 msec 
 2012-06-19 13:26:43,419 [eXistThread-90] DEBUG (JMSMessageSender.java [sendMessage]:156) - Message sent with id: ID:Dan-PC12-51166-1340109804913-3:1:1:1:1 


在从服务器系统上,您应该看到以下内容

 2012-06-19 13:48:05,875 [DefaultQuartzScheduler_Worker-2] DEBUG (NotificationService.java [debug]:94) - Registered UpdateListeners: 
 2012-06-19 13:50:06,218 [ActiveMQ Session Task-1] DEBUG (eXistJMSListener.java [onMessage]:138) - CREATE_UPDATE : DOCUMENT from /db/mycollection/mydoc1000.xml
 2012-06-19 13:50:06,234 [ActiveMQ Session Task-1] DEBUG (ConfigurationHelper.java [getExistHome]:55) - Got eXist home from broker: C:\ws\exist-trunk\eXist

其他配置

[编辑 | 编辑源代码]

由于消息传递是一种在计算机系统之间进行通信的通用方法,因此可以通过这种第一个示例的变体来解决许多其他可能的业务问题。复制不仅可以提高可靠性,而且还可以与负载平衡和自动扩展一起使用,在系统负载过重时提高性能。

消息还可以用于将查询分配到多个节点,每个节点都有自己的数据集合。查询结果被放置在结果队列中,并返回给用户,就好像他们正在使用单个非常快的服务器一样。

由于主 eXist 系统只需要将更新事件放置在消息队列上,因此您可以自由地使用各种配置的消息存储来将数据和程序分发到具有不同可靠性级别的远程站点。

静态或动态队列

[编辑 | 编辑源代码]

创建消息队列有两种选择

  1. 静态 您可以在 ActiveMQ 的配置文件中定义必须创建的主题或队列
  2. 动态 队列可以在您第一次使用它们时创建

参考资料

[编辑 | 编辑源代码]
华夏公益教科书