第226期 / August 5, 2016

分享到臉書!分享到維特!分享到噗浪!分享到Google+!分享到微博!轉寄友人友善列印

In-Memory OLTP 記憶體最佳化介紹

作者/陳峰漳

[發表日期:2016/5/13]

簡介

Microsoft SQL Server是由美國微軟公司所推出的關聯式資料庫解決方案,最新的版本是SQL Server 2014,已經在2014年4月1日發布。 資料庫的內建語言原本是採用美國標準局(ANSI)和國際標準組織(ISO)所定義的SQL語言,但是微軟公司對它進行了部分擴充而成為作業用SQL(Transact-SQL)。 幾個初始版本適用於中小企業的資料庫管理,但是近年來它的應用範圍有所擴充功能,已經觸及到大型、跨國企業的資料庫管理。SQL Server一開始並不是微軟自己研發的產品,而是當時為了要和IBM競爭時,與Sybase合作所產生的,其最早的發展者是Sybase,同時微軟也和Sybase合作過SQL Server 4.2版本的研發,微軟亦將SQL Server 4.2移植到Windows NT(當時為3.1版),在與Sybase終止合作關係後,自力開發出SQL Server 6.0版,往後的SQL Server即均由微軟自行研發。在與微軟終止合作關係後,Sybase在Windows NT上的資料庫產品原本稱為Sybase SQL Server,後來改為現在的Sybase Adaptive Server Enterprise。

而In-Memory OLTP是SQL Server的新功能的使用 In-Memory OLTP,一般來說資料庫的資料皆存在磁碟上,來要進行存取時,再透過SQL語法進行處理,並將資料撈取至記憶體中,再進行顯示或處理,在以往如果要加快處理,所以就有許多的軟體或硬體的搭配進而推出RAM-Disk的機制,雖然可以加快處理,但最大的問題是,如果遇到突然斷電時,會造成資料的損失,所以大部份的使用者只敢架構在TempDB的部份。而此次SQL Server整合了此功能(In-Memory),即可解決此問題又可以達到加速處理的效果。 In-Memory OLTP 引擎的設計目的是,在衍生自高度向外擴充中間層的 OLTP 類型交易發生極高的工作階段並行處理時使用。為達成此目的,它使用了不需閂鎖的資料結構,以及開放式、多版本的並行控制。結果是可針對資料庫交易進行線性比例調整來產生可預期、亞毫秒低延遲及高輸送量。實際效能獲益取決於許多因素,但通常可以獲得 5 到 20 倍的效能提升。

使用記憶體最佳化資料表的需求

