2013-03-06 62 views
3

我是新來azure緩存並面臨一個問題。處理Azure緩存中悲觀併發的最佳方法是什麼?

我會先介紹一下情況。我們使用SQL Azure作爲我們的應用程序的數據庫。爲了避免出現延遲問題和節流問題,我們正在使用Azure緩存(Web角色上的協同定位緩存)。通過使用Azure緩存,我們只從數據庫中提取數據一次,並將其保存在緩存中以供進一步使用。

由於我們使用的是緩存數據,因此每當有任何DML操作執行時,在任何時間點都始終保持SQL Azure數據庫和Azure緩存之間的數據同步。我們通過首先更新數據庫並更新成功的無效緩存數據來做到這一點。這種方法適用於正常場景。 但是,在併發用戶工作並執行更新時,似乎存在問題。我們在更新Cache中的數據時使用悲觀併發模型。在這裏,我們使用瞬間重試策略來確保重試嘗試(假設5秒,固定間隔爲1秒)。

示例代碼看起來是這樣的:

Microsoft.Practices.TransientFaultHandling.RetryPolicy cacheRetryPolicy = 
    GetAzureCacheRetryPolicy(); 

cacheRetryPolicy.Retrying += TransientRetryManager.OnRetrying; 
DataCacheLockHandle handle = null; 
cacheRetryPolicy.ExecuteAction(() => 
{ 
    try 
    { 
     object obj = cache.GetAndLock(key, TimeSpan.FromSeconds(1), out handle); 
     cache.PutAndUnlock(key, value, handle, expirationTime.Value, tags); 
    } 
    catch (DataCacheException ex) 
    { 
     if (ex.ErrorCode == DataCacheErrorCode.KeyDoesNotExist) 
     { 
      cache.Put(key, value, expirationTime.Value, tags); 
     } 
     else 
     { 
      //This means wait till the cache is released. 
      //Throwing from here will allow to retry with Transient 
      //handling retry policy.       
      throw ex; 
     } 
    } 
} 

在此,在等待的情況下,數(可以說6)超過重試次數(即在我們的例子5)。到第六輪到來時,重試嘗試已經結束,因此具有最新更新的第六等待將無法將其更新到緩存中。

有一種方法可以通過排隊等候所有等待的情況來解決此問題,以防errorcodeobjectlocked,同時獲取緩存密鑰的鎖定。

任何人都可以請建議處理這種情況下的最佳方式?

回答

0

如果我沒有錯,緩存的結果並沒有在數據庫中保存最新的數據。

-------------------------------------------------------------------------------- 
This could happen in following Scenario 
-------------------------------------------------------------------------------- 
Time  User 1        User 2 
1   Updates DB data from A to B   Idle 
4   Adding data to cache    Updates DB data from B to C 
5   Still adding to cache    Adding data to cache 
7   Still adding to cache    caching is done 
9   Still adding to cache    current data is C 
10   caching is done 
11   current data is B (but it should be C) 
  1. 用戶2發起用戶後更新1
  2. 因此理想情況下,最新的數據應該是用戶2的
  3. 但用戶1的代碼之前2完成用戶的緩存代碼,那麼緩存代碼的用戶1被擊發
  4. 所以最新的結果將是用戶1,這不是預期的。

如果我們可以使用線程鎖來解決單個實例應用程序,由於Azure是多實例,並且有更多命中的APP,您可以採取以下方法。

也許不是最好的,但我們已經解決了這個問題,我們的應用程序運行在6個Web服務器上,並且我們有超過75k個用戶。

我們始終保持兩個數據在緩存中

  1. 內容哪些是需要緩存
  2. 價值上次更改列的從我們的數據庫相同內容

增加新的價值緩存之前,我們總是確保緩存中的LastModified數據少於我們在數據庫中的數據。 由於任何原因,緩存的數據超過了當前的數據庫數據,那麼最近的值已經被推送到緩存,所以我們不加回來。

So what we have done is 
----------------------------------------------------------------------------------- 
Time    User 1      User 2 
----------------------------------------------------------------------------------- 
1   Updates DB data from A to B   Idle 
4   Adding data to cache    Updates DB data from B to C  
5   still adding to cache    Adding data to cache 
7   Still adding to cache    caching is done with last modified date 
9   Still adding to cache    current data is C 
10   found that cached date is greater than the current 
11   skips caching 
相關問題