How to convey transactions operating on multiple distributed maps within a distributed cache product
By distributed cache product I mean something like Coherence or Hazelcast. I will use Hazelcast as the example.
Suppose I have an object that keeps state in a number of maps:
class DataState {
Map<ID, Dog> dogs = Hazelcast.getMap("dog");
Map<ID, Owner> owners = Hazelcast.getMap("owner");
public void associate(Dog dog, Owner owner) {
/* ... put in maps and set up references */
}
}
Note that the associate() function needs to be transactional because it modifies multiple maps. Since dogs and owners are somehow associated, it may be that the data is in an inconsistent state until the method completes. Now if another class reads from the distributed memory, it has no idea that a transaction is happening and may see data inconsistently.
class DataStateClient {
Map<ID, Dog> dogs = Hazelcast.getMap("dog");
Map<ID, Owner> owners = Hazelcast.getMap("owner");
public void doSomething() {
// oops, owner2 is a开发者_如何学编程ssociated with dog1 but
// dog1 is not yet in the map!
}
}
Now, Hazelcast has distributed locks to solve something like this, but what are the performance implications? Suppose that doSomething() is expensive (for example, copying both maps locally) in which case it may not be adequate to lock out multiple clients.
Is there a standard solution to this distributed synchronization problem?
If you want to serialize write access (mutual exclusion), a distributed lock is a way to go. If you were using Cacheonix your example could have a better performance if you used Cacheonix read/write locks. This way readers could have concurrent read access and wouldn't have to wait for a single server to finish that would be a case if a simple mutex were used:
Writer:
final Cacheonix cacheonix = Cacheonix.getInstance();
final ReadWriteLock rwLock = cacheonix.getCluster().getReadWriteLock();
final Lock writeLock = rwLock.writeLock();
writeLock.lock();
try {
// No one else can enter this section
// Update dogs
// Update owners
} finally {
writeLock.unlock();
}
...
Readers:
final Cacheonix cacheonix = Cacheonix.getInstance();
final ReadWriteLock rwLock = cacheonix.getCluster().getReadWriteLock();
final Lock readLock = rwLock.readLock();
readLock.lock();
try {
// Readers can enter this section simultaneously
// Read dogs
// Read owners
} finally {
readLock.unlock();
}
精彩评论