So we have configured JCR in standalone mode and want to reconfigure it for clustered environment. First of all, let's check whether all requirements are satisfied:
Dedicated RDBMS anyone like MySQL, Postges, Oracle and, etc but just not HSSQL;
Shared storage. The simplest thing is to use shared FS like NFS or SMB mounted in operation system, but they are rather slow. The best thing is to use SAN (Storage Area Network);
Fast network between JCR nodes.
So now, need to configure Container a bit. Check exo-configuration.xml to be sure that you are using JBossTS Transaction Service and JBossCache Transaction Manager, as shown below.
<component>
<key>org.jboss.cache.transaction.TransactionManagerLookup</key>
<type>org.jboss.cache.GenericTransactionManagerLookup</type>
</component>
<component>
<key>org.exoplatform.services.transaction.TransactionService</key>
<type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
<init-params>
<value-param>
<name>timeout</name>
<value>300</value>
</value-param>
</init-params>
</component>
Next stage is actually the JCR configuration. We need JBossCache configuration templates for : data-cache, indexer-cache and lock-manager-cache. Later they will be used to configure JCR's core components. There are pre-bundled templates in EAR or JAR in conf/standalone/cluster. They can be used as is or re-written if needed. And now, re-configure a bit each workspace. Actually, a few parameters need changing, e.g. <cache>, <query-handler> and <lock-manager>.
<cache> configuration should look like this:
<cache enabled="true"
class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
<properties>
<property name="jbosscache-configuration" value="test-jbosscache-data.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
<property name="jbosscache-cluster-name" value="JCR-cluster-data" />
<property name="jbosscache-shareable" value="true"/>
</properties>
</cache>
"jbosscache-configuration" is the path to configuration template;
"jgroups-configuration" is path to JGroups configuration that should not be anymore jgroups' stack definitions but a normal jgroups configuration format with the shared transport configured by simply setting the jgroups property singleton_name to a unique name (it must remain unique from one portal container to another). This file is also pre-bundled with templates and is recommended for use;
"jgroups-multiplexer-stack" set to "false" in order to disable the multiplexer stack as now it is recommended to use the JGroups' shared transport instead.
"jbosscache-cluster-name" is the name of cluster group. It should be different for each workspace and each workspace component. I.e.: <repository_name>-<ws_name>-<component(cache\|lock\|index)>
"jbosscache-shareable" set "true" in order to share the same JBoss Cache instance between several workspaces.
<query-handler> configuration
You must replace or add in <query-handler> block the "changesfilter-class" parameter equals with:
<property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter"/>
add JBossCache-oriented configuration:
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
<property name="jbosscache-cluster-name" value="JCR-cluster-indexer" />
<property name="jbosscache-shareable" value="true"/>
<property name="max-volatile-time" value="60" />
Those properties have the same meaning and restrictions as in the previous block. The last property "max-volatile-time" is not mandatory but recommended. This notifies that the latest changes in index will be visible for each cluster node not later than in 60s.
<lock-manager> configuration
Maybe this is the hardest element to configure, because we have to define access to DB where locks will be stored. Replace exsiting lock-manager configuration with shown below.
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
<property name="jbosscache-configuration" value="test-jbosscache-lock.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
<property name="jbosscache-cluster-name" value="JCR-cluster-locks" />
<property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks" />
<property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
<property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
<property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_pk" />
<property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
<property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
<property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
<property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
<property name="jbosscache-shareable" value="true"/>
</properties>
</lock-manager>
First few properties are the same as in the previous components, but here you can see some strange "jbosscache-cl-cache.jdbc.*" properties. They define access parameters for database where lock are persisted.
"jbosscache-cl-cache.jdbc.table.create" - whether to create it or not. Usually "true";
"jbosscache-cl-cache.jdbc.table.drop" - whether to drop on a start or not. Use "false";
"jbosscache-cl-cache.jdbc.table.primarykey" - the name of column with pk;
"jbosscache-cl-cache.jdbc.fqn.column" - the name of one more column. If you are not sure how to use, follow the example above (if much interested, please refer to JBossCache JDBCCacheLoader documentation)
"jbosscache-cl-cache.jdbc.node.column" - the name of one more column. If you are not sure how to use, follow the example above (if much interested, please refer to JBossCache JDBCCacheLoader documentation)
"jbosscache-cl-cache.jdbc.parent.column" - name of one more column. If you are not sure how to use, follow the example above if you are not sure (if much interested, please refer to JBossCache JDBCCacheLoader documentation)
"jbosscache-cl-cache.jdbc.datasource" - name of configured in Container datasource, where you want to store locks. The best idea is to use the same as for workspace.
That's all. JCR is ready for running in a cluster.