2009-04-21 5 views
8

Wir haben eine Website, die auf zwei Lastenausgleichservern ausgeführt wird. Wir verwenden das ASP.Net-Caching, um die Leistung zu verbessern, indem Sie hohe Nutzungsdaten zwischenspeichern. ABER, gelegentlich ändern sich diese Daten. Wenn dies der Fall ist, müssen die relevanten Cache-Elemente auf BEIDEN Servern mit Lastenausgleich gelöscht werden. Hat jemand einige leicht zu implementierende Vorschläge, wie das gemacht werden kann?Selektives Cache-Clearing über Lastausgleichserver (ASP.Net)

Ich weiß, dass es Software für Sie gibt (Microsoft Velocity für einen). Ich weiß auch, dass es andere Möglichkeiten gibt, getrennte Zustandsserver usw. zu haben. Jedoch, für was wir wollen, scheinen sie alle wie Overkill. Wir brauchen nur einen einfachen Mechanismus, um bestimmte Cache-Elemente auf mehreren Servern zu löschen.

Vielen Dank für Anregungen.

+0

Ich bin froh, dass meine Lösung für Sie arbeiten wird. Wenn Sie auf irgendwelche Probleme stoßen, lassen Sie es mich wissen! – wweicker

Antwort

1

Wir verwenden einen einfachen Web-Service-Ansatz. Unser Cache-Löschmechanismus überprüft eine Web-Konfigurationseinstellung, um festzustellen, ob andere Server vorhanden sind, und ruft den Webdienst auf diesen Servern asynchron auf.

Wir speichern Daten mit spezifischen Namenskonventionen, um es einfach zu machen, was wir wollen. Daher geben wir entweder ein Präfix oder ein Postfix für das zu entfernende Element ein, da es manchmal benutzerspezifisch sein kann (z. B. die Benutzerkennung wird an den Namen des Elements angehängt) oder anwendungsspezifisch (z. B. das Präfix des Elements ist die Anwendung) Name).

Hier ist ein VB Beispiel der ClearItem Routine, die entweder auf einer Ihrer Knoten genannt würde:

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 

Sie können sehen, dass der Code oben ruft andere Server (n) unter Verwendung dieser Hilfsklasse:

Der Webdienst auf dem Remote-Server ruft dann denselben Code auf, den das _ClearItem aufgerufen hat.