Skip to main content
Fusion supports uni-directional, multi-region replication of Solr updates between data centers using Solr’s CrossDC (Cross Datacenter) framework. This feature simplifies geo-redundancy and failover by providing a preconfigured Solr plugin (fusion-crossdc-producer) and a dedicated consumer application (fusion-crossdc-consumer) for replaying updates on the target cluster, helping to ensure high availability and business continuity in distributed or hybrid cloud environments.
This feature is supported in Fusion 5.9.13 and later.
With uni-directional CrossDC, Solr update requests (including indexing, collection, and configset changes) from a primary cluster are mirrored to a secondary cluster using Apache Kafka. You can configure which collections and actions are mirrored.
Be sure to review the Limitations section to understand what to expect before you enable this feature.

CrossDC and ConfigSync

Fusion supports ConfigSync in addition to CrossDC. While CrossDC is designed for data replication, ConfigSync is designed for configuration synchronization.
When you use CrossDC, we recommend also enabling ConfigSync to synchronize the Solr schema. If you do not enable ConfigSync, you must ensure that the Solr schema is synchronized by some other method.
Here’s a comparison of the two features: For complete details about what ConfigSync manages, see Supported objects in the ConfigSync documentation. See below for details about what Solr CrossDC manages.

Supported objects

These are the objects managed by Solr CrossDC:
  • Solr collections, which can optionally include creating and deleting collections. You can also select which collections and commands are synchronized and which ones are ignored.
  • Rules stored in *_query_rewrite and *_query_rewrite_staging collections
  • Any other new Solr collection data that you configure to be synchronized, as explained below

Before you begin

Before you enable Solr CrossDC, your Solr collections must already be in a synchronized state. After you enable CrossDC, synchronization happens automatically. The instructions below explain how to synchronize your collections before enabling this feature.
  1. Schedule a maintenance window. During this window, ensure that Fusion will not perform any operations that could alter the contents of its Solr collections. Schedule sufficient time to perform Solr collections backup/restore operations followed by Solr CrossDC enablement.
  2. Back up your Solr collections from the source Fusion cluster, using your cloud storage provider’s repository. The Solr documentation has provider-specific instructions for configuring the backup. An example configuration is shown below:
  3. Restore your Solr collections on the Fusion clusters you want to synchronize, using your newly-created backup. The Solr documentation has complete instructions for doing this, too.
  4. Ensure that your Solr schema is synchronized between clusters. You can do this using ConfigSync or the method of your choice.
Now you’re ready to configure CrossDC as explained below.

Configure CrossDC

CrossDC configuration is done in two data centers: the source and target. You’ll also configure MirrorMaker as the conduit between them.
  • In the source data center, you select which collections and commands to mirror. You can also tune parameters that affect performance and resource consumption.
  • In the target data center, you ensure that all of the collections to be mirrored already exist, then set up the Consumer.
