譯者 | 大愚若智 我們經(jīng)常需要為自己的OLTP(事務(wù)/運營)數(shù)據(jù)庫選擇適合的RDBMS(關(guān)系型數(shù)據(jù)庫管理系統(tǒng))。雖然通過編寫可移植的SQL可以暫時避免進行這樣的選擇,但遲早要做出這樣的選擇,至少需要進行這樣的嘗試(比如,意識到具體的選擇不夠明確,因此決定選擇跨RDBMS的SQL)。 在發(fā)起“到底哪個RDBMS最好”的討論圣戰(zhàn)之前,也許需要首先明確一下對于24x7運行的生產(chǎn)級OLTP RDBMS,到底需要具備哪些必不可少的功能。 考慮到并發(fā)性,目前幾乎所有RDBMS無外乎基于鎖的(Lock-Based),或基于MVCC(多版本并發(fā)控制)的。從寫負(fù)載更重的OLTP處理角度來說,我曾經(jīng)見到過:
另外,值得注意的是,如果使用了單一寫入連接(Single-write-connection)數(shù)據(jù)庫架構(gòu),基于鎖和基于MVCC的RDBMS之間的邏輯差異將顯得微乎其微(盡管性能略有差別,但其他方面幾乎相同,基于鎖的RDBMS通常略微領(lǐng)先一些)。
如上所述,對于OLTP數(shù)據(jù)庫,我們需要為事務(wù)提供全面的ACID保障。更重要的是,需要保障涉及多行和多表的事務(wù)具備ACID特性。雖然這一規(guī)則也有例外,但這種例外情況實際上極為罕見。 這幾乎已自動將MySQL+MyISAM用作OLTP數(shù)據(jù)庫的可能性徹底排除在外。但是也要注意,MySQL+ISAM可能是少數(shù)應(yīng)用(例如作為快遞追蹤系統(tǒng)或系統(tǒng)監(jiān)視工具的后端)的好選擇,但并不適合涉及某類與金錢有關(guān)信息的常規(guī)OLTP處理。 此外RDBMS提供的ACID保障差不多等同于意味著需要使用數(shù)據(jù)庫日志,同時也意味著一旦RDBMS崩潰,隨后需要通過數(shù)據(jù)庫日志進行自動恢復(fù)(并自動前卷Rollforward)。
我們需要的另一系列功能主要與24×7不間斷運行有關(guān)(例如游戲服務(wù)器,總得全天候運行對吧)。這些功能包括: 聯(lián)機備份。無論做什么都肯定需要備份,24x7不間斷運行更是少不了聯(lián)機備份。 1、通常來說,聯(lián)機備份意味著需要具備“日志前卷”能力。大部分時候是這樣工作的:創(chuàng)建兩個數(shù)據(jù)庫,一個作為“主”,一個作為“從”;隨后從“主”獲取日志文件并發(fā)送給“從”,然后在從數(shù)據(jù)庫上進行“前卷”。 此外,有些數(shù)據(jù)庫可以對處于“日志前卷”狀態(tài)下的“從”數(shù)據(jù)庫執(zhí)行只讀請求(實際上等同于創(chuàng)建了一個只讀從副本)。然而其他一些RDBMS不能處理這樣的請求(例如需要首先完成“日志前卷”操作才能讓從RDBMS能夠接受查詢操作)。 2、作為聯(lián)機備份的備選方案,也可以通過異步主從復(fù)制獲得近乎完全同步的備份副本(這種做法對MySQL+InnoDB是一種尤為有趣的選項)。 需要注意,這樣的副本也許可以或無法支持聯(lián)機備份+前卷那樣的“時點”恢復(fù)(具體情況請參閱文檔)。雖然只在從一些非常糟糕的情況下恢復(fù)時需要“時點”恢復(fù)(實際生產(chǎn)環(huán)境中我從未遇到需要這種恢復(fù)的情況),不過真遇到這種糟糕的情況至少也能助我們一臂之力。 3、“即時”的ADD COLUMN語句。我們可能需要對生產(chǎn)環(huán)境的數(shù)據(jù)庫進行擴展,這一點是確定無疑的。大部分時候這是通過ALTER TABLE… ADD COLUMN語句實現(xiàn)的。面對ADD COLUMN語句,很多RDBMS會簡單地將整個表重寫為新格式的行。如果表包含10億行,這一過程可能需要數(shù)小時?(在進行復(fù)制的過程中,整個表將完全無法訪問,導(dǎo)致數(shù)據(jù)庫在數(shù)小時內(nèi)無法使用?)。讓ADD COLUMN能夠近乎即時(考慮到表的大小,可能需要幾毫秒的時間)執(zhí)行完成并不需要什么艱深的技術(shù),有些RDBMS也確實能做到這一點,但是也不能忽視,這并不是一種普遍特性。 預(yù)算不足時的備選方案是實現(xiàn)無鎖ADD COLUMN(以及常規(guī)的ALTER TABLE),方法如下:
這種“廉價”的ADD COLUMN方法相當(dāng)繁瑣(全過程會對性能產(chǎn)生極大影響),但如果沒有其他更好的方法,這種做法至少可以起到一定的效果。 “即時”ALTER COLUMN(字段拓寬,Widening field)也是個很好的功能,但因為字段拓寬可通過ADD COLUMN模擬,因此顯得并不是太重要。 4、聯(lián)機表優(yōu)化。這個功能需要介紹一下。由于RDBMS會不斷修改表內(nèi)容,表的性能會逐漸退化(實際上取決于所用存儲引擎,從“行溢出(Overflow row)”到“死行(Dead row)”,我們會遇到各種不希望出現(xiàn)的情況)。為此有必要進行一定的優(yōu)化(例如InnoDB的OPTIMIZE TABLE,DB/2的REORG TABLE,Postgres的VACUUM等),并且我們會需要聯(lián)機完成這些操作(無需讓整個數(shù)據(jù)庫徹底停擺,因為對包含數(shù)百萬行內(nèi)容的表進行優(yōu)化通常需要花很長時間)。 大部分時候,此類優(yōu)化需要創(chuàng)建“影子副本”(由數(shù)據(jù)庫自行創(chuàng)建,這總好過需要我們手工創(chuàng)建),這也意味著需要額外的存儲空間。不過至少有一個RDBMS提供了“原地”表優(yōu)化功能。 5、容器的重新平衡。雖然不像上文列出的其他問題那么重要,但我始終認(rèn)為“容器的重新平衡”也是RDBMS需要考慮的一個重要問題。 簡單來說,這個問題主要出現(xiàn)在添加存儲數(shù)據(jù)的新硬盤(這種情況時有發(fā)生),以及通過將數(shù)據(jù)分散在所有硬盤上實現(xiàn)提速時。此時可通過下列兩種方法之一實現(xiàn): (a) 使用RAID-10(這樣就無需考慮數(shù)據(jù)庫存儲數(shù)據(jù)的方式了) (b) 通過多個RAID-1磁盤使用數(shù)據(jù)庫容器(因為數(shù)據(jù)庫本質(zhì)上采用了類似RAID-0的工作原理)。 只要無需添加新硬盤(實際上通常在添加時,為了實現(xiàn)冗余往往會成對增加硬盤),所有系統(tǒng)基本上是均等的,然而在添加了一對新硬盤后,我們需要對硬盤進行“重新平衡”,借此實現(xiàn)負(fù)載的重新平衡,這一“重新平衡”的工作分別是由RAID或數(shù)據(jù)庫進行的。RAID級別的重新平衡對服務(wù)器性能的影響遠(yuǎn)大于數(shù)據(jù)庫級別的重新平衡(尤其是有些情況下系統(tǒng)甚至完全無力承擔(dān)RAID級別重新平衡過程中產(chǎn)生的負(fù)荷)。 因此我更樂于選擇使用由數(shù)據(jù)庫管理的容器(會在增加容器后重新平衡,整個過程會保持盡可能平緩)。
當(dāng)然,性能(尤其是寫性能)對OLTP數(shù)據(jù)庫至關(guān)重要。不幸的是,缺乏具體用例情況下進行的數(shù)據(jù)庫性能評測其實沒有任何意義。因此我只能盡量介紹一些與性能有關(guān)的知名RDBMS架構(gòu)功能及對某些功能的誤解。
在向RDBMS提交SQL語句時,語句會被編譯為“執(zhí)行計劃”。而(無論數(shù)據(jù)庫開發(fā)者怎么想或數(shù)據(jù)庫產(chǎn)品的銷售人員怎么說)這樣的編譯器時不時總會出錯。例如下面列出了一個常見的此類錯誤:
某些RDBMS會讓人感覺它們在設(shè)計時從未考慮過主要以寫操作為主的OLTP(而是更專注于讀取查詢)。雖然這并不意味著此類RDBMS從本質(zhì)上就很糟糕(畢竟大部分?jǐn)?shù)據(jù)庫確實主要以讀取查詢?yōu)橹饕蝿?wù)),但在現(xiàn)實世界中,面對需要執(zhí)行大量寫操作的OLTP環(huán)境,這會成為一個不容忽視的問題。一起看看這些相當(dāng)著名的問題吧。 Postgres:甚至對非索引字段進行更新也會導(dǎo)致Ctid的變化(存在爭議) 有報道稱現(xiàn)實用例中對包含大量索引的數(shù)據(jù)庫進行更新時,Postgres的數(shù)據(jù)庫會遇到嚴(yán)重的性能問題。相關(guān)問題的詳細(xì)討論可參考StackOverflow.PostgresUpdates和Klitzke,在我看來問題主要在于: “由于索引需要通過Ctid引用行,一個簡單的UPDATE(哪怕針對非索引列執(zhí)行)也會改變Ctid,導(dǎo)致引用了被更改行的表中每個索引中的Ctid均需要重寫。” 這就很糟了,對寫操作負(fù)擔(dān)重的OLTP數(shù)據(jù)庫尤為如此。另外從Postgres 8.3開始提供了一種所謂的Heap-Only Tuples(HOT)功能,該功能至少在理論上應(yīng)該能消除大部分相關(guān)問題(然而我沒找到任何能確認(rèn)這一點的現(xiàn)實用例),該功能的簡要介紹可參閱Postgres.HOT。這個功能的大致思路是:在HOT正常工作的前提下,如果新行可以放入同一頁,那么無論Ctid如何變化,索引依然會指向同一頁,因此無需更新索引。當(dāng)然這種想法有一定效果,但前提是新行可以放入同一頁,為此似乎可以通過“機會型的(Opportunistic)Mini-vacuum”實現(xiàn):盡管Postgres依然無法清理(Prune)需要更新的Tuple(出于MVCC的考慮必須保持精簡),但(據(jù)推測)可以對同一頁中較舊的Tuple進行清理,這樣也許可以在同一頁中保存新行并避免更新索引。 底線是:雖然Postgres存在不必要的索引更新問題,但通過HOT功能大幅緩解了這個問題,但HOT能否完全解決這個問題還有待討論(這種緩解過程可能需要額外的配置以便在頁中為HOT提供所需的空間),但至少我們可以針對數(shù)據(jù)庫實例監(jiān)視HOT的運行效率(可參閱Postgres.HOT)。 雖然內(nèi)存中數(shù)據(jù)庫為OLTP應(yīng)用提供了巨大收益,但我并不會出于這種用途考慮選擇MemSQL,原因如下。 正如Mituzas所述,MemSQL會使用耗時50毫秒的投票發(fā)起數(shù)據(jù)庫日志寫入操作。對任何類型的OLTP數(shù)據(jù)庫來說這都是一種很糟糕的做法,但如果你考慮我的建議選擇單一寫入數(shù)據(jù)庫連接架構(gòu),MemSQL的這種所謂“功能”會造成極為嚴(yán)重的后果。一定要反復(fù)核實該產(chǎn)品是否還在使用這個功能,如果在使用,至少應(yīng)該盡量避免使用單一寫入數(shù)據(jù)庫連接的配置。
面對生產(chǎn)數(shù)據(jù)庫,我們需要對SQL語句進行調(diào)試和Profiling。至少需要具備一個能展示SQL查詢“執(zhí)行計劃”的工具。這樣才能預(yù)測查詢的執(zhí)行方式(即,SQL語句編譯后的執(zhí)行計劃將用于生產(chǎn)數(shù)據(jù)庫,或從生產(chǎn)數(shù)據(jù)庫狀態(tài)導(dǎo)入的數(shù)據(jù)庫)。 另外執(zhí)行計劃只能告訴我們預(yù)測的執(zhí)行成本(通過數(shù)據(jù)庫狀態(tài)計算而來),但可能與實際情況存在數(shù)量級的差異。 為此可以使用某些類型的實時Profiling技術(shù)。這類工具可能有一定的作用,但在我看來并非絕對必要:通常來說只要具備一些經(jīng)驗和常識,就可以很容易地發(fā)現(xiàn)這些與查詢有關(guān)的性能問題(一般來說,迫使數(shù)據(jù)庫使用我們指定的查詢計劃,這往往要比確定當(dāng)前所用查詢計劃表現(xiàn)欠佳的原因更為困難)。 目前已經(jīng)有不少RDBMS提供了內(nèi)存中處理功能。這些功能主要可分為兩類:
面對極高的負(fù)載,我們遲早需要為數(shù)據(jù)庫創(chuàng)建(只讀的)副本(Replica)。如果所用RDBMS產(chǎn)品支持復(fù)制(并能正確使用),就可以自動創(chuàng)建所需副本。 大部分時候我們最需要的是一種所謂的主從異步復(fù)制(這樣從副本的延遲才不會影響主副本)。此外可能還會用到其他相關(guān)功能,例如副本合并(同樣適用于簡單的主從異步環(huán)境,但絕對不會產(chǎn)生任何沖突)。 然而從我個人的經(jīng)驗來看,RDBMS提供的復(fù)制功能在高負(fù)載情況下通常表現(xiàn)都很糟。有這樣一個極端案例:在負(fù)載持續(xù)多天維持每天不超過1百萬筆事務(wù)的情況下,復(fù)制功能總是因為一些難以理解的錯誤而失敗,需要對副本進行完整的重新同步(這也是個非常頭疼的問題)。這種情況告訴我們:
DUD:設(shè)備或機械由于無法正常工作或運轉(zhuǎn)失敗而顯得無用。 — 維基詞典 好在如果你選擇的復(fù)制技術(shù)恰好就是這樣的“DUD”(并且使用了單一連接的方法),還可以用相對較為簡單的方法自行進行復(fù)制。 RDBMS提供的分區(qū)(Partitioning)是一種實現(xiàn)可縮放性的工具,但往往會被過度吹捧。但是我本人也傾向于選擇無需共享(Share-Nothing)的模式(并采用應(yīng)用層面的分區(qū)),因為相比將一個數(shù)據(jù)庫分區(qū)至多臺服務(wù)器,這種方式可以上線更為線性的縮放能力。但有些情況下RDBMS提供的分區(qū)功能也會顯得較為有用,因此如果提供有這樣的功能,也可以將其看作一個“加分項”(盡管可能并不像RDBMS銷售人員說的那么天花亂墜)。 在比較不同RDBMS時,你肯定會看到有關(guān)不同RDBMS對JOIN的支持情況,或?qū)QL標(biāo)準(zhǔn)不同解釋的大量爭議。然而有一件事必須注意: 雖然所有這些問題對“報表”和“分析”數(shù)據(jù)庫非常重要,但從以往經(jīng)驗來說,對OLTP數(shù)據(jù)庫并不重要。 OLTP數(shù)據(jù)庫是一種很奇怪的東西,尤其是這一領(lǐng)域很少會使用JOIN語句。當(dāng)然,你可能有時候會需要JOIN(畢竟這是SQL的全部),但大部分情況下OLTP數(shù)據(jù)庫并不需要JOIN(哪怕真的需要JOIN,也可以非常簡單地實現(xiàn))。因此除非為“報表”和“分析”使用同一個數(shù)據(jù)庫(下文將詳細(xì)介紹),這個問題其實并不重要。
然而有些時候確實需要為“報表”和OLTP使用同一個RDBMS,尤其是恰巧在這兩類數(shù)據(jù)庫之間進行了RDBMS級別的復(fù)制時,可以無需自行實現(xiàn),直接獲得所需副本(過程較為簡單,但非常耗時)。 RDBMS供應(yīng)商(尤其是商用供應(yīng)商)還過度鼓吹了另一個問題:容錯。使用容錯功能的數(shù)據(jù)庫服務(wù)器并不能保證可以改善MTBF(考慮到容錯系統(tǒng)本身的MTBF并非無限的,很容易得出這樣的結(jié)論)。更重要的是,現(xiàn)實情況告訴我們,容錯功能的MTBF通常低于高質(zhì)量服務(wù)器硬件自身的MTBF,這意味著如果不使用容錯機制,系統(tǒng)本身的MTBF反而更高(這也是現(xiàn)實世界中經(jīng)驗得出的結(jié)論)。換句話說,對于高質(zhì)量服務(wù)器,硬件(例如CPU或主板)故障幾率遠(yuǎn)低于容錯系統(tǒng)出錯(進而導(dǎo)致各種類型的麻煩,直到最棘手的“腦裂(Split brain)”)的幾率。 當(dāng)然,有些情況下確實需要容錯(例如證交所或銀行的系統(tǒng)),但這些系統(tǒng)很可能運行在DB/2 / Oracle產(chǎn)品之上,它們在這方面表現(xiàn)其實差不多,因此RDBMS的容錯問題也就不那么重要了。
最后同樣重要的一個問題:還需要考慮許可的獲取及相關(guān)成本。一旦開始考慮商用RDBMS的許可問題,你會發(fā)現(xiàn)這些產(chǎn)品不僅昂貴,而且許可機制極為復(fù)雜,可能需要花費數(shù)天時間才能理解到底要花多少錢。我對截止2016年底市面上三大商用RDBMS的許可情況分析如下。 首先是幾個說明:
在各大主要商用數(shù)據(jù)庫中,MS SQL Server是最便宜,許可模式最簡單的產(chǎn)品之一(沒錯,按照商用RDBMS的標(biāo)準(zhǔn)來看真的是既便宜又簡單)。注:下列數(shù)據(jù)來自SQLServer.Editions。 1、Microsoft SQL Server Express 成本:免費。 局限:最多1顆處理器(或4個內(nèi)核,取較小值),1GB內(nèi)存,數(shù)據(jù)庫體積上限10GB。SQL Server 2016中這些限制適用于每實例,主要限制了每個實例(而非每臺數(shù)據(jù)庫服務(wù)器)可用資源總量,通過一臺物理服務(wù)器運行多個實例繞過這些每實例限制的做法是官方允許的,詳情請參閱SQLServer.CapacityLimits。
因此該版本非常適合為每個服務(wù)提供一個數(shù)據(jù)庫(無論是否使用單一數(shù)據(jù)庫連接)的模式。然而考慮到每個數(shù)據(jù)庫10GB容量的限制,就算為每個服務(wù)提供一個數(shù)據(jù)庫,也會很快達到上限。 具備的功能:基本的SQL功能,支持24×7運行,可充當(dāng)復(fù)制關(guān)系中的客戶端。 欠缺的功能:分區(qū),充當(dāng)復(fù)制關(guān)系中的主副本。 當(dāng)然,該版本可以由用戶自行進行分區(qū)和復(fù)制,如果希望針對企業(yè)版之外SQL Server版本自行分區(qū),可使用一些工具,例如Clement實現(xiàn)。 2、Microsoft SQL Server Standard 成本:約每內(nèi)核2千-4千美元(可參閱Ozar和SQLServer.Pricing)。 局限:最多4顆處理器(或24個內(nèi)核,取較小值),128GB內(nèi)存,數(shù)據(jù)庫大小幾乎無上限。 具備的功能:基本的SQL,支持24×7運行、復(fù)制,及SQL Profiler。 缺乏的功能:分區(qū)。 只要預(yù)算允許,SQL Server Standard是一款完整功能的RDBMS產(chǎn)品,很適合用于OLTP負(fù)載。我通常更愿意選擇該產(chǎn)品而非MySQL(出于可靠性和功能豐富程度的考慮),然而如果預(yù)算極為充足,我會考慮用DB/2或Oracle產(chǎn)品代替(雖然通常更貴,但相比MS SQL而言,長遠(yuǎn)來看通常會更可靠)。 3、Microsoft SQL Server Enterprise 成本:每內(nèi)核7千-1.4萬美元。 局限:無。 具備功能:需要的一切功能,外加內(nèi)存中OLTP處理。 缺乏的功能:無。 SQL Server Enterprise無疑很貴,老實說我沒看到該版本有任何實際用例,除了內(nèi)存中OLTP(在這一領(lǐng)域SQL Server在價格方面遠(yuǎn)超其他所有商用RDBMS)。其實如果你按照本書其他章節(jié)提供的思路來設(shè)計數(shù)據(jù)庫架構(gòu),除非每天寫入事務(wù)量上億,否則通常并不需要內(nèi)存中OLTP,這樣價格也就顯得不是那么的高。 BM DB/2在一個領(lǐng)域是不容置疑的冠軍:盡可能讓價格高到離譜讓人難以置信。然而DB/2也確實具備一些不錯的技術(shù)特性(我本人就有良好的使用體驗),因此成本分析中也包含了這個產(chǎn)品。 1、DB/2 Express-C 成本:免費。 局限:最多2個內(nèi)核,16GB內(nèi)存,數(shù)據(jù)庫體積上限15TB。這一系列限制適用于每臺服務(wù)器(而非每個實例),但也可適用于每個虛擬化會話,詳情請參閱RadaMelnyk。 具備的功能:基本的SQL,支持24×7運行。 缺乏的功能:分區(qū),復(fù)制。 總的來說,對于大部分單一寫入數(shù)據(jù)庫連接部署(尤其是使用副本作為報表用途時),2內(nèi)核的限制并不是太糟,通??稍跓o需面臨太多局限的情況下滿足要求。其他局限其實也顯得不是太糟糕了。 另外還可參閱上文自行實現(xiàn)分區(qū)和復(fù)制的介紹(DB/2的自行分區(qū)實現(xiàn)方式與SQL Server差不多)。 2、DB/2 Express DB/2 Express主要有兩種值得我們考慮的定價模式。 成本:DB/2 Express主要有兩種值得我們考慮的定價模式。其中之一基于一種名為PVU(暫不考慮其含義)的概念:約為每PVU 70美元[3]及每內(nèi)核100PVU,換算后價格為每內(nèi)核7千美元。另一種定價模式基于所謂的FTL概念,可將其簡單理解為包年訂閱的全套方案(初始TCO較低,長期范圍內(nèi)較高)。然而我暫時沒找到有關(guān)DB/2最新FTL定價的標(biāo)準(zhǔn)。 局限:最多8內(nèi)核,64GB內(nèi)存(每服務(wù)器),數(shù)據(jù)庫大小上限15TB。 具備的功能:基本的SQL,支持24×7運行和復(fù)制(一種名為SQL Replication的復(fù)制方式)。 缺乏的功能:分區(qū),Q Replication。 DB/2 Express相當(dāng)貴,但功能也相當(dāng)強大。對于OLTP應(yīng)用,通常使用中不可能達到規(guī)格上限,但對報表(和分析)副本,這樣的上限略微有些低。 3、DB/2 Workgroup 顧名思義,DB/2 Workgroup與DB/2 Express基本類似,但存在下列差異: 上限提高至16個內(nèi)核與128GB內(nèi)存(每服務(wù)器)。相比DB/2 Express,成本提高約1.5倍(大約每內(nèi)核1萬美元左右)。是否可以將Workgroup版用于OLTP應(yīng)用這不太好說,但報表副本可以從該版本提高的上限中獲益。 4、DB/2 Enterprise 相比DB/2 Workgroup,上限有所提高,但價格也有了5倍-6倍的提升(約為每內(nèi)核5萬美元左右!)。此外Enterprise Server還提供了一些花哨的功能(例如Q Replication),但老實說與其支付對這么貴的價格,不如自行開發(fā)復(fù)制機制 ;-)。 實際上我沒看到任何將DB/2 Enterprise用于OLTP的用例(甚至銀行/證交所也不會這樣做)。 5、 DB/2 Advanced * Server 為了讓許可機制變得更復(fù)雜,DB/2還提供了Advanced Workgroup Server和Advanced Enterprise Server版本。這些版本的價格高得離譜(Advanced Workgroup的價格與非Advanced Enterprise版價格類似,但Advanced Enterprise的價格比非Advanced Enterprise版高了1.5倍)。另外他們還提供了每TB容量定價的模式(Advanced Workgroup版每TB容量約5萬美元,Advanced Enterprise版每TB10萬美元)。OLTP數(shù)據(jù)庫的容量通常不會超過1TB(但他們沒提供低于1TB容量的許可),因此可以將其理解為實際成本。 在OLTP處理方面,DB/2 Advanced Workgroup Server的用例可能只有一個:那就是你真的非常“不差錢”,并且同時你還需要內(nèi)存處理技術(shù)。 相比BD/2,Oracle的許可機制略微簡單,但實際價格更加昂貴。 1、Oracle DB Express (DB XE) 成本:免費 局限:11GB用戶數(shù)據(jù),最高1GB內(nèi)存,單一內(nèi)核。 具備的功能:基本的SQL,支持24×7運行。 缺乏的功能:分區(qū),復(fù)制。 在我看來,11GB用戶數(shù)據(jù)的限制使得該產(chǎn)品基本無法用于現(xiàn)實環(huán)境,哪怕為每個服務(wù)使用一個數(shù)據(jù)庫也是如此。然而對于OLTP,也不是完全不現(xiàn)實。 2、Oracle DB Standard Edition 2 (DB SE2) 成本:每內(nèi)核17500美元[4](永久許可),每內(nèi)核3500美元(1年期限),此外如果稍后需要使用其他功能,需要隨時準(zhǔn)備好為這些功能額外付費。 局限:最多16個內(nèi)核(或2個處理器,取較小值)。 具備功能:基本的SQL,支持24×7運行,復(fù)制。 缺乏的功能:分區(qū)。 老實說,SE2應(yīng)該已經(jīng)可以滿足所有OLTP負(fù)載的需求(內(nèi)存中處理除外),但成本同樣很高。 3、Oracle DB Enterprise Edition (DB EE) 成本:每內(nèi)核47500美元(永久許可),每CPU 9500美元(1年期限),此外如果稍后需要使用其他功能,需要隨時準(zhǔn)備好為這些功能額外付費。 局限:無。 具備功能:基本的SQL,支持24×7運行,復(fù)制,分區(qū)。 額外付費的可選功能:內(nèi)存中處理(適用于Oracle EE的TimesTen In-Memory Cache)。 我認(rèn)為唯一OLTP環(huán)境中有必要使用Oracle EE的唯一原因是TimesTen,而這技術(shù)真是貴得過分。 上文內(nèi)容可總結(jié)在下表中(但是要注意:下表列出的都是對OLTP生產(chǎn)環(huán)境較為重要的因素,與報表、分析等場景的關(guān)系不大。也就是說,下表并不能告訴你“總的來說最棒的RDBMS是哪個”,而是會告訴你“以寫操作為主的OLTP應(yīng)用最適合的數(shù)據(jù)庫是哪個”): 注意:對OLTP最為重要的特性均使用了粗體字 從上表中可以發(fā)現(xiàn),RDBMS的選擇并不像想象中那么容易。免費的數(shù)據(jù)庫固然很有吸引力;-),但一些問題使其無法用于生產(chǎn)環(huán)境。老實說,如果能忽略價格,我肯定會選擇上述一種商用RDBMS來使用(也許會選擇DB/2或Oracle)。然而就算“標(biāo)準(zhǔn)”、“Express”之類版本的商用RDBMS,價格也顯得非常高,對于企業(yè)級的版本,簡直有些高得讓人無法接受,實際上通常我們并不需要這些產(chǎn)品。 因此如果要開始一個全新的項目,我也許會考慮各種不同選項,并根據(jù)項目的具體需求權(quán)衡利弊。 對于“我們要使用哪個RDBMS”這樣的問題,最可行的回答也許就是:“哪個都行”。這是個很有趣(并且很可行)的選項,為此我們需要確保自己的SQL語句可以跨越不同RDBMS使用。 所有 RDBMS供應(yīng)商都在努力實現(xiàn)供應(yīng)商鎖定,并且通常都會成功。 雖然可以編寫與具體RDBMS無關(guān)的SQL語句,但通常來說這樣做的難度會介于“相當(dāng)難”和“十分難”之間(在我看來,遠(yuǎn)比編寫跨平臺C++更難,而C++本身就夠難著手了)。如此難的主要原因在于所有RDBMS供應(yīng)商都在努力實現(xiàn)供應(yīng)商鎖定,并且通常都會成功。如果你向負(fù)責(zé)數(shù)據(jù)庫的同事詢問這類夸RDBMS的方法,他們有99%的可能性會讓你別犯傻了,為啥放著<他們自己所熟悉的任何RDBMS產(chǎn)品>那么棒的功能不用。 作為各類供應(yīng)商鎖定做法始終不渝的反對者,我非常提倡跨RDBMS SQL(并且已經(jīng)獲得了不錯的成績)。然而這畢竟不是決定項目生死的問題,具體怎樣做還要由你來決定。所有跨平臺的做法面臨著一個共同的情況:一開始很痛苦,但長遠(yuǎn)來看終究會讓你獲益。 如果你也打算朝著這個方向努力,需要注意一些重要的常見問題:
另外,無論負(fù)責(zé)數(shù)據(jù)庫的那幫人怎么跟你說,具體供應(yīng)商專有的擴展都不是獲得更高性能所必需的。 最后同樣重要的是,對SQL綁定(Binging)進行編譯(下文將進行介紹,出于很多原因考慮這都是一種很好的做法)可以對跨平臺SQL的實現(xiàn)提供巨大的幫助。 跨平臺SQL姑且不談,看看都有哪些選項吧。最主要的方法是使用免費的RDBMS。 如果為OLTP應(yīng)用使用免費的RDBMS,我更愿意選擇MySQL+InnoDB而非Postgres。在我看來,有關(guān)Postgres的設(shè)計決策更適合讀取密集型工作負(fù)載而非寫入密集型負(fù)載,有報道Postgres面對寫入密集型OLTP環(huán)境存在嚴(yán)重的性能問題。另外根據(jù)第三方報道,很多非常大型的公司(例如Skype)已經(jīng)成功使用PostgreSQL運行了非常的規(guī)模的負(fù)載,因此在OLTP應(yīng)用中使用Postgres是非??尚械?。 另一方面我要說的是,如果將MySQL用作OLTP數(shù)據(jù)庫,生產(chǎn)環(huán)境中的運行并不像你想象的那么簡單,尤其是為表添加新字段是一種相當(dāng)繁瑣的操作(但也是可以實現(xiàn)的)。 關(guān)于RDBMS還有個問題需要注意:當(dāng)同一時間有成千上萬用戶后,任何停機事件都會造成巨大的損失。這方面商用RDBMS通常比MySQL的社區(qū)版做得更好(社區(qū)版在這方面的改動比商用數(shù)據(jù)庫更頻繁,詳情可參閱Schwartz的討論),當(dāng)然也比Postgres做得好(例如可以參閱Klitzke有關(guān)間歇性數(shù)據(jù)不一致問題的抱怨)。如果選擇MySQL企業(yè)版,其實從價格方面考慮已經(jīng)和另一個競爭者Microsoft SQL Server的價格相差無幾了(如果要在不考慮價格的前提下從這兩者中做選擇,我更愿意選擇至少為OLTP使用SQL Server)。 Microsoft SQL Server的定位恰巧位于兩個極端(免費的數(shù)據(jù)庫,極為昂貴的DB/2和Oracle)之間。很多實際用例中,用戶會出于穩(wěn)定性(24x7連續(xù)運行)和價格的折衷而選擇更顯合理的SQL Server。
如果選擇SQL Server,也許可以首先從免費的SQL Server Express著手(并在數(shù)據(jù)庫容量超過不怎么大的“10GB上限”之前繼續(xù)使用),隨后可以考慮為OLTP購買SQL Server Standard的4內(nèi)核許可,并隨著需求的增加為報表副本購買2個8內(nèi)核許可。這樣的搭配(共20個內(nèi)核的許可,總價格約為4萬-8萬美元)通常可以應(yīng)對同時訪問的成千上萬個用戶。如果預(yù)算允許,這將是一種非??尚械倪x項。 但我想強調(diào)的是,從功能和可靠性的角度考慮(暫不考慮SQL Server過去20年來脫胎換骨的改進),我依然不認(rèn)為MS SQL Server可以成為DB/2和Oracle勢均力敵的對手。然而考慮到其價格(相比其他商用產(chǎn)品更便宜),選擇SQL Server也是一個適度的妥協(xié)。 我認(rèn)為比較可行的方法是,使用商用RDBMS(我個人在使用DB/2時獲得了不錯的體驗)作為OLTP數(shù)據(jù)庫。從個人經(jīng)驗來說,此時最多只需要4個內(nèi)核。同時依照個人經(jīng)驗,OLTP數(shù)據(jù)庫通常并不大(大部分空間都用來保存歷史數(shù)據(jù),這些數(shù)據(jù)其實可以轉(zhuǎn)移到副本中),因此大部分情況下就算為OLTP系統(tǒng)使用免費版RDBMS也是可行的(考慮到各自的局限,免費版DB/2的可行性高于Oracle和SQL Server,但超出免費版限制后DB/2的成本會更高。 如果免費版不夠用,通常使用“標(biāo)準(zhǔn)版”、“Express”版OLTP數(shù)據(jù)庫(但并不用于報表副本)也是可以的(至少你已經(jīng)考慮了成本的問題,而1萬-3萬美元的成本也并沒有高到離譜)。 如果為報表副本使用商用RDBMS(MS SQL Server除外),很可能需要付出更高成本。為了避免這種問題,我們可以使用自行實現(xiàn)的副本,并通過首選RDBMS之外的其他產(chǎn)品運行這些副本(例如Postgres,但有必要進行相應(yīng)的測試以確保復(fù)制寫操作負(fù)載的處理速度足夠快)。 最后同樣重要的是:如果是證交所、銀行、賭場的系統(tǒng),如果不愿意承擔(dān)任何風(fēng)險,此時最佳做法是完全使用DB/2或Oracle。這些行業(yè)通常很賺錢,DB/2或Oracle的許可成本完全不是問題,并且這些RDBMS也是公認(rèn)的高負(fù)荷OLTP環(huán)境最佳選擇(并提供了這些環(huán)境必須的功能)。然而就算這種環(huán)境,大部分情況下Workgroup/SE2版的OLTP數(shù)據(jù)庫也足夠了(但也要具體問題絕體分析)。
本文系“No Bugs” Hare原創(chuàng)文章,已經(jīng)授權(quán)InfoQ翻譯并傳播。閱讀英文原文:Choosing RDMBS for OLTP DB(http:///choosing-rdmbs-for-oltp-db/)本文歸屬于即將出版的圖書《Development&Deployment of Multiplayer Online Games》第2卷“Beta”版第11(f)章。目前這本書正處于Beta測試階段,Beta測試意在改善圖書質(zhì)量,并為協(xié)助改善本書的熱心人提供免費的“可發(fā)行”電子版本,更多詳情請參閱“圖書的Beta測試”。Beta測試過程中發(fā)布的所有內(nèi)容可能會在圖書正式出版前有所改動。 今日薦文點擊下方圖片即可閱讀 QCon北京2017將于4月16日~18日在北京·國家會議中心舉行,精心設(shè)計了智能化運維、支撐海量業(yè)務(wù)的互聯(lián)網(wǎng)架構(gòu)、大規(guī)模網(wǎng)關(guān)系統(tǒng)、微服務(wù)實踐等30來個專題,將邀請來自Google、Facebook、阿里巴巴、騰訊、百度、美團點評、愛奇藝等典型互聯(lián)網(wǎng)公司的技術(shù)專家,分享技術(shù)領(lǐng)域最新成果。敬請期待。 |
|