Skip to content
Dannes Wessels edited this page Nov 18, 2016 · 22 revisions

Q: What is the Concurrency Model?

Single master, multi-slave.

All writes must be performed on the master, reads may be performed on the master, however you will achieve better scalability by performing all reads against slaves.

Replication concurrency is per-Collection hierarchy. There will be a single topic queue for each configured Collection.

If a slave has a collection, with a document which is under heavy-read contention, and there is a pending update for that document on the head of the topic-queue, it may be difficult to apply that update until all reads on the document have ceased, during this period replication of updates to other documents in that Collection will be blocked... Put another way: Attempting to update a specific document (via replication) which is locked for reading (on a slave), stops all replication for that collection (on the affected slave).

In future, we could possibly look at providing replication on a per-Document basis as opposed to per-Collection. Effectively, each Collection would have a fixed topic which describes adding and removing document topics, and then a number of dynamic topics for each document as they are required for updated.

Q: I have a compile error

org.exist.EXistException: org.exist.collections.triggers.DocumentTriggerProxies.add(Lorg/exist/collections/triggers/AbstractTriggerProxy;)V
	at org.exist.storage.BrokerPool.initialize(BrokerPool.java:1065)
	at org.exist.storage.BrokerPool.<init>(BrokerPool.java:722)
	at org.exist.storage.BrokerPool.configure(BrokerPool.java:248)
	at org.exist.storage.BrokerPool.configure(BrokerPool.java:224)
	at org.exist.jetty.JettyStart.run(JettyStart.java:163)
	at org.exist.jetty.JettyStart.main(JettyStart.java:71)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.exist.start.Main.invokeMain(Main.java:126)
	at org.exist.start.Main.run(Main.java:448)
	at org.exist.start.Main.main(Main.java:50)
Caused by: java.lang.NoSuchMethodError: org.exist.collections.triggers.DocumentTriggerProxies.add(Lorg/exist/collections/triggers/AbstractTriggerProxy;)V
	at org.exist.storage.BrokerPool.initialiseTriggersForCollections(BrokerPool.java:1175)
	at org.exist.storage.BrokerPool.initialize(BrokerPool.java:981)
	... 12 more

Answer: The internal Trigger interface (API) has been changed during development of eXist-db 2.2. Please update the extension-code to at least commit 15fe9259a8

Q: how to set the logging level for the extension?

See the FAQ.

note that for eXist-db v2.x the log4j xml system is a bit different, and the package name pattern is org.exist.replication.

Q: My queries stopped working with v0.9.0

With the v0.9.0 pre-release the java-packages have been updated making them more logical and consistent. It makes the code better maintainable. Apologies for any inconvenience.

Replication:

<trigger class="org.exist.jms.replication.publish.ReplicationTrigger">
<trigger class="org.exist.jms.replication.subscribe.ReceiverStartupTrigger">
import module namespace replication="http://exist-db.org/xquery/replication" 
              at "java:org.exist.jms.xquery.ReplicationModule"; 

Messaging:

import module namespace messaging="http://exist-db.org/xquery/messaging" 
              at "java:org.exist.jms.xquery.MessagingModule";

JMS receiver management:

import module namespace jms="http://exist-db.org/xquery/jms" 
              at "java:org.exist.jms.xquery.JmsModule";

Q: My own ActiveMQ/JMS application can not parse the messages with XML payload

For efficiency reasons (XML fragments can consume a lot of memory), the XML payload is GZIPped before transport.

To prevent compression, set 'exist.document.compression' to 'none' in the message properties of the data producer:

let $messageProperties :=
    map {
        "exist.document.compression" := "none"
    }

Q: The slave seems to think it's the master ... but why?

The log file contains the following entry: (ReplicationJmsListener.java) [onMessage]:111 - Incoming JMS message was sent by this instance. Processing stopped.

When the extension is started for the first time, the file webapp/WEB-INF/data/jms.identity is generated, containing a unique "token". With this token the extension can prevent that when a master node is also configured as a slave node, that an replication event is re-replicated.

Durable messaging

The replication feature uses a durable subscription, this cannot be changed. The messaging feature can subscribe for both Queues and Topics. For Topics , the durable subscription is optional. It can be switched on by setting the property "subscriber.durable" := true()

Clone this wiki locally