如何讓使用SQL Server In-Memory存儲ASP.NET的會話狀態(tài),針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、壺關(guān)網(wǎng)站維護(hù)、網(wǎng)站推廣。
從以前的 “classic” ASP 到目前的 ASP.NET 4.5 Web Forms,很多開發(fā)者依賴ASP.NET 會話狀態(tài)作為重要的臨時(shí)保存每個(gè)用戶的數(shù)據(jù)的主要手段。 它的特征是在用戶訪問web應(yīng)用程序的過程中,允許開發(fā)者存儲和讀取用戶的數(shù)據(jù)。 會話數(shù)據(jù)是自動(dòng)從存儲中持續(xù)保存和恢復(fù),并且自動(dòng)過期刪除。
問題
使用Session State的替代方案這些內(nèi)容超出了本文的范圍。 對于依賴Session State的應(yīng)用程序也有陷阱,最常見的是訪問每個(gè)用戶,每個(gè)請求的Session基礎(chǔ)數(shù)據(jù)。這種獨(dú)特的訪問是維持Session State的一致性的一種方式,并且是通過設(shè)計(jì)實(shí)現(xiàn)了這種方式。 如果你對這樣殘暴細(xì)節(jié)的設(shè)計(jì)感興趣, 他們在題名為“鎖定會話狀態(tài)數(shù)據(jù)”章節(jié)這里解釋了。會話狀態(tài)常見于ASP.NET Web窗體應(yīng)用程序,而ASP.NET MVC在較小程度上使用了TempData(POST數(shù)據(jù)到GET作為例子) 。
Web應(yīng)用程序主要利用Session狀態(tài)來協(xié)調(diào)彼此間的工作。作為對比,客戶端腳本較多的重量級web應(yīng)用通常擁有更高的并發(fā)請求,這種情況下使用Session狀態(tài)訪問資源需要對Session加鎖和解鎖,從而成為了Web應(yīng)用的瓶頸。不限制類型的Web應(yīng)用將會成為另外一個(gè)瓶頸因?yàn)樾枰銐虻拇鎯臻g維持它們的會話的狀態(tài)。有三種途徑優(yōu)化Session狀態(tài)的訪問,使得一些請求可以不需要session或者使用只讀的,但是如果加載后應(yīng)用規(guī)模持續(xù)增大,最終仍然會有瓶頸。
目前的狀況
基于這些考慮目前的ASP.NET的會話狀態(tài)仍然使用的非常普遍。在許多領(lǐng)域我不斷看到許多消費(fèi)者在有大量擴(kuò)展的Web應(yīng)用中使用會話狀態(tài)。對大量企業(yè)級用戶而言,內(nèi)部使用ASP.NET窗體應(yīng)用更為普遍。對于這些消費(fèi)者而言,如何選擇Session State存儲提供商是相當(dāng)關(guān)鍵的。這些提供商必須將Session字典的內(nèi)容序列化存儲在耐用的設(shè)備上并反序列化從中提取數(shù)據(jù)(通常使用BLOB應(yīng)用程序)。這里有許多提供商可供選擇,包括Microsoft和第三方開發(fā)者提供的工具。目前Microsoft提供了下面的Session存儲工具,假定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ù)據(jù)中心來提供地理冗余(geo-redundancy).而AppFabric則受限于單一數(shù)據(jù)中心.實(shí)際應(yīng)用中,這兩種解決方案都工作良好.但是,傳統(tǒng)的SQL Server實(shí)現(xiàn)常常遇到瓶頸,產(chǎn)生的原因是基于單一磁盤的表存在競爭.競爭導(dǎo)致阻塞,死鎖,或者其它不友好的變化.這影響了它存儲和恢復(fù)會話的時(shí)間.另外,在刪除操作過程中,當(dāng)先前的會話數(shù)據(jù)由于鎖的擴(kuò)大和競爭的延續(xù)而清除了,這也會存在問題.
為了解決老版本SQL Server安裝包的性能問題,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è)請求!這個(gè)新實(shí)現(xiàn)使用了SQL Server 2014稱為"Hekaton"的內(nèi)存優(yōu)化表特性.這需要這個(gè)產(chǎn)品的2014版本.這個(gè)安裝包如何在老版本SQL Server會話狀態(tài)安裝包上有所提升的呢?
會話存儲的持續(xù)性是通過內(nèi)存優(yōu)化表而不是磁盤表.對于繁重的訪問模型,如存儲會話狀態(tài)等,內(nèi)存優(yōu)化表是全事務(wù)的,可持續(xù)性和理想的.這類表使用無鎖數(shù)據(jù)結(jié)構(gòu)和優(yōu)化的,多版本的并發(fā)控制.
為了更進(jìn)一步提升性能,可用本地編譯存儲過程來恢復(fù)和存儲會話數(shù)據(jù). 本質(zhì)上,這是一種新型的存儲過程,它被編譯為本地機(jī)器代碼.
這兩個(gè)SQL 2014產(chǎn)品特性,解決了主要的性能和競爭問題,這些問題存在于基于磁盤實(shí)現(xiàn)的舊的傳統(tǒng)的SQL Server安裝包.安裝和配置這個(gè)程序是相當(dāng)直接的.通過NuGet包管理控制臺,可以按照下面的方式安裝:
Install-Package Microsoft.Web.SessionState.SqlInMemory.
在你的應(yīng)用程序中,NuGet包將增加一個(gè)到Microsoft.Web.SessionState.SqlInMemory的引用,同時(shí)也會增加一個(gè)名為ASPStateInMemory.sql的腳本文件來安裝SQL Server 2014 Session State數(shù)據(jù)庫.這個(gè)文件包含了必須的DDL來安裝數(shù)據(jù)庫.在SQL腳本中有一些項(xiàng),你想要審查或者最可能審查或修改的:
這個(gè)數(shù)據(jù)庫的名字默認(rèn)是ASPStateInMemory.
數(shù)據(jù)庫的主文件組路徑.
數(shù)據(jù)庫的MEMORY_OPTIMIZED_DATA文件組路徑.
BUCKET_COUNT的大小信息,它基于會話中的項(xiàng)的預(yù)期大小.
讓會話中的表可持久或非可持久的決定(涉及到是否需要會話高可用)
以上的第五個(gè)部分,需要對已經(jīng)存在的SQL Server會話數(shù)據(jù)庫作一些分析,它可能像計(jì)算傳統(tǒng)ASP.NET SQL Server會話模式里BLOB列的DATALENGTH()一樣簡單.對于InProc或者StateServer來說,決定會話項(xiàng)的平均大小會更加困難,但可以通過捕獲w3wp.exe或者StateServer進(jìn)程的內(nèi)存dump來實(shí)現(xiàn),其間檢查在會話字典中的項(xiàng)的數(shù)目和大小.對于InProc或者StateServer,關(guān)于會話中的項(xiàng)的數(shù)目,有性能計(jì)數(shù).***的建議總是測試和調(diào)整.
默認(rèn),SQL Server 2014基于內(nèi)存會話的內(nèi)存優(yōu)化表是標(biāo)記為非持久的.這意味著,這些表里的數(shù)據(jù)變化是過渡性的一致.這些變化沒有記錄在日志中,這意味著如果SQL Server重啟了,服務(wù)器重啟了或者任何形式的故障恢復(fù)發(fā)生(FCI或者AlwaysOn),所有的會話數(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)
取消語句的注釋(注意***的逗號): Id bigint IDENTITY,
取消語句的注釋(注意***的逗號,根據(jù)需要修改1000000 * 2為real值,在這個(gè)語句前讀T-SQL注釋以選擇一個(gè)起始值): CONSTRAINT [PK_SessionItems_Id] PRIMARY KEY NONCLUSTERED HASH (Id) WITH (BUCKET_COUNT = 2000000),
修改會話表
修改WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY
為WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_AND_DATA)
只要做了這些修改,我們可以讓數(shù)據(jù)庫成為部分SQL Server AlwaysOn可用性組.當(dāng)故障恢復(fù)時(shí),會話數(shù)據(jù)將會保留.由于增加的重試邏輯,所以,當(dāng)一個(gè)自動(dòng)的或者人為的故障恢復(fù)發(fā)生時(shí),連接池中的過期連接不會產(chǎn)生異常拋出給終端用戶.
請注意,即使我們設(shè)置表為非可持續(xù)的,將會話數(shù)據(jù)庫放入SQL Server AlwaysOn可用性組,但會話表中的數(shù)據(jù)在復(fù)制(只有schema可用)時(shí)不可用.對于客戶負(fù)荷,這個(gè)"schema only"復(fù)制模型,通過使用非可持續(xù)內(nèi)存優(yōu)化表,已足夠來保證性能提升.
這個(gè)最簡單的高可用的拓?fù)鋵QL Server In-Memory來說是最合適的,它與下面的類似:
位于子網(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ù)中心的丟失連接成為可能.(***的男人的場景[last man standing scenario]).
在 ASP.NET web 應(yīng)用程序的配置文件web.config中,配置一個(gè)新的provider,并且按照下面編輯它。
<sessionState mode="Custom" customProvider="SqlInMemoryProvider">
<providers>
<add name="SqlInMemoryProvider"
type="Microsoft.Web.SessionState.SqlInMemoryProvider"
connectionString="Data Source=AGAspNet; Initial Catalog=ASPStateInMemory;Integrated Security=True;" />
</providers>
</sessionState>
在上面的代碼片段中, ‘AGAspNet’ 是SQL Server 2014 中永遠(yuǎn)可用的監(jiān)聽者名字。
使用ASP.NET網(wǎng)頁表單4.5應(yīng)用,并在會話中編寫簡單的帶有時(shí)間戳的字符串,SQL Server 2014中便生成如下的數(shù)據(jù):
注意在SQLNode1-2014中,AspStateInMemory數(shù)據(jù)庫的位置.接下來,我們手動(dòng)進(jìn)行故障恢復(fù)可用性組.
在SQLNode2-2014上,會話現(xiàn)在可用了,而且不會干擾ASP.NET應(yīng)用程序.簡單的敲擊web應(yīng)用程序的F5,以獲取來自會話的數(shù)據(jù),而不會向客戶端拋出異常.
在舊的SQL Server會話中,一個(gè)SQL Agent作業(yè)創(chuàng)建后用來刪除過期會話.在新版本中,提供了一個(gè)必須被作業(yè)調(diào)用的存儲過程[dbo].[DeleteExpiredSessions].默認(rèn),會話超時(shí)時(shí)間為20分鐘.每次一個(gè)會話項(xiàng)被訪問,超時(shí)被重置以保持用戶會話“存活”.
在新的會話狀態(tài)中,有許多有意思的細(xì)節(jié).我鼓勵(lì)你為自己而深入研究代碼.你將會發(fā)現(xiàn)它是一段奇妙的學(xué)習(xí)旅程,其間是關(guān)于SQL Server 2014 基于內(nèi)存的OLTP "Hekaton"特性的性能和限制.一個(gè)特別的屬性包含在代碼中,以模擬內(nèi)存中存儲BLOB類型的數(shù)據(jù).內(nèi)存優(yōu)化表現(xiàn)在不支持BLOB類型.序列化的會話字典和可能的大BLOB數(shù)據(jù)類型有什么不同呢?其中使用的預(yù)處理程序(sprocs)將序列化的會話分拆為7000字節(jié)的數(shù)據(jù)塊,以增強(qiáng)大的會話項(xiàng)數(shù)據(jù)的存儲.
精明的讀者可能已經(jīng)發(fā)現(xiàn),在我的屏幕截圖中, [SessionItems]表中并沒有數(shù)據(jù)行,但在[Sessions]表中有一行數(shù)據(jù).如果我的會話內(nèi)容超過了7000字節(jié),你應(yīng)該會在[SessionItems]表中看到"溢出"(spill over)行.關(guān)于這方面,在ASP.NET會話存儲之外,有許多其它潛在的應(yīng)用程序,我很可能在下一篇文章中深入挖掘這點(diǎn).
本地編譯存儲過程也值得一看.有一些技巧來處理本地編譯存儲過程的限制,如缺少CASE語句的支持.這個(gè)限制是因?yàn)?只要預(yù)處理程序(sproc)編譯為本地代碼,是不允許進(jìn)行分支的!
如果你在考慮使用這個(gè)新特性,有如下關(guān)鍵點(diǎn)和問題需要考慮:
內(nèi)存優(yōu)化表由內(nèi)存來支撐!你的SQL Server在峰值負(fù)載時(shí),有足夠的內(nèi)存來包含所有的會話數(shù)據(jù)嗎?
默認(rèn)表是非可持久的.請仔細(xì)考慮你的高可用性的需求.不管是可持久還是非可持久,性能將超出你現(xiàn)在使用的傳統(tǒng)SQL Server數(shù)據(jù)庫的會話和模式.
閱讀SQL文件中的注釋,調(diào)整BUCKET_COUNT為非簇集HASH索引.以下是SessionItems表DDL語句的代碼片段.
關(guān)于如何讓使用SQL Server In-Memory存儲ASP.NET的會話狀態(tài)問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。
本文標(biāo)題:如何讓使用SQLServerIn-Memory存儲ASP.NET的會話狀態(tài)
瀏覽路徑:http://www.rwnh.cn/article2/gshcoc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、Google、網(wǎng)站排名、動(dòng)態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)