2009-04-21 5 views
8

У нас есть веб-сайт, который работает на двух серверах с балансировкой нагрузки. Мы используем кэширование ASP.Net, чтобы повысить производительность, кэшируя данные высокого уровня использования. НО, иногда эти данные меняются. Когда это произойдет, нам нужно очистить соответствующие элементы кэша на BOTH серверах с балансировкой нагрузки. Есть ли у кого-нибудь некоторые возможности для реализации предложений о том, как это можно сделать?Выборочная очистка кеша на серверах с балансировкой нагрузки (ASP.Net)

Я знаю, что есть программное обеспечение для управления этим для вас (Microsoft Velocity для одного). Я также знаю, что есть другие варианты наличия отдельных государственных серверов и т. Д. Однако для того, что мы хотим, все они кажутся излишними. Просто простой механизм для очистки конкретных элементов кеша на серверах - это все, что нам нужно сейчас.

Спасибо за любые предложения.

+0

Я рад, что мое решение будет работать на вас. Если вы столкнетесь с какими-то корягами, дайте мне знать! – wweicker

ответ

1

Мы используем простой подход веб-службы. Механизм очистки кэша проверяет настройки веб-конфигурации, чтобы увидеть, существуют ли какие-либо другие серверы и асинхронно вызывает веб-службу на этих серверах.

Мы храним данные с определенными советами именования, чтобы упростить очистку того, что мы хотим. Таким образом, мы передаем либо префикс, либо постфикс для элемента, который должен быть удален, поскольку иногда он может быть специфичным для пользователя (например, идентификатор пользователя добавлен к имени элемента) или конкретному приложению (например, префикс элемента является приложением имя).

Вот VB пример подпрограммы ClearItem, который будет называться на любом из ваших узлов:

Public Shared Sub ClearItem(ByVal strPrefix As String, ByVal strPostfix As String) 

    If WebConfig.Caching_Enabled() Then 

     ' Exit if no criteria specified ' 
     If IsNothing(strPrefix) AndAlso IsNothing(strPostfix) Then 
      Exit Sub 
     End If 

     ' At the very least we need a Postfix ' 
     If Not IsNothing(strPostfix) AndAlso Not strPostfix.Length.Equals(0) Then 
      _ClearItem(strPrefix, strPostfix) 
     End If 

     If WebConfig.Caching_WebFarmEnabled() Then 
      ' Now clear the cache across the rest of the server farm ' 
      _ClearItem_WebFarm(strPrefix, strPostfix) 
     End If 

    End If 

End Sub 

Private Shared Sub _ClearItem_WebFarm(ByVal strPrefix As String, ByVal strPostfix As String) 

    If WebConfig.Caching_WebFarmEnabled() Then 

     ' Use a web service on each server in the farm to clear the ' 
     ' requested item from the Cache ' 

     ' Determine which servers need to remove cache items ' 
     Dim arrServers As String() 
     arrServers = Split(WebConfig.Caching_WebFarmServers(), "|") 

     Dim strServer As String ' Holds which server we are currently contacting ' 

     ' Loop through all the servers and call their web services ' 
     For Each strServer In arrServers 

      Dim WS As New WebServiceAsyncCall 
      WS.StartCallBack(strServer, strPrefix, strPostfix) 

     Next 

    End If 

End Sub 

Private Shared Sub _ClearItem(ByVal strPrefix As String, ByVal strPostfix As String) 

    If WebConfig.Caching_Enabled() Then 

     ' Determine how we are comparing keys ' 
     Dim blnPrefix, blnPostfix As Boolean 

     If strPrefix.Length.Equals(0) Then 
      blnPrefix = False 
     Else 
      blnPrefix = True 
     End If 

     If strPostfix.Length.Equals(0) Then 
      blnPostfix = False 
     Else 
      blnPostfix = True 
     End If 

     ' Reference the Cache collection ' 
     Dim objCache As System.Web.Caching.Cache = HttpContext.Current.Cache 

     ' Exit if the cache is empty ' 
     If objCache.Count.Equals(0) Then 
      Exit Sub 
     End If 

     ' Clear out the cache for all items matching the input(s) (on this local server) ' 
     Dim objCacheEnum As IEnumerator = objCache.GetEnumerator() 
     Dim objCacheItem As Object 
     Dim objCurrentKey As System.Collections.DictionaryEntry 
     Dim strCurrentKey As String 

     ' Enumerate through the cache ' 
     While objCacheEnum.MoveNext() 

      objCurrentKey = CType(objCacheEnum.Current, DictionaryEntry) 
      strCurrentKey = objCurrentKey.Key.ToString() 

      ' How are we comparing the key? ' 
      If blnPrefix AndAlso Not (blnPostfix) Then ' Only by PREFIX ' 

       If strCurrentKey.StartsWith(strPrefix) Then 
        ' Remove it from the cache ' 
        objCacheItem = objCache.Remove(strCurrentKey) ' Returns a reference to the item ' 
        objCacheItem = Nothing ' Need to explicitly nuke this because the objCache.Remove() above doesn t destroy ' 
       End If 

      ElseIf Not (blnPrefix) AndAlso blnPostfix Then ' Only by POSTFIX ' 

       If strCurrentKey.EndsWith(strPostfix) Then 
        ' Remove it from the cache ' 
        objCacheItem = objCache.Remove(strCurrentKey) ' Returns a reference to the item ' 
        objCacheItem = Nothing ' Need to explicitly nuke this because the objCache.Remove() above doesn t destroy ' 
       End If 

      ElseIf blnPrefix AndAlso blnPostfix Then ' By both PREFIX and POSTFIX' 

       If strCurrentKey.StartsWith(strPrefix) AndAlso strCurrentKey.EndsWith(strPostfix) Then 
        ' Remove it from the cache ' 
        objCacheItem = objCache.Remove(strCurrentKey) ' Returns a reference to the item ' 
        objCacheItem = Nothing ' Need to explicitly nuke this because the objCache.Remove() above doesn t destroy ' 
       End If 

      Else 
       ' Not comparing prefix OR postfix? Why bother continuing then! ' 
       Exit Sub 
      End If 

     End While 

    End If 

End Sub 

Вы можете увидеть, что приведенный выше код вызывает другой сервер (ы) с помощью этого вспомогательного класса:

Private Class WebServiceAsyncCall 

    Public Sub StartCallBack(ByVal strService As String, ByVal strPrefix As String, ByVal strPostfix As String) 

     ActiveWebServiceCounter += 1 

     Dim clearCacheProxy As New CacheClearService.CacheClear ' This is the web service which of course will exist on the other node as well ' 
     clearCacheProxy.Url = strService 

     AddHandler clearCacheProxy.ClearItemCompleted, AddressOf DoneCallBack 

     clearCacheProxy.ClearItemAsync(strPrefix, strPostfix) 

    End Sub 

    Public Sub DoneCallBack(ByVal sender As Object, ByVal e As CacheClearService.ClearItemCompletedEventArgs) 

     ActiveWebServiceCounter -= 1 

     If e.Result.Length > 0 Then ' Something failed ' 
      ' Log the error ' 
     End If 

    End Sub 

End Class 

Веб-сервис на удаленном сервере затем вызывает тот же код, что и вызываемый _ClearItem.

5

Почему бы не определить зависимость кеша от объекта, который могут видеть оба сервера? Вы можете использовать зависимость кэша SQL или File.

Link to Caching Msdn Page