Follow the detailed steps below.
  1. In the source data center, configure Solr and Kafka.
    This is where you select what to synchronize and tune the performance parameters.To enable CrossDC for Solr in the source data center, you need to configure the following components:The steps and examples below show you how to configure your source Solr instance.
    In Fusion 5.9.16 and later, you can also fine-tune the Kafka connection using Kafka configuration properties, either as KAFKA_* environment properties (such as KAFKA_MAX_POLL_RECORDS) or kafka.* system properties (such as kafka.max.poll.records).
    1. Pull and deploy the fusion-solr-managed Docker image.
    2. In solrconfig.xml, for each collection you want to mirror, add the MirroringUpdateRequestProcessorFactory handler to its configset:
      Only collections with MirroringUpdateRequestProcessorFactory configured in the updateRequestProcessorChain are mirrored; other collections are ignored.
      Both bootstrapServers and topicName are required: These parameters are optional for the MirroringUpdateRequestProcessorFactory:
    3. If you are not using ConfigSync: Configure configset mirroring in solr.xml:
    4. If you are not using ConfigSync: Configure collection admin request mirroring in solr.xml. You can choose one of these handlers to use for this:
      • MirroringCollectionsHandler is the native Solr handler. It mirrors all admin actions for all collections, or you can select specific collections to mirror.
      • FusionCollectionsHandler has all the same capabilities and configuration options, plus action whitelisting so you can mirror only selected actions and ignore others.
      By default, admin commands are mirrored for all collections. To mirror admin commands for specific collections only, you can set this system property:
      string
      A comma-separated list of collections for which the admin commands will be mirrored. If this list is empty or the property is not set, then admin commands for all collections mirrored. This property is supported by both MirroringCollectionsHandler and FusionCollectionsHandler.
      If you are using FusionCollectionsHandler, you can also configure action whitelisting by configuring the following system property:
      string
      A comma-separated list of actions to mirror. If it is not empty, then only the listed actions are mirrored; all others are ignored. See the Solr documentation for the list of actions.
    In the source data center’s Kafka instance, the Kafka topic must already exist and be configured to accept messages from the Solr instance. Make sure that the bootstrapServers you configured in Solr are reachable by Solr and that the configured topicName exists.If you configured Solr to use a Dead-Letter Queue (DLQ) topic (dlqTopicName), you must also create that topic in the source Kafka instance.
    If you need strict ordering of updates across multiple collections, use a single partition per topic. When a topic has multiple partitions, strict ordering of updates is guaranteed within each collection but not across multiple collections.
    When a Kafka topic used for mirroring has multiple partitions, the CrossDC Producer and Consumer guarantee strict ordering of updates (but see also the note above) ONLY within the same collection. In other words, when a multi-partition topic is used for mirroring there’s no guarantee of a strict global request ordering across collections, which normally should not be an issue. However, if a strict global ordering across collections is required then the mirroring topic must use a single partition.See the Kafka documentation for configuration details.
  2. In the target data center, configure Solr, Kafka, and the Consumer.
    Because CrossDC only mirrors new commands, the existing collections, documents, and configsets from your source Solr must already exist on the target Solr before mirroring begins. Create them if needed. The target collections must have the same names as the source collections, and they must use the same configsets as the source collections.
    New collections created on the source Solr are not automatically created on the target Solr unless ConfigSync is enabled or you have enabled either MirroringCollectionsHandler or FusionCollectionsHandler on the source Solr.
    In the target data center’s Kafka instance, you must create the same topic that you’ll also configure in MirrorMaker and the Consumer. If you configured a Dead-Letter Queue (DLQ) topic in the source Solr instance, you must also create that topic in the target Kafka instance.
    If you need strict ordering of updates across multiple collections, use a single partition per topic. When a topic has multiple partitions, strict ordering of updates is guaranteed within each collection but not across multiple collections.
    See the Kafka documentation for configuration details.
    1. Pull and deploy the fusion-crossdc-consumer Docker image for your Fusion release, such as 5.9.14.
    2. Configure the required system properties listed below, and any optional ones that apply to your use case. These additional optional configuration properties are used when the Consumer must retry by putting updates back in the Kafka queue:
      In Fusion 5.9.16 and later, you can also fine-tune the Kafka connection using Kafka configuration properties, either as KAFKA_* environment properties (such as KAFKA_MAX_POLL_RECORDS) or kafka.* system properties (such as kafka.max.poll.records).
  3. Configure Kafka MirrorMaker to connect to Kafka in both data centers.
    You can deploy MirrorMaker in either of your data centers, or somewhere else. Ensure that it can access both the source Kafka and target Kafka instances. Configure the source and target topic names to correspond with the names configured in MirroringUpdateRequestProcessorFactory and the Consumer application.See the MirrorMaker documentation for configuration details.

Metrics and monitoring

Both fusion-crossdc-producer and fusion-crossdc-consumer expose metrics that can be monitored, in two formats, at these endpoints:
  • Dropwizard JSON format: /metrics/json
  • Prometheus format: /metrics/prometheus (Fusion 5.9.16 and later)

