3

我所说的分布式缓存产品是指 Coherence 或 Hazelcast。我将使用 Hazelcast 作为示例。

假设我有一个在多个地图中保持状态的对象:

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 */ 
    }
}

请注意, associate() 函数需要是事务性的,因为它修改了多个映射。由于狗和主人以某种方式关联,因此在方法完成之前数据可能处于不一致状态。现在,如果另一个类从分布式内存中读取,它不知道事务正在发生,并且可能会不一致地看到数据。

class DataStateClient {
     Map<ID, Dog> dogs = Hazelcast.getMap("dog");
     Map<ID, Owner> owners = Hazelcast.getMap("owner");

     public void doSomething() {
        // oops, owner2 is associated with dog1 but
        // dog1 is not yet in the map!
    }
}

现在,Hazelcast 已经分布式锁来解决这样的问题,但性能影响是什么?假设 doSomething() 开销很大(例如,在本地复制两个地图),在这种情况下,可能不足以锁定多个客户端。

这个分布式同步问题有标准解决方案吗?

4

1 回答 1

1

如果要序列化写访问(互斥),分布式锁是一种方法。如果您使用的是 Cacheonix,如果您使用 Cacheonix 读/写锁,您的示例可能会有更好的性能。这样,读者可以有并发的读取访问,并且不必等待单个服务器完成,如果使用简单的互斥锁,情况就是这样:

作家:

  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();
  }

...

读者:

  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();
  }
于 2011-09-20T02:56:19.147 回答