Wednesday, January 20, 2010

Quartz Clustering Cookbook










Quartz Clustering Cookbook


This section is designed to provide a resource for developers looking to solve specific problems with clustering in Quartz.



Assigning Jobs to Specific Instances in the Cluster


Currently, no way exists to assign (pin) a job to a specific node in the cluster. If you need this behavior, you can create a nonclustered Quartz application running in parallel with a clustered node and use either a separate set of database tables or an XML file along with the JobInitializationPlugin.


Don't point a nonclustered instance to the same set of database tables being used by a cluster. You will get very erratic results.




Running Jobs on Every Node in the Cluster


As with the previous answer, there is currently no way to run an instance of a job on every node in a cluster. The best option is to use a nonclustered instance in parallel with each node in the cluster and either use a separate set of database tables or use an XML file along with the JobInitializationPlugin and the RAMJobStore.





Running Nodes on Separate Machines


Quartz doesn't really care if you run nodes on the same machine or on different ones. When clustering is done on separate machines, it is commonly referred to as horizontal clustering. When nodes are run from the same machine, it is referred to as vertical clustering. With vertical clustering, there is a single point of failure. This is bad news for highly available applications because if the machine crashes, all nodes are effectively stopped.




Using a Time Synch Service


When you are running a Quartz cluster on separate machines, the clocks should be synchronized to prevent weird and unpredictable behavior. We have already mentioned that if the clocks are not in synch, that Scheduler instances will become confused about the state of other nodes. There are several easy ways to ensure the clocks are in synch, and there should be no reason not to do this.


The easiest way to synch the computers' clocks is to use one of the Internet Time Servers (ITS). For information on how to set up your clock based on one of these internationally accepted standards, see http://tf.nist.gov/service/its.htm.




Retrieving a List of Executing Jobs from the Cluster


Currently there is no easy way to get a list of all jobs executing in the cluster without going to the database directly. If you ask a Scheduler instance, you will get only a list of jobs executing on that instance. You could write some JDBC code that hits the database and retrieves the information from the proper table. Of course, this goes outside of Quartz, but it will solve the problem. Another approach is to use Quartz's RMI features to connect to each node in turn, querying it for its currently executing jobs.





Running Clustered and Nonclustered Instances Together


Nothing prevents you from using clustered and nonclustered Quartz applications in the same environment. The only caution is not to mix these two environments in the same database. That is, the nonclustered environment should not go against the same set of database tables as the clustered applications; you will get erratic results, and both clustered and nonclustered Jobs could encounter problems.


If you do run a nonclustered Quartz application in parallel with a clustered node, try using the JobInitializationPlugin (along with an XML file) and the RAMJobStore. This will make your life much easier.




Using Global Listeners in a Clustered Environment


You can still use job and trigger listeners in a clustered environment. The only confusion comes in when you try to understand which Scheduler instance will receive the callback method.


The easiest way to remember this is that the Listener will be notified in the Scheduler instance where the job or trigger is executed. Because a job and trigger are executed on only a single node, the Listener is notified on that node.













No comments: