As of the 5.7.0 release of ActiveMQ the choice of storage locking mechanism, as used by a persistence adapter, has been made pluggable. This feature is only meaningful to brokers configured in a shared storage master/slave topology. Prior to release 5.7.0 the storage locking mechanism (and thus master election) was dictated by the choice of persistence adapter. With the KahaDB persistence adapter, for example, the storage locking mechanism was based on a shared file lock. Similarly, the JDBC persistence adapter used a database backed storage lock. Now that the choice of storage locker is divorced from that of the persistence adapter one can mix and match combinations of the two. Storage locker pluggability is made possible by the Locker interface that all pluggable lockers must implement. This interface makes it easy to implement a custom storage locker that meets local requirements. Every persistence adapter, however, has its own default locker which works as before. LockersEvery locker must implement the Locker interface. The locker interface has the following properties:
Persistence AdaptersEvery persistence adapter (or any other broker service that wishes to use locks) must implement the Lockable interface. This interface has the following properties:
Existing LockersShared File LockerThe Shared File Locker is the default locker for the KahaDB persistence adapter. It locks a file to ensure that only the broker holding the lock (the master) is granted access to the message store. Example:<persistenceAdapter> <kahaDB directory="target/activemq-data" lockKeepAlivePeriod="10000"> <locker> <shared-file-locker lockAcquireSleepInterval="5000"/> </locker> </kahaDB> </persistenceAdapter> The Consequences of lockKeepAlivePeriod = 0 For this locker When When Note that as of ActiveMQ 5.9.0 the KahaDB persistence adapter can also use the Lease Database Locker (see below). Database LockerThe Database Locker is the default locker for the JDBC persistence adapter. It locks a database table in a transaction to ensure that only single resource is used. Example:<persistenceAdapter> <jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" lockKeepAlivePeriod="10000"> <locker> <database-locker lockAcquireSleepInterval="5000"/> </locker> </jdbcPersistenceAdapter> </persistenceAdapter> The Database Locker uses its This locker opens a JDBC transaction against a database table ( A problem with this locker can arise when the master broker crashes or loses its connection to the database causing the lock to remain in the database until the database responds to the half closed socket connection via a TCP timeout. The database lock expiry requirement can prevent the slave from starting some time. In addition, if the database supports failover, and the connection is dropped in the event of a replica failover, that JDBC transaction will be rolled back. The broker sees this as a failure. Both master and slave brokes will again compete for a lock. Lease Database LockerThe Lease Database Locker was created to solve the shortcomings of the Database Locker. The Lease Database Locker does not open a long running JDBC transaction. Instead it lets the master broker acquire a lock that's valid for a fixed (usually short) duration after which it expires. To retain the lock the master broker must periodically extend the lock's lease before it expires. Simultaneously the slave broker checks periodically to see if the lease has expired. If, for whatever reason, the master broker fails to update its lease on the lock the slave will take ownership of the lock becoming the new master in the process. The leased lock can survive a DB replica failover. Example:<persistenceAdapter> <jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" lockKeepAlivePeriod="5000"> <locker> <lease-database-locker lockAcquireSleepInterval="10000"/> </locker> </jdbcPersistenceAdapter> </persistenceAdapter> In order for this mechanism to work correctly, each broker in a master/slave(s) cluster must have a unique value for the The lease based lock is acquired by blocking at startup. It is then retained for a period whose duration (in ms) is given by the In the simplest case, the clocks between master and slave must be in sync for this solution to work properly. If the clocks cannot be in sync, the locker can use the system time from the database CURRENT TIME and adjust the timeouts in accordance with their local variance from the DB system time. If It is important to know if the default rules your JDBC driver uses for converting As of ActiveMQ 5.9.0 the lease database locker can be used in conjunction with the KahaDB persistence adapter. However, this particular combination requires that the lease database locker element contains a <persistenceAdapter> <kahaDB directory="target/activemq-data" lockKeepAlivePeriod="5000"> <locker> <!-- When used with the KahaDB persistence adapter the 'dataSource' attribute must be defined on the locker itself: --> <lease-database-locker lockAcquireSleepInterval="10000" dataSource="#mysql-ds"> <statements> <!-- Default locker attributes and SQL statements may be overridden here using one or more <statements attribute_or_statement="value"/> entries: --> <statements lockTableName="activemq_lock"/> </statements> </lease-database-locker> </locker> </kahaDB> </persistenceAdapter> To see the complete list of attributes and SQL statements that can be overridden see the Statements class. When the KahaDB persistence adapter is configured to use the As of ActiveMQ 5.11, however, the
|