新聞中心
從以前的 “classic” ASP 到目前的 ASP.NET 4.5 Web Forms,很多開(kāi)發(fā)者依賴ASP.NET 會(huì)話狀態(tài)作為重要的臨時(shí)保存每個(gè)用戶的數(shù)據(jù)的主要手段。 它的特征是在用戶訪問(wèn)web應(yīng)用程序的過(guò)程中,允許開(kāi)發(fā)者存儲(chǔ)和讀取用戶的數(shù)據(jù)。 會(huì)話數(shù)據(jù)是自動(dòng)從存儲(chǔ)中持續(xù)保存和恢復(fù),并且自動(dòng)過(guò)期刪除。

創(chuàng)新互聯(lián)建站自成立以來(lái),一直致力于為企業(yè)提供從網(wǎng)站策劃、網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、電子商務(wù)、網(wǎng)站推廣、網(wǎng)站優(yōu)化到為企業(yè)提供個(gè)性化軟件開(kāi)發(fā)等基于互聯(lián)網(wǎng)的全面整合營(yíng)銷(xiāo)服務(wù)。公司擁有豐富的網(wǎng)站建設(shè)和互聯(lián)網(wǎng)應(yīng)用系統(tǒng)開(kāi)發(fā)管理經(jīng)驗(yàn)、成熟的應(yīng)用系統(tǒng)解決方案、優(yōu)秀的網(wǎng)站開(kāi)發(fā)工程師團(tuán)隊(duì)及專業(yè)的網(wǎng)站設(shè)計(jì)師團(tuán)隊(duì)。
問(wèn)題
使用Session State的替代方案這些內(nèi)容超出了本文的范圍。 對(duì)于依賴Session State的應(yīng)用程序也有陷阱,最常見(jiàn)的是訪問(wèn)每個(gè)用戶,每個(gè)請(qǐng)求的Session基礎(chǔ)數(shù)據(jù)。這種獨(dú)特的訪問(wèn)是維持Session State的一致性的一種方式,并且是通過(guò)設(shè)計(jì)實(shí)現(xiàn)了這種方式。 如果你對(duì)這樣殘暴細(xì)節(jié)的設(shè)計(jì)感興趣, 他們?cè)陬}名為“鎖定會(huì)話狀態(tài)數(shù)據(jù)”章節(jié)這里解釋了。會(huì)話狀態(tài)常見(jiàn)于ASP.NET Web窗體應(yīng)用程序,而ASP.NET MVC在較小程度上使用了TempData(POST數(shù)據(jù)到GET作為例子) 。
Web應(yīng)用程序主要利用Session狀態(tài)來(lái)協(xié)調(diào)彼此間的工作。作為對(duì)比,客戶端腳本較多的重量級(jí)web應(yīng)用通常擁有更高的并發(fā)請(qǐng)求,這種情況下使用Session狀態(tài)訪問(wèn)資源需要對(duì)Session加鎖和解鎖,從而成為了Web應(yīng)用的瓶頸。不限制類型的Web應(yīng)用將會(huì)成為另外一個(gè)瓶頸因?yàn)樾枰銐虻拇鎯?chǔ)空間維持它們的會(huì)話的狀態(tài)。有三種途徑優(yōu)化Session狀態(tài)的訪問(wèn),使得一些請(qǐng)求可以不需要session或者使用只讀的,但是如果加載后應(yīng)用規(guī)模持續(xù)增大,最終仍然會(huì)有瓶頸。
目前的狀況
基于這些考慮目前的ASP.NET的會(huì)話狀態(tài)仍然使用的非常普遍。在許多領(lǐng)域我不斷看到許多消費(fèi)者在有大量擴(kuò)展的Web應(yīng)用中使用會(huì)話狀態(tài)。對(duì)大量企業(yè)級(jí)用戶而言,內(nèi)部使用ASP.NET窗體應(yīng)用更為普遍。對(duì)于這些消費(fèi)者而言,如何選擇Session State存儲(chǔ)提供商是相當(dāng)關(guān)鍵的。這些提供商必須將Session字典的內(nèi)容序列化存儲(chǔ)在耐用的設(shè)備上并反序列化從中提取數(shù)據(jù)(通常使用BLOB應(yīng)用程序)。這里有許多提供商可供選擇,包括Microsoft和第三方開(kāi)發(fā)者提供的工具。目前Microsoft提供了下面的Session存儲(chǔ)工具,假定ASP.NET應(yīng)用部署在企業(yè)內(nèi)部:
Session Provider | Can be Highly Available? | Can be Geo Redundant? | Can be used in Web Farms? | Performance? |
In-Proc | No | No | No | Excellent |
State Server | No | No | Yes | Good |
SQL Server (Traditional) | Yes | Yes | Yes | Fair |
AppFabric Caching | Yes | No | Yes | Good |
SQL Server (In-Memory) | Yes* | Yes | Yes | Excellent |
*需要在 in-memory表中將模式和數(shù)據(jù)標(biāo)記為持久的
如果你的應(yīng)用程序需要Session State高可用,同時(shí)支持跨web farm的部署,你可以從Microsoft提供的選項(xiàng),僅限于SQL Server或者AppFabric Caching.SQL Server有一個(gè)增加的優(yōu)勢(shì),它可以跨越數(shù)據(jù)中心來(lái)提供地理冗余(geo-redundancy).而AppFabric則受限于單一數(shù)據(jù)中心.實(shí)際應(yīng)用中,這兩種解決方案都工作良好.但是,傳統(tǒng)的SQL Server實(shí)現(xiàn)常常遇到瓶頸,產(chǎn)生的原因是基于單一磁盤(pán)的表存在競(jìng)爭(zhēng).競(jìng)爭(zhēng)導(dǎo)致阻塞,死鎖,或者其它不友好的變化.這影響了它存儲(chǔ)和恢復(fù)會(huì)話的時(shí)間.另外,在刪除操作過(guò)程中,當(dāng)先前的會(huì)話數(shù)據(jù)由于鎖的擴(kuò)大和競(jìng)爭(zhēng)的延續(xù)而清除了,這也會(huì)存在問(wèn)題.
SQL Server 2014的新選項(xiàng)
為了解決老版本SQL Server安裝包的性能問(wèn)題,SQL Server團(tuán)隊(duì)最近發(fā)布了新的安裝包“Microsoft ASP.NET Session State provider for SQL Sever In-Memory”作為NugGet包.在this case study中有這個(gè)安裝包不可思議的性能提升的證明.它在ASP.NET應(yīng)用程序中使用Session State,每秒處理250,000個(gè)請(qǐng)求!這個(gè)新實(shí)現(xiàn)使用了SQL Server 2014稱為"Hekaton"的內(nèi)存優(yōu)化表特性.這需要這個(gè)產(chǎn)品的2014版本.這個(gè)安裝包如何在老版本SQL Server會(huì)話狀態(tài)安裝包上有所提升的呢?
-
會(huì)話存儲(chǔ)的持續(xù)性是通過(guò)內(nèi)存優(yōu)化表而不是磁盤(pán)表.對(duì)于繁重的訪問(wèn)模型,如存儲(chǔ)會(huì)話狀態(tài)等,內(nèi)存優(yōu)化表是全事務(wù)的,可持續(xù)性和理想的.這類表使用無(wú)鎖數(shù)據(jù)結(jié)構(gòu)和優(yōu)化的,多版本的并發(fā)控制.
-
為了更進(jìn)一步提升性能,可用本地編譯存儲(chǔ)過(guò)程來(lái)恢復(fù)和存儲(chǔ)會(huì)話數(shù)據(jù). 本質(zhì)上,這是一種新型的存儲(chǔ)過(guò)程,它被編譯為本地機(jī)器代碼.
這兩個(gè)SQL 2014產(chǎn)品特性,解決了主要的性能和競(jìng)爭(zhēng)問(wèn)題,這些問(wèn)題存在于基于磁盤(pán)實(shí)現(xiàn)的舊的傳統(tǒng)的SQL Server安裝包.安裝和配置這個(gè)程序是相當(dāng)直接的.通過(guò)NuGet包管理控制臺(tái),可以按照下面的方式安裝:
Install-Package Microsoft.Web.SessionState.SqlInMemory.
在你的應(yīng)用程序中,NuGet包將增加一個(gè)到Microsoft.Web.SessionState.SqlInMemory的引用,同時(shí)也會(huì)增加一個(gè)名為ASPStateInMemory.sql的腳本文件來(lái)安裝SQL Server 2014 Session State數(shù)據(jù)庫(kù).這個(gè)文件包含了必須的DDL來(lái)安裝數(shù)據(jù)庫(kù).在SQL腳本中有一些項(xiàng),你想要審查或者最可能審查或修改的:
-
這個(gè)數(shù)據(jù)庫(kù)的名字默認(rèn)是ASPStateInMemory.
-
數(shù)據(jù)庫(kù)的主文件組路徑.
-
數(shù)據(jù)庫(kù)的MEMORY_OPTIMIZED_DATA文件組路徑.
-
BUCKET_COUNT的大小信息,它基于會(huì)話中的項(xiàng)的預(yù)期大小.
-
讓會(huì)話中的表可持久或非可持久的決定(涉及到是否需要會(huì)話高可用)
以上的第五個(gè)部分,需要對(duì)已經(jīng)存在的SQL Server會(huì)話數(shù)據(jù)庫(kù)作一些分析,它可能像計(jì)算傳統(tǒng)ASP.NET SQL Server會(huì)話模式里BLOB列的DATALENGTH()一樣簡(jiǎn)單.對(duì)于InProc或者StateServer來(lái)說(shuō),決定會(huì)話項(xiàng)的平均大小會(huì)更加困難,但可以通過(guò)捕獲w3wp.exe或者StateServer進(jìn)程的內(nèi)存dump來(lái)實(shí)現(xiàn),其間檢查在會(huì)話字典中的項(xiàng)的數(shù)目和大小.對(duì)于InProc或者StateServer,關(guān)于會(huì)話中的項(xiàng)的數(shù)目,有性能計(jì)數(shù).***的建議總是測(cè)試和調(diào)整.
讓基于內(nèi)存的會(huì)話高可用
默認(rèn),SQL Server 2014基于內(nèi)存會(huì)話的內(nèi)存優(yōu)化表是標(biāo)記為非持久的.這意味著,這些表里的數(shù)據(jù)變化是過(guò)渡性的一致.這些變化沒(méi)有記錄在日志中,這意味著如果SQL Server重啟了,服務(wù)器重啟了或者任何形式的故障恢復(fù)發(fā)生(FCI或者AlwaysOn),所有的會(huì)話數(shù)據(jù)將丟失.設(shè)置這個(gè)默認(rèn)值是因?yàn)樾阅?為了讓這些內(nèi)存優(yōu)化表可持續(xù),需要在ASPStateInMemory.sql腳本中做三點(diǎn)改變.在腳本中有一些注釋解釋了為何需要做這些改變.
-
按下面的方式修改SessionItems表.
-
修改WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY)
-
為WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_AND_DATA)
-
取消語(yǔ)句的注釋(注意***的逗號(hào)): Id bigint IDENTITY,
-
取消語(yǔ)句的注釋(注意***的逗號(hào),根據(jù)需要修改1000000 * 2為real值,在這個(gè)語(yǔ)句前讀T-SQL注釋以選擇一個(gè)起始值): CONSTRAINT [PK_SessionItems_Id] PRIMARY KEY NONCLUSTERED HASH (Id) WITH (BUCKET_COUNT = 2000000),
-
-
修改會(huì)話表
-
修改WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY
-
為WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_AND_DATA)
-
只要做了這些修改,我們可以讓數(shù)據(jù)庫(kù)成為部分SQL Server AlwaysOn可用性組.當(dāng)故障恢復(fù)時(shí),會(huì)話數(shù)據(jù)將會(huì)保留.由于增加的重試邏輯,所以,當(dāng)一個(gè)自動(dòng)的或者人為的故障恢復(fù)發(fā)生時(shí),連接池中的過(guò)期連接不會(huì)產(chǎn)生異常拋出給終端用戶.
請(qǐng)注意,即使我們?cè)O(shè)置表為非可持續(xù)的,將會(huì)話數(shù)據(jù)庫(kù)放入SQL Server AlwaysOn可用性組,但會(huì)話表中的數(shù)據(jù)在復(fù)制(只有schema可用)時(shí)不可用.對(duì)于客戶負(fù)荷,這個(gè)"schema only"復(fù)制模型,通過(guò)使用非可持續(xù)內(nèi)存優(yōu)化表,已足夠來(lái)保證性能提升.
這個(gè)最簡(jiǎn)單的高可用的拓?fù)鋵?duì)SQL Server In-Memory來(lái)說(shuō)是最合適的,它與下面的類似:
-
位于子網(wǎng)(數(shù)據(jù)中心)A的SQL Server 2014 Node 1
-
位于子網(wǎng)(數(shù)據(jù)中心)B的SQL Server 2014 Node 2
-
位于子網(wǎng)(數(shù)據(jù)中心)C的文件共享
這個(gè)拓?fù)涮峁┝说乩砣哂?自動(dòng)故障恢復(fù)和維持了1/3的數(shù)據(jù)中心完整的丟失連接.Windows Server 2012 R2的動(dòng)態(tài)特性,使得自動(dòng)維持2個(gè)數(shù)據(jù)中心的丟失連接成為可能.(***的男人的場(chǎng)景[last man standing scenario]).
ASP.NET 配置文件
在 ASP.NET web 應(yīng)用程序的配置文件web.config中,配置一個(gè)新的provider,并且按照下面編輯它。
connectionString="Data Source=AGAspNet; Initial Catalog=ASPStateInMemory;Integrated Security=True;" />
在上面的代碼片段中, ‘AGAspNet’ 是SQL Server 2014 中永遠(yuǎn)可用的監(jiān)聽(tīng)者名字。
一個(gè)快速的例子
使用ASP.NET網(wǎng)頁(yè)表單4.5應(yīng)用,并在會(huì)話中編寫(xiě)簡(jiǎn)單的帶有時(shí)間戳的字符串,SQL Server 2014中便生成如下的數(shù)據(jù):
注意在SQLNode1-2014中,AspStateInMemory數(shù)據(jù)庫(kù)的位置.接下來(lái),我們手動(dòng)進(jìn)行故障恢復(fù)可用性組.
在SQLNode2-2014上,會(huì)話現(xiàn)在可用了,而且不會(huì)干擾ASP.NET應(yīng)用程序.簡(jiǎn)單的敲擊web應(yīng)用程序的F5,以獲取來(lái)自會(huì)話的數(shù)據(jù),而不會(huì)向客戶端拋出異常.
過(guò)期會(huì)話會(huì)怎么樣呢?
在舊的SQL Server會(huì)話中,一個(gè)SQL Agent作業(yè)創(chuàng)建后用來(lái)刪除過(guò)期會(huì)話.在新版本中,提供了一個(gè)必須被作業(yè)調(diào)用的存儲(chǔ)過(guò)程[dbo].[DeleteExpiredSessions].默認(rèn),會(huì)話超時(shí)時(shí)間為20分鐘.每次一個(gè)會(huì)話項(xiàng)被訪問(wèn),超時(shí)被重置以保持用戶會(huì)話“存活”.
概述
在新的會(huì)話狀態(tài)中,有許多有意思的細(xì)節(jié).我鼓勵(lì)你為自己而深入研究代碼.你將會(huì)發(fā)現(xiàn)它是一段奇妙的學(xué)習(xí)旅程,其間是關(guān)于SQL Server 2014 基于內(nèi)存的OLTP "Hekaton"特性的性能和限制.一個(gè)特別的屬性包含在代碼中,以模擬內(nèi)存中存儲(chǔ)BLOB類型的數(shù)據(jù).內(nèi)存優(yōu)化表現(xiàn)在不支持BLOB類型.序列化的會(huì)話字典和可能的大BLOB數(shù)據(jù)類型有什么不同呢?其中使用的預(yù)處理程序(sprocs)將序列化的會(huì)話分拆為7000字節(jié)的數(shù)據(jù)塊,以增強(qiáng)大的會(huì)話項(xiàng)數(shù)據(jù)的存儲(chǔ).
精明的讀者可能已經(jīng)發(fā)現(xiàn),在我的屏幕截圖中, [SessionItems]表中并沒(méi)有數(shù)據(jù)行,但在[Sessions]表中有一行數(shù)據(jù).如果我的會(huì)話內(nèi)容超過(guò)了7000字節(jié),你應(yīng)該會(huì)在[SessionItems]表中看到"溢出"(spill over)行.關(guān)于這方面,在ASP.NET會(huì)話存儲(chǔ)之外,有許多其它潛在的應(yīng)用程序,我很可能在下一篇文章中深入挖掘這點(diǎn).
本地編譯存儲(chǔ)過(guò)程也值得一看.有一些技巧來(lái)處理本地編譯存儲(chǔ)過(guò)程的限制,如缺少CASE語(yǔ)句的支持.這個(gè)限制是因?yàn)?只要預(yù)處理程序(sproc)編譯為本地代碼,是不允許進(jìn)行分支的!
如果你在考慮使用這個(gè)新特性,有如下關(guān)鍵點(diǎn)和問(wèn)題需要考慮:
-
內(nèi)存優(yōu)化表由內(nèi)存來(lái)支撐!你的SQL Server在峰值負(fù)載時(shí),有足夠的內(nèi)存來(lái)包含所有的會(huì)話數(shù)據(jù)嗎?
-
默認(rèn)表是非可持久的.請(qǐng)仔細(xì)考慮你的高可用性的需求.不管是可持久還是非可持久,性能將超出你現(xiàn)在使用的傳統(tǒng)SQL Server數(shù)據(jù)庫(kù)的會(huì)話和模式.
-
閱讀SQL文件中的注釋,調(diào)整BUCKET_COUNT為非簇集HASH索引.以下是SessionItems表DDL語(yǔ)句的代碼片段.
祝你好運(yùn)!請(qǐng)?jiān)谠u(píng)論中分享你使用新版本的經(jīng)驗(yàn)!
英文原文:ASP.NET Session State using SQL Server In-Memory
譯文出自:http://www.oschina.net/translate/asp-net-session-state-using-sql-sever-in-memory
名稱欄目:使用SQLServerIn-Memory存儲(chǔ)ASP.NET的會(huì)話狀態(tài)
本文網(wǎng)址:http://fisionsoft.com.cn/article/coshhhe.html


咨詢
建站咨詢
