XQuery/eXist 複製
本檔案已過時,應更新或刪除。
請檢視 GitHub 上的頁面以獲取最新資訊。
您希望配置兩個或多個 eXist 例項,以便它們協同工作,自動同步特定於集合的資料集。這使您可以擴充套件 eXist 伺服器的容量。例如,透過配置多個 eXist 伺服器以同步,如以下所述,您可以新增負載均衡器以在伺服器池中分配傳入查詢的負載,同時仍保持高效能。
我們將使用 eXist-db 2.1dev(最新版本)開發版中獨有的新 eXist 叢集選項。此功能基於使用集合觸發器來觸發來自主伺服器到一個或多個遠端主機上的從系統的“更新”訊息。
注意:此頁面正在開發中。
從長遠來看,eXist 集群系統可能會有很多不同的配置方式。在本教程中,我們將僅介紹從單個主伺服器到多個從系統的基於集合的複製。下圖描述了此複製配置中節點之間的關係。

我們將在此檔案中使用以下術語
- 主伺服器 - 特別配置的 eXist 例項,在該例項中對文件和集合進行活動更改。例如,XML 更新、文件正在儲存、更新或刪除。主伺服器被認為是更改事件的“釋出者”。這也必須是執行 ActiveMQ 伺服器的伺服器。
- 從伺服器 - 一組一個或多個特別配置的 eXist 例項,當主伺服器發生更改時,它們會自動接收更新。每個從伺服器被認為是主伺服器上更改事件的“訂閱者”。
- 訊息儲存 - 主伺服器 eXist 例項外部的位置,用於儲存所有更新事件,並在遠端系統準備好接收更新事件時將這些事件轉發到遠端系統。儘管在我們的例子中經常使用術語“訊息佇列”,但我們將使用“主題”,而不是“佇列”,來將訊息分發到遠端系統。ActiveMQ 在主伺服器上提供此功能。
當配置的集合上的任何文件發生更改時,更新將被放置到訊息佇列中。更新將保留在該訊息佇列中,直到所有訂閱者都收到更新訊息。
注意:需要與開發人員確認:任何系統上的任何集合都可以被配置為主伺服器或從伺服器,以其他系統上的其他集合。
注意:一旦“持久”訊息實現,從系統就不需要在更改時執行。當從伺服器關閉時,它會自動收到自上次與主伺服器通訊以來的所有更改通知。

叢集複製配置使用基於 Java 訊息系統標準 (JMS) 的標準相容訊息系統。eXist 使用的實現基於 Apache ActiveMQ 系統。ActiveMQ 廣泛用作“中介軟體”來幫助應用程式以可靠的方式進行通訊。
- 從 http://activemq.apache.org/download.html 下載 ActiveMQ 的最新版本。請注意,TGZ 檔案具有額外的 Unix(Linux、Mac OS X)支援,ZIP 檔案適用於 Windows。
- 將內容解壓縮到磁碟,稱為 $ACTIVEMQ_HOME
- 將 $ACTIVEMQ_HOME/activemq-all-X.Y.Z.jar 檔案複製到 $EXIST_HOME/lib/user
為了測試,我使用了 activemq-all-5.6.0.jar。
注意:叢集的當前工作是在 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://:61616"/>
<parameter name="connectionfactory" value="ConnectionFactory"/>
<parameter name="destination" value="dynamicTopics/eXistdb"/>
<parameter name="client-id" value="id1"/>
</trigger>
</triggers>
</collection>
在下面的示例中,集合名為“mycollection”

對於每個“從伺服器”,必須透過 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://: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 伺服器
cd ACTIVEMQ_HOME ./bin/activemq start (for mac, use the bin/macosx wrapper)
在每個從伺服器上啟動 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)
當使用動態主題或動態佇列時,您可以透過訪問 https://: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 系統只需要將更新事件放置在訊息佇列上,因此您可以自由地使用各種配置的訊息儲存來將資料和程式分發到具有不同可靠性級別的遠端站點。
建立訊息佇列有兩種選擇
- 靜態 您可以在 ActiveMQ 的配置檔案中定義必須建立的主題或佇列
- 動態 佇列可以在您第一次使用它們時建立
- Subversion 中的金鑰叢集自述檔案
- Apache Active MQ - 叢集工具使用的 Apache ActiveMQ 軟體的主頁
- ActiveMQ In Action - 使用 ActiveMQ 的良好概述書籍