|
With 5.7.0 release, we introduced the change on locking strategies for shared storage master/slave topologies. Previously storage locking (and thus master election) was hard-coded directly in the particular store. So KahaDB had only the option to use shared file lock, while JDBC was using database lock. Now, the storage locking is separated from the store, so you can implement your own locking strategies if necessary (or tune existing ones). Of course, every store has it's own default locker. LockersEvery locker must implement Locker interface. So there are a couple of settings you can tune for every locker
Persistence AdaptersEvery persistence adapter (or other broker service that wants to use locks) needs to implement Lockable interface. You can use a few settings for every persistence adapter (that supports locking):
Existing LockersShared File LockerShared File Locker is a default locker used by KahaDB. It locks a file to ensure that only single resource is used. You can configure it like this: <persistenceAdapter> <kahaDB directory = "target/activemq-data"> <locker> <shared-file-locker lockAcquireSleepInterval="5000"/> </locker> </kahaDB> </persistenceAdapter> This locker doesn't implement keep alive function so there's no point in using lockKeepAliverPeriod settings Database LockerDatabase Locker is used by default by JDBC persistence adapter. It locks a database table in a transaction to ensure that only single resource is used. You can configure it like this: <persistenceAdapter>
<jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" lockKeepAlivePeriod="10000">
<locker>
<database-locker lockAcquireSleepInterval="5000"/>
</locker>
</jdbcPersistenceAdapter>
</persistenceAdapter>
Database locker uses keep alive to make sure broker still holds a lock. You can set keep alive period with lockKeepAlivePeriod property. Default value is 30000 (meaning 30 seconds). The problem with this locker can occur when the master broker lose its connection to the database or crash unexpectedly. The information about the lock remains 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 for a period. Lease Database LockerLease database locker solves master/slave problem of the default database locker. Master acquires a lock only for a certain period and must extend it's lease from time to time. Slave also checks periodically to see if the lease has expired. The lease can survive a db replica failover. You can configure it like this: <persistenceAdapter> <jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" lockKeepAlivePeriod="5000"> <locker> <lease-database-locker lockAcquireSleepInterval="10000"/> </locker> </jdbcPersistenceAdapter> </persistenceAdapter> The lease based lock is acquired by blocking at start and retained by the keepAlivePeriod. To retain, the lease is extended by the lockAcquireSleepInterval, so in theory the master is always (lockAcquireSleepInterval-lockKeepAlivePeriod) ahead of the slave w.r.t the lease. It is imperative that lockAcquireSleepInterval > lockKeepAlivePeriod, to ensure the lease is always current. |