SQLServer內(nèi)存數(shù)據(jù)庫原理解析

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

創(chuàng)新互聯(lián)專注于潮安企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,商城網(wǎng)站定制開發(fā)。潮安網(wǎng)站建設(shè)公司,為潮安等地區(qū)提供建站服務(wù)。全流程專業(yè)公司,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)


前言

關(guān)系型數(shù)據(jù)庫發(fā)展至今,細節(jié)上以做足文章,在尋求自身突破發(fā)展的過程中,內(nèi)存與分布式數(shù)據(jù)庫是當下最流行的主題,這與性能及擴展性在大數(shù)據(jù)時代的需求交相輝映。


SQL Server作為傳統(tǒng)的數(shù)據(jù)庫也在最新發(fā)布版本SQL Server 2014中提供了新利器 SQL Server In-Memory OLTP(Hekaton),使得其在OLTP系統(tǒng)中的性能有了幾十倍甚至上百倍的性能提升,本篇文章為大家探究一二。 

大數(shù)據(jù)時代的數(shù)據(jù)如何組織應(yīng)用?這恐怕眾口不一。但不可否認,關(guān)系型數(shù)據(jù)依舊是當下世界最有效的應(yīng)用方式。作為應(yīng)用技術(shù),也必將伴隨著應(yīng)用的需求而不斷演化。

信息爆炸對信息處理提出了更為嚴苛的需求,單從傳統(tǒng)的OLTP系統(tǒng)來看,性能和擴展性便是應(yīng)用者最為關(guān)注的方面。假如應(yīng)用者告訴你我需要當下數(shù)據(jù)庫訪問量100倍的計算資源,單純硬件?顯然新的技術(shù)應(yīng)用呼之而出。

 

傳統(tǒng)關(guān)系型數(shù)據(jù)庫自誕生起自身不斷完善的同時也伴隨著硬件的飛速發(fā)展,性能提升上伴隨處理器神奇的摩爾定律,TPC-C,TPC-E等指標不斷提升,而隨著今年來處理器物理工藝接近極限,CPU的主頻速度幾乎不再提升,這時計算機朝著多核方向進展,同時內(nèi)存成本也在線性降低,不再如此昂貴,目前內(nèi)存的成本已經(jīng)低于10$/GB。

而固態(tài)硬盤(SSD)的廣泛應(yīng)用也使得傳統(tǒng)數(shù)據(jù)庫在性能上有更多的延伸。面對這些新的硬件環(huán)境,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫自然也有其設(shè)計之初不可避免的自身性能瓶頸。

 

SQL Server 2014的傳統(tǒng)引擎中引入緩沖池擴展(Buffer Pool Extension)功能,利用SSD的高IOPS作為緩沖池的有利延伸,構(gòu)成了熱,活,冷三層數(shù)據(jù)體系,有效緩解磁盤的壓力。

我們可以把更多的數(shù)據(jù)放入內(nèi)存,SSD中,但即便如此數(shù)據(jù)庫的性能還是被自身的一些架構(gòu)和處理方式所約束著。

就著前面的假設(shè),我們要把事務(wù)處理能力提升100倍。假設(shè)我們現(xiàn)在的處理能力是100 TPS,而這時每個事務(wù)所以得平均CPU指令為100萬個,以此提升10倍1000 TPS,每個事務(wù)的CPU指令就需降為10萬個,而再提升10倍10000TPS每個事務(wù)的CPU指令就需降為1萬個,這在現(xiàn)有的數(shù)據(jù)庫系統(tǒng)中是不可能實現(xiàn)的,所以我們依舊需要新的處理方式。

一、傳統(tǒng)數(shù)據(jù)庫引擎面臨的問題

有的朋友可能會說把所有數(shù)據(jù)都放入內(nèi)存中就是內(nèi)存數(shù)據(jù)庫,就不存在短板了,但即便如此我們?nèi)悦媾R如下主要問題:

1.保護內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)而采用的閂鎖(latch)引起的熱點 (hot spots)問題。

2.使用鎖機制控制多版本并發(fā)帶來的阻塞等問題。

3.使用解釋型(interpretation)語言的執(zhí)行計劃的執(zhí)行效率問題。

我們簡單看下上述問題的由來


1.假設(shè)我有一個查詢Q1需要訪問一個數(shù)據(jù)頁 頁號7,此時數(shù)據(jù)頁不在BufferPool(BP)中,為此系統(tǒng)為其分配了內(nèi)存架構(gòu),并去磁盤取相關(guān)數(shù)據(jù)頁置入BP中此過程正常大概10-20ms,而此時恰好另一個查詢Q2需訪問數(shù)據(jù)頁號7,由于BP中已經(jīng)存在應(yīng)該頁架構(gòu),如果此時允許Q2讀取,則Q2將會臟讀。

 

因此引入閂鎖,當Q1去磁盤讀取數(shù)據(jù)時BP中的相應(yīng)架構(gòu)被閂鎖保護,Q2讀相應(yīng)的頁時將被阻塞,知道Q1完成相應(yīng)操作并釋放閂鎖,如下圖1-1所示:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖1-1


現(xiàn)在有數(shù)據(jù)庫系統(tǒng)中為保證多線程下的共享數(shù)據(jù)一致性,內(nèi)存任何數(shù)據(jù)結(jié)構(gòu)都需被閂鎖保護。而當大量并發(fā)進程同時訪問一個數(shù)據(jù)頁(結(jié)構(gòu))就造成了熱點問題。消耗了大量CPU的同時影響了并發(fā)吞吐。

2.假設(shè)有如下兩個操作,都對數(shù)據(jù)庫中的某個值進行修改:

A=1000

Q1:A = A + 100Q2: A = A + 500

在數(shù)據(jù)庫中的操作為

Q1:Read A,A=A+100, Write A

Q2:Read A,A=A+500, Write A

如果是串行先后執(zhí)行,則沒有問題,但如果同時執(zhí)行則可以出現(xiàn)數(shù)據(jù)的不一致情形。

Q1,Q2同時讀取了A的原始值后,進行修改,則數(shù)據(jù)不一致如圖1-2:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析
圖1-2


為了解決此問題,已故的業(yè)界大神,圖靈獎的獲得者JimGray提出了兩階段鎖概念 (Two-Phase Locking),合理地解決了并發(fā)一致性問題,并被絕大多數(shù)數(shù)據(jù)庫系統(tǒng)應(yīng)用并改進(如SQL Server中數(shù)據(jù)不同粒度下并發(fā)兼容情形引入的意向鎖)。

本例中當Q1讀取A時,對A加排他鎖,當Q2試圖讀取時就會被阻塞,需等待Q1的事務(wù)完成后釋放鎖資源后才能繼續(xù)讀取。如圖1-3:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖1-3


但也正因為鎖的引入,使得事務(wù)間可能出現(xiàn)相互阻塞,并且需要特定的進行管理鎖資源,且需對死鎖等問題即時檢測,而這些問題自然地會影響并發(fā)性能。

 

3.熟悉SQL Server的人都知道一條語句在SQL Server中執(zhí)行,現(xiàn)有進行綁定,語義分析,基于成本的優(yōu)化等一些列過程然后生成相應(yīng)的解釋性語言執(zhí)行計劃,而引擎在執(zhí)行相應(yīng)的執(zhí)行計劃時會調(diào)用相應(yīng)的數(shù)據(jù)庫函數(shù),運行每一個運算符,如果數(shù)據(jù)在硬盤上則會去硬盤上取數(shù)據(jù)……

這些情形使得執(zhí)行解釋性語言時高時間消耗的同時也打斷CPU流水,使得CPU的效率無法充分發(fā)揮,而如果數(shù)據(jù)均在內(nèi)存中,則可以采用更高效的方式處理。而絕大多數(shù)關(guān)系型數(shù)據(jù)庫系統(tǒng)的執(zhí)行計劃均為解釋性語言。

 

面對這些問題,巨頭數(shù)據(jù)庫廠商們都提供了相應(yīng)的內(nèi)存數(shù)據(jù)庫解決方案,如Oracle的Timesten,還有最新圖靈獎獲得者Michael Stonebraker教授的研究H-store演化出的商業(yè)產(chǎn)品VoltDB等。

而微軟的SQL Server 2014也推出了內(nèi)存數(shù)據(jù)庫SQL Server In-Memory OLTP(開發(fā)代號Hekaton),接下來我們就簡要的看下Hekaton如何應(yīng)對上面的問題,使得性能得到新的升華。

二、SQL Server Hekaton的應(yīng)對方式

SQL Server Hekaton是一個基于內(nèi)存優(yōu)化的高性能的OLTP數(shù)據(jù)庫引擎,且數(shù)據(jù)是可持久化的,它完全集成于SQL Server內(nèi)(可與傳統(tǒng)引擎,基于列存儲引擎混合透明使用如圖2-1),且是基于現(xiàn)代多核CPU架構(gòu)設(shè)計。如圖2-1:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-1


