2011-09-19 59 views
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 */ 
    } 
} 

注意,聯想()函數需要是事務性的,因爲它修改多個地圖。由於狗和所有者在某種程度上是相關聯的,因此可能數據在方法完成之前處於不一致的狀態。現在,如果另一個類從分佈式內存中讀取,它不知道事務正在發生,並且可能會看到數據不一致。

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()是昂貴的(例如,在本地複製兩個映射),在這種情況下,它可能不足以鎖定多個客戶端。

是否有這種分佈式同步問題的標準解決方案?

+1

是鎖壞..所以做交易。可以訂購解決這個特定的問題;先將dog1放入地圖中,然後創建關聯?因此,相關的dog1將始終在地圖中。 –

回答

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