跨负载平衡服务器的选择性缓存清除(ASP.Net)

Jam*_*mes 8 .net architecture asp.net caching load-balancing

我们有一个运行在两个负载平衡服务器上的网站.我们使用ASP.Net缓存来缓存高使用率数据,从而帮助提高性能.但是,偶尔会有数据发生变化.当它发生时,我们需要清除负载平衡服务器上的相关缓存项.有没有人有一些容易实施的建议如何做到这一点?

我知道有一些软件可以为你管理(Microsoft Velocity for one).我也知道有其他选择可以使用单独的状态服务器等.但是,对于我们想要的东西,它们看起来都有点过分.我们现在只需要一种简单的机制来清除服务器上的特定缓存项.

谢谢你的任何建议.

Jos*_*rke 5

为什么不在服务器可以看到的对象上定义Cache Dependancy?您可以使用SQL文件缓存依赖性.

链接到缓存Msdn页面


wwe*_*ker 1

我们使用简单的网络服务方法。我们的缓存清除机制会检查 Web 配置设置,以查看是否存在任何其他服务器,并异步调用这些服务器上的 Web 服务。

我们用特定的命名约定来存储数据,以便于明确我们想要的内容。因此,我们为要删除的项目传入前缀或后缀,因为有时它可能是特定于用户的(例如,用户 ID 附加到项目的名称中)或特定于应用程序的(例如,项目的前缀是应用程序)姓名)。

下面是 ClearItem 例程的 VB 示例,该例程将在任一节点上调用:

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
Run Code Online (Sandbox Code Playgroud)

您可以看到上面的代码使用此帮助程序类调用其他服务器:

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
Run Code Online (Sandbox Code Playgroud)

然后,远程服务器上的 Web 服务调用 _ClearItem 调用的相同代码。