應(yīng)對上述三點性能瓶頸,熱點上Hekaton采用”Bw-tree”數(shù)據(jù)結(jié)構(gòu)實現(xiàn)Latch-free,并發(fā)鎖上采用樂觀并發(fā)中多版本時間戳數(shù)據(jù)行控制實現(xiàn)無鎖事務(wù),解釋性語言執(zhí)行效率采用截執(zhí)行計劃編譯為機器代碼(DLL)提升CPU效率。

 

下面針對這三點來簡要說明下。

Hekaton中的數(shù)據(jù)頁大小是彈性的,以便于增量更新Delta update,因為現(xiàn)有傳統(tǒng)的update in place會使得現(xiàn)有的CPU Cache失效,在多核架構(gòu)下會使得性能受限。數(shù)據(jù)頁在內(nèi)存中通過映射表管理,將每個數(shù)據(jù)頁的邏輯ID與物理地址一一映射。如圖2-2:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-2


在對數(shù)據(jù)進行更新時采用Compareand Swap(CAS)實現(xiàn)無鎖(Latch free)操作

CAS:通過比對物理地址的值與攜帶值是否匹配,匹配則可操作,不匹配則拒絕操作。

如某個進程在攜帶的地址M的值為20,匹配地址M的實際值,如果為20則可以修改,否則拒絕如圖2-3:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-3

在對數(shù)據(jù)頁進行增量更新時每次操作均會在數(shù)據(jù)上生成一個新的增量地址作為數(shù)據(jù)頁的訪問入口,并采用CAS完成映射表中(mapping table)物理新地址的映射(delta address),并對針對同一數(shù)據(jù)頁可能出現(xiàn)的同時更新進行仲裁,此時勝出者將進行更新,而失敗者可以進行重試,遺憾的是目前SQL Server只會對失敗操作拋出錯誤信息,需要我們自己捕捉錯誤信息并重試,具體可參考聯(lián)機文檔。

具體如圖2-4所示:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-4

這樣的操作方式下,當更新鏈過長時訪問數(shù)據(jù)會造成時間復(fù)雜度提升從而影響性能,SQL server會在合適的情形下進行整理,生成新的數(shù)據(jù)頁,并將物理地址指向新的數(shù)據(jù)頁,而老的數(shù)據(jù)頁鏈表將會作為垃圾回收釋放內(nèi)存。

如圖2-5:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-5

由于數(shù)據(jù)頁是彈性的,所以可能造成數(shù)據(jù)頁過大或是過程,Hekaton中會在其認為合適的情形下進行頁分裂或是合并。限于篇幅這里就不在詳細敘述了,在實現(xiàn)Latch-free中所有內(nèi)存中的操作都是通過一個或多個原子操作完成。感興趣的朋友可以參考微軟的相關(guān)文獻。

 

有的朋友可能會說閂鎖本身是保護內(nèi)存結(jié)構(gòu)的輕量級鎖,況且不同類型的閂鎖可能兼容,Latch-free對性能幫助能有多大呢?

實際SQL Server在訪問內(nèi)存中數(shù)據(jù)時,閂鎖本身用作控制數(shù)據(jù)訪問時成本很高,為此會在數(shù)據(jù)上加自旋鎖(Spin lock)供線程探測數(shù)據(jù)是否可以訪問,Spin lock實現(xiàn)即一個Bit位(0或1),線程會一直探測內(nèi)存中的這個Bit位以試圖獲得自旋鎖,如果可以訪問則訪問,否則自旋,如果幾千次的探測仍無法訪問則停下”休息”這個稱作一次碰撞。

 

但是在自旋的過程CPU負荷狀態(tài),因此也就造成CPU資源白白浪費。生產(chǎn)中我們可能看到CPU高啟,而并發(fā)卻上不去,訪問變慢,其中的一個原因就是大量進程訪問熱點數(shù)據(jù)下大量自旋鎖征用使得性能受限。

而在Hekaton中無閂鎖的情況下就不存在這樣問題,單從這個角度來看隨著線程的增加性能也是線性放大。當然除了Latch-free,其他的兩個方面Hekaton同樣表現(xiàn)出色。

 

前文中敘述可知,關(guān)系型數(shù)據(jù)庫中事務(wù)是靠鎖來保證多版本并發(fā)控制的,由此帶來的阻塞死鎖等問題相信所有的DBA都印象深刻。而Hekaton中采用樂觀并發(fā)下多版本數(shù)據(jù)加時間戳的形式實現(xiàn)。

 

下面來簡要解下。

