Configuring workers

One of the component types that index managers coordinate are workers, which are responsible for the actual updates made to a Lucene index.

If you are using Lucene and Hibernate Search in a clustered environment, many of the configuration options are set at the worker level. We will explore those more fully in Chapter 7, Advanced Performance Strategies. However, three key configuration options are available in any environment.

Execution mode

By default, workers perform Lucene updates synchronously. That is, once an update begins, execution of the main thread is blocked until that update completes.

Workers may instead be configured to update asynchronously, a "fire and forget" mode that spawns a separate thread to perform the work. The advantages are that the main thread will be more responsive, and the workload handled more efficiently. The downside is that the database and the index may be out of sync for very brief periods.

Execution mode is declared in hibernate.cfg.xml (or persistence.xml for JPA). A global default may be established with the default substring, and per-entity configurations may be set with the entity index name (for example, App):

...
<property name="hibernate.search.default.worker.execution">
   sync
</property>
<property name="hibernate.search.App.worker.execution">
   async
</property>
...

Thread pool

By default workers perform updates in only one thread, either the main thread in the synchronous mode, or a single spawned thread in the asynchronous mode. However, you have the option of creating a larger pool of threads to handle the work. The pool may apply at the global default level, or be specific to a particular index:

...
<property name="hibernate.search.default.worker.thread_pool.size">
   2
</property>
<property name="hibernate.search.App.worker.thread_pool.size">
   5
</property>
...

Tip

Because of the way that Lucene indexes are locked during update operations, using a lot of threads in parallel often does not provide the performance boost that you might expect. However, it is worth experimenting when tuning and load-testing an application.

Buffer queue

Pending work gets backed up in a queue, waiting for a thread to free up and deal with it. By default, the size of this buffer is infinite, at least in theory. In reality, it is bound by the amount of system memory available, and an OutOfMemoryExeception may be thrown if the buffer grows too large.

Therefore, it is a good idea to place some limit, globally or on a per-index basis, for the size to which these buffer can grow.

...
<property name="hibernate.search.default.worker.buffer_queue.max">
   50
</property>
<property name="hibernate.search.App.worker.buffer_queue.max">
   250
</property>
...

When a buffer reaches the maximum allowable size for its index, additional operations will be performed by the thread which creates them. This blocks execution and slows down performance, but ensures that the application will not run out of memory. Experiment to find a balanced threshold for an application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset