asp.net有效使用緩衝

來源:互聯網
上載者:User
Rob Howard
Telligent Systems, Inc.

標題比較口語化,但是引起了您的興趣,對不對?ASP.NET 緩衝是到目前為止我最喜歡的 ASP.NET 功能之一。為什麼呢?這是因為,通過使用緩衝,可以獲得一些奇異的效能和延展性結果,而這些結果可以輕鬆地進行衡量並轉換為應用程式實際節省的資金。這會使您成為 CTO 最喜歡的代碼猴子,因為您影響了至關重要的應用程式投資報酬率 (ROI)。換句話說,緩衝確實節省了資金!

從較進階別來說,在 ASP.NET 1.1 中,緩衝是作為支援最近最少使用 (LRU) 演算法概念的雜湊表實現的,以便確保如果需要記憶體,可以從緩衝中刪除項(一組用於在緩衝中插入和移除項的編程介面),並最終實現依賴項、支援時間、檔案和關鍵依賴項等概念。

依賴項模型是緩衝較為重要的功能之一,因為它允許進行如下陳述:

此時此刻,緩衝中的該項將不再有效(基於時間的依賴項)。

如果該緩衝條目更改,則另外一個緩衝條目也無效(基於鍵的依賴項)。

如果該檔案更改,則緩衝中的該項不再有效(基於檔案的依賴項)。

在用緩衝編程時,應該始終在使用項之前檢查該項是否存在。因此,在使用緩衝時,遵循下面的模式是一個很好的方法:

' #1 – Get a reference to the objectDim myCachedArrayList As ArrayList = Cache("MyArrayList")' #2 – Check if the reference is nullIf (myCachedArrayList) Is Nothing Then   ' Add items to array list   myCachedArrayList = PopulateMyArrayList()   ' Cache   Cache.Insert("MyArrayList", myCachedArrayList)End If' #3 – Return the dataReturn myCachedArrayList

看起來不錯,是不是?我們具有一個用於在可在某些條件下無效化的記憶體中儲存資料的靈活模型。該模型存在 ASP.NET 開發人員經常要求解決的幾個缺點。一個缺點是資料庫快取無效判定化,它意味著當資料庫中的某資料更改時,從緩衝中移除該項。第二個缺點是能夠建立自己的緩衝依賴項。

好訊息是,在 ASP.NET 2.0(先前的代號為“Whidbey”)中,這兩個缺陷都修複了。現在有兩個資料庫緩衝依賴項模型 — 一個用於 Microsoft SQL Server 7 和 2000,另一個用於 SQL Server 2005(先前的代號為“Yukon”)。第二項較大的更改是 CacheDependency 類沒有密封,並且被重新管道化,以便您可以為緩衝編寫自己的依賴項規則。

壞訊息是 ASP.NET 2.0 還不能用於生產用途。但是,目前我們可以通過 ASP.NET 1.1 來產生類似的資料庫快取無效判定化系統。實際上,在 2002 年早些時候,當我還在 ASP.NET 團隊中時,我就是使用該技術來對用於 Microsoft SQL Server 7 和 SQL Server 2000 的資料庫快取無效判定化機制進行原型設計的。

ASP.NET 2.0 中提供的兩個資料庫快取無效判定化選項極為不同。用於 SQL Server 2000 或 SQL Server 7.0 的選項被限制到一種稱為“表層級通知”的功能中。只引發在 SQL 表上執行的操作的通知。例如,表上的 UPDATE、INSERT 和 DELETE 操作。然而在 SQL Server 2005 中,可以從對動態 SQL、預存程序、視圖和簡單表層級無效化的結果進行的更改接收通知。

遺憾的是,無法通過 ASP.NET 1.1 複製 SQL Server 2005 所使用的資料庫緩衝依賴項模型,因為資料庫中直接內建了新的功能,以便支援在以前版本的 SQL Server 中停用通知。

資料庫快取無效判定化:您需要瞭解的內容

目前,有多種用於實現資料庫快取無效判定化的技術。其中第一種技術是我在大約四年前提供的,它使用擴充預存程序技術在資料庫中的資料更改時通知 ASP.NET。該原型是 ASP.NET 團隊對如何?資料庫快取無效判定化的第一次探索。如果您希望閱讀有關該技術的更多詳細資料,請閱讀位於 http://www.dotnetjunkies.com/Tutorial/A4ED5FD6-D385-4475-A357-27CF43A78205.dcik 的文章。

很多人已經使用過的另一種技術是,讓 SQL Server 在資料庫中的資料更改並且緩衝需要無效化時接觸外部檔案(檔案依賴項)。

這些技術的表現非常好,它們催生了許多出色的文章,並且非常適合於小型應用程式。但是,如果您要產生複雜的大型應用程式,那麼強烈建議您避免使用這些技術。舉個例子說,我們不會使用這些技術來開發自己的應用程式,例如,在 www.asp.net/forums 啟動並執行論壇,或我們要產生的名為 Community Server 的下一個版本 (www.communityserver.org)。

下面我們簡要討論一下為什麼這些現有技術存在缺陷 — 首先從擴充預存程序模型開始。

擴充預存程序 HTTP 推模型

擴充預存程序推模型使用以下體繫結構:

一個用來向緩衝中添加項並使該項依賴於某個資料庫通知的自訂類。

一個可以接收通知並使緩衝中的項無效的 HttpHandler。

被監視是否發生更改的資料庫中表上的觸發器。

資料庫中的一個表,用於對被監視是否發生更改的表以及在資料更改時要求通知的應用程式進行跟蹤。

一個擴充預存程序,用於調用應用程式的 HttpHandler 以通知其發生的更改。

當檢測到更改時,無論使用預存程序或觸發器中需要的哪個邏輯,都會調用一個更改通知預存程序。該更改通知過程檢索要向其通知更改的 Web 應用程式列表,然後對每個應用程式調用一個擴充預存程序,以便對該 Web 應用程式進行 HTTP 調用,以指示它移除特定的緩衝條目,從而將更改推送到該應用程式。Web 應用程式只是接收一個包含需要移除的緩衝鍵的 HTTP 要求。在內部,該應用程式只是用發送的緩衝鍵調用 Cache.Remove()

這聽起來很好,不是嗎?是的,而且它實際上能夠很好地工作。但下面是一些不利方面:

擴充預存程序對緩衝需要無效化的伺服器進行 HTTP 回調。預存程序作為更改資料庫內部資料的“原子”操作的一部分執行。它在表被修改時從觸發器中調用。與其他協議不同,HTTP 不是發後不理;相反,任何給定請求都期待響應。因此,擴充預存程序無法在 HTTP 調用完成之前完成。如果 Web 服務器位於慢速網路中或者需要花費較長的時間進行響應,則該延遲會妨礙資料庫操作完成。此妨礙會進一步導致 SQL Server 可能序列化其他 UPDATES/DELETE/INSERT,或者更糟糕的是,妨礙線程完成。現在,請將這一因素乘以伺服器陣列中伺服器的數量和資料庫操作的總數。

如果 Web 服務器在網路園模式(其中會建立多個進程以類比虛擬 Web 服務器)下運行,則沒有辦法指示如何將給定的請求分配給特定的進程。換句話說,在網路園模式下運行時,伺服器會為應用程式運行很多個虛擬 Web 服務器。當擴充預存程序回調到伺服器以通知它更改已經發生時,它沒有辦法確保所有虛擬 Web 服務器都能獲得通知。最後,您可能只更新了一個應用程式,而其他幾個應用程式卻未能同步。

如果您啟動並執行是小型伺服器環境,請不要在網路園模式下運行 Web 服務器,並且 SQL Server 不應該是系統中的爭用資源。擴充預存程序 HTTP 推模型能夠很好地工作,但是如果出現應用程式突然增長的情況,則可能會阻塞資料庫,或者陷入緩衝並不總是同步的情況。

檔案更新模型

第二種技術(無疑比另一種技術更簡單)在資料更改時更新檔案,而不是試圖使用 HTTP 回調到應用程式。ASP.NET 應用程式開發人員使用標準的快取檔案更改依賴項來監視檔案更改,當檔案更改時,緩衝的項會被移除。

該技術不存在與擴充預存程序推模型有關的網路園問題,但是它存在很多與擴充預存程序技術有關的相同阻塞問題。另外,它引入了自己的特性:

在使用該技術時,檔案爭用成為一個問題,因為當“更改”檔案沒有被另外的伺服器用戶端檔案鎖時,SQL Server 可以只更新該檔案。因此,需要通知更改的資料庫中的所有更改都必須相互協調以鎖定該檔案,更改一些值,然後取消鎖定該檔案。換句話說,資料庫可序列化針對該檔案進行的工作。這裡面臨的問題仍然是 SQL Server 上可能發生的序列化和阻塞問題。

在使用該技術時,檔案更改通知也會成為一個問題,因為要在 Web 場中使用變更檔,必須將其放到共用中,並且將正確的安全許可權授予各種 Web 服務器,以便其查看該共用並監視檔案更改。

檔案更新模型能夠很好地用於小型伺服器環境,支援網路園,並且適合於 SQL Server 不是系統爭用資源的情況。實際上,它可能是一種更好的選擇,因為它比擴充預存程序解決方案簡單得多。但是,在較大的伺服器環境或資料庫已經是系統選通資源的環境中,該模型會崩潰。

正如您看到的那樣,這兩種技術都具有適用性,但是您需要根據是否可以基於伺服器大小和負載使用這些技術做出良好決策。每當您將已知的阻塞操作引入到應用程式中的時候,都會添加潛在的延展性和效能瓶頸。

資料庫快取無效判定化:ASP.NET 2.0 樣式

擴充預存程序快取無效判定化模型的原始目標是,開始對資料庫快取無效判定化問題進行一些早期的原型化工作。ASP.NET 團隊知道,該功能是他們希望在版本 2.0 中解決的一個問題,但是他們需要更好地瞭解如何以可伸縮的方式產生該功能。

實際上,作為一家公司,Microsoft 知道這有多麼重要,並且在 ASP.NET、IIS、SQL Server、ADO.NET 和 ISA 伺服器等團隊的基礎上成立了一個新的團隊,稱為 The Caching Taskforce

我的有關 Bill Gates 會議的部落格張貼專門用於使他瞭解我們在 ASP.NET/Yukon 實現中完成的工作。您可以在 http://weblogs.asp.net/rhoward/archive/2003/04/28/6128.aspx 閱讀該文章。

該緩衝工作群組的成績是兩個新的資料庫快取無效判定化體繫結構。第一個被設計到系統中,並且只是 ASP.NET、ADO.NET 和 SQL Server 2005 的一部分。它在超粒度層級產生了推通知的可伸縮模型。例如,當特定預存程序的特定結果更改時,請通知我。快取無效判定化的 SQL Server 2005 實現無法在 .NET Framework 版本 1.1 中鏡像或實現。我們將在以後的文章中討論該系統如何工作。建立第二種技術的目的是支援 SQL Server 7.0 和 SQL Server 2000 的資料庫快取無效判定化。顯然,無法向資料庫中添加任何東西,因此我們必須在當今技術的約束範圍內工作。好訊息是,目前可以通過 ASP.NET 1.1 實現與用於 SQL Server 7.0 和 SQL Server 2000 支援的完全相同的技術。

我們還沒有到嗎?

我們都在電視上看到過,如果您有孩子的話,恐怕已經親身體驗過,當孩子坐在汽車中前往某個夢寐已久的地方時,會不停地詢問是否已經到達目的地。而此時,它們也是在不停地輪詢,直到收到所需的響應為止。

類似地,用於 SQL Server 7.0 和 SQL Server 2000 的資料庫快取無效判定化技術會輪詢資料庫,以檢查是否發生了更改。在這裡,無意識的反應通常是消極的 — 難道輪詢不是一件糟糕的事情嗎?但是,一旦您瞭解有關正在發生的事情的更多資訊,該設計的簡單性和延展性就會立即呈現在您的面前。

對於任何資料庫快取無效判定化系統而言,都必須克服兩個較大的問題:

防止資料庫發生阻塞:資料庫儘可能地快速和高效是極為重要的,因此在資料更改期間必須避免發生阻塞和序列化。從根本上說來,資料庫的目的是有效地管理對資料的訪問並允許進行這種訪問。

確保緩衝一致性:如果一個解決方案只能保證將通知發送到在網路園模式下啟動並執行 Web 服務器中的單個虛擬伺服器,則該解決方案是沒有用的。所有應用程式都必須能夠在資料更改時收到通知。

產生輪詢模型的前提是:輪詢資料庫的成本大大低於重新執行原始查詢的成本。此外,輪詢不應當在請求線程上發生,而是應該作為後台操作發生。

這裡,一個良好的方案是 Community Server。Community Server 是一個複雜的應用程式,它使用很多標準化的表將相關資料結合在一起來滿足請求。一種常見的任務是通過預存程序檢索分頁的資料集,以便顯示特定論壇中的線程的分頁檢視。滿足分頁線程視圖請求的預存程序執行一系列從 3 到 5 個表中聯結的選擇語句,建立一個暫存資料表,從該暫存資料表中進行選擇,然後執行另一次聯結。換句話說,必鬚髮生以滿足某個請求的資料轉換完全是一個操作。

通過 ASP.NET 2.0 中使用的資料庫快取無效判定化模型(我們稍後將實現該模型),我們在資料庫中建立了一個更改通知表。最初請求的資料緩衝在應用程式層級,在這裡可以快速地檢索資料,並且應用程式層每隔幾秒鐘就會輪詢資料庫以確定資料是否發生了更改。與原始請求不同,輪詢將訪問其行深度不大於資料庫中表的數量的單個表。輪詢操作從該更改通知表中檢索所有記錄。很可能的情況是,該表非常小,以至於可以將全部結果分頁到 SQL 中的記憶體中並快速地進行訪問。

隨後,將在應用程式層內部分析該更改通知表的結果。結果集是資料庫中每個表的更改 ID 的列表。如果更改 ID 值不同於當前緩衝的更改 ID,則會無效化相關的緩衝條目,對下一個請求使用完全尋找操作(因為資料不在緩衝中),並且重新填充緩衝,之後該進程將重新啟動。圖 1 顯示了該體繫結構的工作方式。

1. 體繫結構關係圖

該輪詢機制利用的一個極為重要的方面是,輪詢發生在與執行請求的線程不同的後台線程中。因此,如果可以從緩衝中提供結果,則在進行請求時,絕不會訪問資料庫。但是,一旦檢測到更改,條目將從緩衝中移除,下一個請求將正常執行並重新填充緩衝,並且重新啟動系統, 2 所示。

2. 更改後的體繫結構關係圖

為了在後台線程中完成輪詢,我們將利用 .NET Framework 中我最喜歡但鮮為人知的一個類 — TimerTimer 類位於 System.Threading 命名空間中。通過 Timer 可以完成的工作是,建立一個按照以編程方式確定的時間間隔定期引發的事件。當 Timer 被喚醒時,它會從當前應用程式定義域的線程池中抓取一個線程,並引發一個事件。我們的代碼就是在該事件內部定期運行,以驗證資料庫中的更改或缺少更改的情況。

後台服務類

我們使用 Community Server 中的這一相同技術,按照預先設定的時間間隔(而不是針對每個請求)來寄送電子郵件或者編製張貼索引。這已經為我們節省了在添加新張貼的請求中花費的大量時間,因為在以前,我們是在每次添加新張貼時執行上述操作的。

在 Community Server 中,我們使用 Timer 作為 HttpModule 內部的靜態執行個體。當 ASP.NET 應用程式初始化時,會執行個體化靜態計時器並確定輪詢內部周期。當輪詢事件引發時,我們執行下列操作:

執行必要的 SQL 以便從資料庫中接收一系列更改 ID。

將資料庫中的更改 ID 與 ASP.NET 緩衝中儲存的相應值進行比較。緩衝中不匹配的值被更新,這會將依賴項強行從緩衝中移除。

從我的 Microsoft Tech Ed 2004 簡報(它位於 http://www.rob-howard.net)的 Blackbelt Slides and Demos 中,您可以下載資料庫快取無效判定化的完全有效樣本。

該特定範例程式碼片段適用於 SQL Server 隨附的 Northwind 樣本資料庫。在使用它之前,您還需要對該資料庫進行一些更改。

首先,您需要添加 ChangeNotification 表:

CREATE TABLE [dbo].[ChangeNotification] (   [Table] [nvarchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,   [ChangeID] [int] NOT NULL )

其次,您需要向 Products 表中添加一個觸發器:

CREATE TRIGGER [ChangeNotificationTrigger] ON [dbo].[Products] FOR INSERT, UPDATE, DELETE ASUPDATE   ChangeNotificationSET   ChangeID = ChangeID + 1WHERE   [Table] = 'Products' 

每當 Products 表被修改時,都會應用該觸發器,從而更新 ChangeNotification 表中的行。

儘管這是一個極為簡單的樣本,但如果您希望為自己的應用程式實現上述功能,則該樣本可以提供一個良好的起點。該樣本中未解決的一些缺點包括:

僅限於表層級更改:為視圖甚至行層級更改修改這一點並不十分困難。

行鎖定:需要添加更新邏輯,以顧及對 Products 表進行的大型修改。例如,更新 100 種產品會導致對 ChangeNotification 表進行 100 個更改。與 ASP.NET 2.0 隨附的版本類似,您可能會希望添加一些邏輯,以便更好地處理大型更新。

小結

ASP.NET 的緩衝系統是所有 ASP.NET 開發人員都應當努力使用的一項功能。請儘早計劃使用緩衝,並瞭解應用程式的哪些方面可以大大協助您最佳地使用緩衝。幾個 ASP.NET 1.1 限制(例如,資料庫快取無效判定化)可以通過使用一些與 ASP.NET 2.0 中使用的相同的技術予以克服。本文中對 Timer 類的使用說明了實現該目標的一種可能方式,而且,儘管還有其他多個選擇,我們仍然建議您使用該輪詢技術。我認為您還會發現,Timer 類對於其他問題的解決也很有用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.