Hekaton中將一個事務(wù)分為三個階段,正常事務(wù)處理步驟用于我們的數(shù)據(jù)操作DML則創(chuàng)建新的版本行。驗證提交階段驗證這個事務(wù)是否可以安全提交(根據(jù)版本數(shù)據(jù))。提交處理階段用于寫日志,并將新的版本行數(shù)據(jù)對其它事務(wù)可見。

如圖2-6:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-6


我們通過一個實例簡要說明下:

事務(wù)過程采用Timestamps(時間戳(全局時鐘))標記事務(wù)和行版本,每個事務(wù)開始時賦予開始時間戳Begin_TS,用于讀取正確的行版本(數(shù)據(jù)行同樣均具有時間戳),行版本數(shù)據(jù)結(jié)束時間戳End_TS一般為正無窮(+∞),當進行數(shù)據(jù)更新時創(chuàng)建新的版本行,并將舊的版本行End_TS修改為事務(wù)ID Xb(此處非時間戳),新的版本行的Begin_TS同樣標記為事務(wù)ID (Xb)。然后獲取事務(wù)的End_TS (唯一),確認可提交后,提交事務(wù),并將新舊版本的事務(wù)ID(Xb)替換成獲取的End_TS。至此完成一次操作。未涉及任何鎖,閂鎖,阻塞。

如圖2-7:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-7


有的同學看到上圖可能回想,這樣Xa讀取的版本行是正確的嗎?他為什么不能讀到Xb的新行數(shù)據(jù)。我們來簡單分析下。

Xa開始時分配的時間戳為25,Xb為35,這就意味著Xb的結(jié)束時間戳一定大于35此時Xa讀取數(shù)據(jù),時間戳范圍應(yīng)為Begin_TS-20,End_TS-+∞,而Xa的Begin_TS小于Xb的Begin_TS,所以讀取正確如圖2-8:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-8


實際上Hekaton中規(guī)定 查詢的可見值區(qū)間必須覆蓋此查詢的開始時間戳比如一個查詢事務(wù)的開始時間戳為30,他可見的行版本可以包括10至+∞,20至150,但不能看到40至+∞。如圖2-9:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-9


有的同學可能會想,隨著訪問,DML的增加,會累積大量的無用數(shù)據(jù)占用內(nèi)存,實際上根據(jù)查詢自身的事務(wù)時間戳,如上當最古老的事務(wù)開始時間戳大于等于50時,舊版本的數(shù)據(jù)就可以安全的清除釋放內(nèi)存了。清除工作可以使多線程并行執(zhí)行,對新能影響很小。

 

從圖2-6中可以看到,并不是每個事務(wù)都可以安全提交的,在驗證階段,Hekaton會根據(jù)用戶設(shè)定的隔離級別進行驗證。


Hekaton為樂觀并發(fā),提供三種隔離級別的支持分別為快照隔離級別(Snapshot Isolation),可重復(fù)讀隔離級別(RepeatableReads Isolation)及序列化隔離級別(Serializable),這與傳統(tǒng)的關(guān)系型數(shù)據(jù)類似,Snapshot中是無需驗證的,而可重復(fù)則需在提交前再次驗證與事務(wù)開始時的數(shù)據(jù)是否一致,如一致則可提交,否則不可提交。

而序列化中顧名思義讀取的區(qū)間數(shù)據(jù)都需一致,否則失敗。有同學可能會想序列化中將匹配多少數(shù)據(jù)啊,成本是不是太高了,別忘了這是在內(nèi)存中,依然比傳統(tǒng)的序列化成本要低很多。

 

熟悉樂觀級別的同學都知道,傳統(tǒng)的樂觀并發(fā)級別下回滾成本是非常高的,而Hekaton中采用驗證的方式有效的規(guī)避了這項成本。提交就是寫日志記錄變化,并將數(shù)據(jù)行中事務(wù)ID替換成獲取的時間戳,對其他事務(wù)可見。

 

當然提高寫日志,我們都知道磁盤終究是瓶頸,為此Hekaton也有其特定的優(yōu)化方式來緩解這個問題,限于篇幅這里就不在敘述。而且針對一些特定的場景我們可以選擇只保留Schema而無需數(shù)據(jù)持久化(如游戲的場景數(shù)據(jù)等)。

最后,針對CPU執(zhí)行效率將執(zhí)行計劃由解釋性語言(Interpreted)替換為機器語言(Native)。

優(yōu)化器可以說是關(guān)系型數(shù)據(jù)庫最復(fù)雜的部分了,簡單說下SQLServer優(yōu)化器處理過程:一條語句交給優(yōu)化器會進行綁定解析,生成解析樹,然后進行語義分析生成邏輯執(zhí)行計劃,最后優(yōu)化器再為邏輯執(zhí)行計劃基于成本生成物理的執(zhí)行計劃。

 

而Hekaton中,如果我們選擇Native方式執(zhí)行(將所執(zhí)行語句通過存儲過程特殊編譯),在生成邏輯執(zhí)行計劃之后將會根據(jù)不同的算法,成本預(yù)估生成不同的物理執(zhí)行計劃,然后將物理執(zhí)行計劃轉(zhuǎn)譯成C語言代碼再通過編譯器將其編譯成DLL即機器代碼。如圖2-10:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-10

曾經(jīng)微博上有朋友問為什么MySQL重構(gòu)優(yōu)化器時為什么要將parsing,optimizing, execution三個模塊分開而不是混在一起了,我想這里可能就找到答案了,一個優(yōu)秀RDBMS它自身的健壯是多么重要。

在Native下,所有的執(zhí)行都是“Goto”,直接讀取數(shù)據(jù),再也不用一個一個的function的調(diào)用,極大提升CPU的工作效率。有人可能會問這樣每次都編譯將是非常大的工作成本,實際上Hekaton將指定查詢(存儲過程)編譯成DLL文件,只是在第一次將其載入內(nèi)存就可以了。對于即席查詢是不可以的。

 

Hekaton在機器代碼下執(zhí)行效率大幅提升,以下是微軟給出的測試數(shù)據(jù):


a.Interpreted與Native的對比,其中分為是否為內(nèi)存優(yōu)化表,查詢單條數(shù)據(jù)所消耗的CPU指令。如圖2-11:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-11

b.隨機查找1000萬數(shù)據(jù)普通表與Hekaton內(nèi)存優(yōu)化表查詢時間對比圖2-12

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-12

c.普通表與Hekaton內(nèi)存優(yōu)化表內(nèi)存中隨機更新數(shù)據(jù)對比,此時不寫日志如圖2-13:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖2-13

三、Hekaton應(yīng)用案例

Hekaton,古希臘語中表示百倍,雖然目前還未達到愿景,我想這個出色的團隊一定能夠做到。

SQL Server有了這個新利器,在應(yīng)對性能問題上更加出色。在微軟的官方網(wǎng)站上有大量案例,這里我們列舉幾個。

Bwin,歐洲最大的在線×××,采用Hekaton后,線上每秒批處理由15000提升到250000。

EdgeNet,硅谷著名的數(shù)據(jù)服務(wù)商,采用Hekaton后,線上入庫數(shù)據(jù)量由7450/s提升到126665/s均由近17倍的速度提升。如圖3-1:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖3-1

而將易車的惠買車的訪問量在Hekaton模擬運行時,各項性能指標都表現(xiàn)的很淡定。如圖3-2:

SQL Server內(nèi)存數(shù)據(jù)庫原理解析

圖3-2

Hekaton不僅為我們解決了不少場景下的性能問題,我想面對特定場景中的一些棘手問題也有一定的幫助。比如電商熱衷的秒殺/搶購。這里筆者就不在敘述業(yè)內(nèi)朋友研究的排隊論,批量提交等等辦法。

實際上計算機在當下普遍應(yīng)用都是模擬三維空間內(nèi)的人為活動,試想下,搶購的過程終究有成功或是失敗,就好像你在搶購熱銷產(chǎn)品時被身手矯健的大媽推到一邊你沒搶到一樣,這不正好符合Hekaton中的事務(wù)機制?我們在設(shè)計網(wǎng)上產(chǎn)品活動的時候是否該想想模擬到現(xiàn)實中是什么樣子的?對此,我認為我們需要的是可控,而不是控制。

四、結(jié)語

最后,這么多帶給人驚喜振奮的數(shù)據(jù)庫,它就完美無缺嗎?當然不是。Hekaton的樂觀并發(fā)級別限定使得其并不適合大量更新沖突的場景,其以空間換速度的設(shè)計要求會消耗大量內(nèi)存,需要應(yīng)用者合理規(guī)劃設(shè)計……

請牢記“任何技術(shù)都是有缺陷的”,沒有哪項技術(shù)/架構(gòu)是完美無缺的,合適的場景選擇合理的技術(shù)/架構(gòu)才是我們的初衷。

網(wǎng)頁名稱:SQLServer內(nèi)存數(shù)據(jù)庫原理解析
文章轉(zhuǎn)載:http://bm7419.com/article24/pcsjce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、網(wǎng)站營銷、網(wǎng)站設(shè)計公司、品牌網(wǎng)站制作外貿(mào)建站、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)