除了安裝SQL Server 2014 的硬體與軟體需求之外,以下還有使用記憶體的OLTP需求:

  • 2.1 SQL Server 2014 64 位元 Enterprise、Developer 或 Evaluation Edition。


  • 2.2 SQL Server 需要足夠的記憶體,以容納記憶體最佳化的資料表和索引中的資料。為了說明資料列版本,我們應該提供記憶體最佳化的資料表和索引預期大小兩倍的記憶體數量。 但是所需的實際記憶體數目將取決於我們的工作負載。我們應該監視記憶體使用量並視需要進行調整。 記憶體最佳化資料表的資料大小不得超過集區所允許的百分比。如果資料庫中有以磁碟為基礎的資料表,我們需要提供足夠的記憶體,讓緩衝集區和查詢能夠在這些資料表上進行處理。


  • 2.3 釋放持久的記憶體最佳化資料表大小的兩倍磁碟空間。


  • 2.4 處理器需要支援指令 cmpxchg16b 以使用記憶體中 OLTP。 所有新型 64 位元處理器都支援 cmpxchg16b。如果我們使用 VM 主應用程式,而 SQL Server 顯示較舊處理器造成的錯誤,請查看應用程式是否有允許 cmpxchg16b 的組態選項。 如果沒有,我們可以使用 Hyper-V,它可以支援 cmpxchg16b,而不需要修改組態選項。


  • 2.5 若要安裝記憶體中 OLTP,請在您安裝 SQL Server 2014 時選取 [Database Engine Services]。


  • 使用In-Memory OLTP的重要注意事項

  • 3.1 資料庫中所有持久資料表的記憶體中大小總計不應該超過 250 GB。 這個 In-Memory OLTP 版本的目標是在含有 2 或 4 個通訊端且少於 60 個核心的系統上可以最佳化方式執行。


  • 3.2 檢查點檔案無法手動刪除。SQL Server 會對不需要的檢查點檔案自動執行記憶體回收。 在此第一版記憶體中 OLTP (在 SQL Server 2014 裡) 中,移除記憶體最佳化檔案群組唯一的方式就是卸除資料庫。


  • 3.3 若我們在嘗試刪除大批資料列時,有並行的插入或更新工作負載會影響您正嘗試刪除的資料列範圍,則刪除作業可能會失敗。 解決方法是先停止插入或更新工作負載,然後執行刪除。 或者,您也可以將交易設定為較小的交易,這樣做比較不容易受到並行工作負載所中斷。 如同記憶體最佳化資料表上的所有寫入作業,使用重試邏輯。


  • 3.4 如果您建立一個或多個具有記憶體最佳化資料表的資料庫,就應該針對 SQL Server 執行個體啟用立即檔案初始化 (將 SE_MANAGE_VOLUME_NAME 使用者權限授與 SQL Server 服務啟動帳戶)。 如果沒有立即檔案初始化,記憶體最佳化儲存體檔案 (資料和差異檔案) 將會在建立時初始化,而這樣可能會對工作負載的效能造成負面影響。


  • 限制

    雖然In-Memory OLTP在效能上有較佳的表現,但是在使用上卻有一些限制:

  • 伺服器與資料表的限制
    1.資料庫的鏡像、複寫、快照集、多重作用結果集、異動資料擷取和Miscrosoft分散式協調器等功能都不支援
    2.每一個In-Memory OLTP的最大記憶體大小不能超過250GB
    3.RTO (Recovery Time Objective) :系統恢復正常所需時間非常的長


  • 綱要(Schema)、鍵值(Keys)、索引(Index)上的限制:
    1.固定的綱要且不能對已經存在的In-Memory Table上的各個欄位做異動。
    2.不能對原本不為In-Memory Table的資料表下指令使其成為In-Memory Table
    3.Foreign Key’s 和Check Constraints也不支援
    4.資料型態的部分,Datetimelffset、Geography, Hierarchyid, Image, Ntext, Text, Sql_variant, Varchar(max), Xml, User data types (UDTs這些都不支援,且char與varchar都要轉為n(var)char。
    5.索引的部分:ColumnStore和Constraint的索引都不支援


  • T-SQL不支援的語法有OR, NOT, IN, LIKE, BETWEEN, CONTAINS, PERCENT, DISTINCT, NEXT VALUE FOR等等幾個,另外還有像LEFT / RIGHT / FULL OUTER JOIN等語法也不支援


  • 函數與預存程序的限制:
    1.自訂的函數不能在本地的預存程序中使用
    2.Views不能在本地的預存程序中被存取
    3.Disk-based tables也不能在本地的預存程序中被存取


  • 實作範例

    首先,利用語法建立資料庫



    上述中我們特別建立了一個FileGroup(imoltp_mod)進行儲存,藉以存放Transaction Log與暫存檔,如下圖所示。


    《圖一》


    然後在建立資料表與新的原生編譯的預存程序



    原生編譯的預存程序與傳統的預存程序差別在於原生的預存程序是建立的當下即進行編譯,而傳統的即是在第一次才進行,而且即載入記憶體中,所以可以快速的重覆執行,但原生的預存程序無法進行修改,進行修改時會得到下列的錯誤訊息。最後再比較測試執行的差異:



    在此次的測試中主要進行三個動作:
    1.新增100000筆資料到傳統的資料庫中
    2.新增100000筆資料到記憶體優化的資料表(memory-optimized table)中。
    3.透過原生編譯的預存程序將100000筆資料新增到記憶體優化的資料表(memory-optimized table)中。

    執行結果如下圖所示:


    《圖二》


    從上述的測試中,我們發現在透過記憶體優化的資料表(memory-optimized table)進行處理(第二個測試),效能其實並沒有明顯的差異,但是在透過原生編譯的預存程序一同配合後,效能即約有3~4成的優化成長。

    結論

    SQL Server In-Memory OLTP提供了可創造和運行記憶體優化的極其高效的管理,實現了對OLTP工作負載的性能優化。真正實現了多版本的積極控制,且不需要在查詢過程中鎖定。所有In-Memory OLTP的記憶體優化資料表必須至少擁有一個索引,然後所有對這資料表的查詢都需要通過這些索引進行。除少量限制情況下外,In-Memory OLTP記憶體優化資料表可以作為分割資料表中的相同引用的事務。本機編譯的存儲過程以最快的方式來使用我們的記憶體資料表表和性能業務邏輯計算。

    參考資料

    1.維基百科Microsoft SQL Server

    2.MSDN In-Memory OLTP(記憶體中最佳化)

    3.CaryHsu – 學無止盡 SQL Server 2014 In-Memory OLTP測試與使用心得

    4.Transact-SQL Constructs Not Supported by In-Memory OLTP