Producer metrics

The fusion-crossdc-producer module exposes the following metrics for each source replica in a collection:

Consumer metrics and health check

Counters

The fusion-crossdc-consumer application exposes the following counters with the following hierarchical keys, where the <TYPE> can be one of UPDATE, ADMIN, or CONFIGSET:

Timers

The fusion-crossdc-consumer application exposes the following timers with the following hierarchical keys, where the <TYPE> can be one of UPDATE, ADMIN, or CONFIGSET:

Health check

In Fusion 5.9.16 and later, the Consumer exposes a /health endpoint that you can use to fetch a report on the status of the Consumer components.
  • If all components pass the health check, the endpoint returns an HTTP 200 OK code.
  • If any components fail, the endpoint returns a 500 Server Error code with the detailed status of each failure.
A simple GET request with no parameters retrieves the report, which shows "healthy": true for healthy components and "healthy": false for failing components, as in the example below where Kafka is failing; note the message field that provides a reason for the failure:
Response

Limitations

The CrossDC feature has some known limitations:
  • Only updates are mirrored, not existing indexes. You should create a copy of each existing collection, with its documents and configset, on the target Solr before you turn on CrossDC.
  • Data loss can lead to divergence. If any of the components in your CrossDC configuration experience an event that causes data loss, the source collections and target collections can potentially diverge. Diverged indexes are not automatically detected or re-synchronized.
  • Document size is limited. The CrossDC Producer module tries to estimate the size of each message and avoid sending messages that are too large to Kafka. It does not split messages that are too large; instead, it rejects them. If this happens after the update has already been processed locally, then the contents of the mirrored collections can diverge. Kafka’s maximum message size is 1MB by default, configured with message.max.bytes.
  • Retries can lead to divergence The CrossDC Producer module first applies updates locally, and attempts mirroring only if they succeed. If sending a mirrored request fails, the request is retried, and if it’s still failing then it’s logged and the message is discarded (or sent to a dead-letter queue). Since the update was already applied locally, this can cause divergence of the local and mirrored collections.
  • Commands can be re-ordered when collapsed. The CrossDC Producer module can optionally preserve exact ordering of updates and deletes sent in a single request, but this negatively affects performance. If you do not need strict ordering of multiple commands in a single request, then you should use collapseUpdates=partial or collapseUpdates=all.
  • Delete-by-Query expansion can lead to divergence. The CrossDC Producer can either mirror Delete-By-Query requests as-is or expand them into individual Delete-By-Id requests (except for *:* which is always sent as-is). In extreme cases this expansion may produce a request that is too large to be mirrored. Delete-By-Query expansion helps to ensure the strict ordering of deletes and updates in the target Solr collection but it may also lead to divergence of the local and mirrored collections if the expansion fails or the resulting request is too large to mirror.
  • Collection creation and deletion requires an existing configset. The CrossDC Producer module can optionally mirror collection creation and deletion requests. However, the target Solr instance must already have the corresponding configset available in ZooKeeper. If it doesn’t, this causes an error when the target collection is created or deleted. The Consumer application may also experience significant slow-downs when it receives update requests to non-existent target collections. These slow-downs affect processing requests for other collections, too.
  • ConfigSet creation and deletion behavior depends on the handler. If you are using MirroringConfigSetsHandler, then new configsets created on the source Solr are mirrored automatically to the target Solr. If you are not using MirroringConfigSetsHandler, then new configsets are not mirrored; you must use ConfigSync or create them manually on the target Solr to avoid an error when the target collection is created or deleted. These errors also impact the performance of the Consumer application.
  • In some cases, admin request whitelisting is needed. If you are using MirroringCollectionsHandler, then all collection admin requests are mirrored. This may not always be desirable if the target Solr cluster is expected to differ or is managed externally (such as by an autoscaling operator). In this case, you should use FusionCollectionsHandler instead, and configure the collectionActionsWhitelist property to restrict the mirrored collection admin requests to only those that are needed.