SQL資料庫真的已經不再那麼重要了嗎?SQL資料庫真的不支援雲端計算嗎?

出版圈郭志敏發表於2013-06-07

有一種說法稱,“雲端計算不再是SQL的時代,而是NoSQL的時代”,因此,不依賴SQL且結構簡單的NoSQL資料庫受到了廣泛的關注。那麼,SQL資料庫真的已經不再那麼重要了嗎?SQL資料庫真的不支援雲端計算嗎?

“雲”的定義

“雲”這個詞有很多種用法,不過它的定義卻非常模糊,導致我們的討論容易過度發散。為了讓論點更加明確,我們在這裡將“雲”定義為“大規模分散式環境”這個概念。

當然,“雲”並非總是代表“大規模分散式環境”,但在資料庫系統的語境中,用“雲”這個詞一般是代表現有資料庫系統很難應對的情況。也就是說,資料量和訪問量這兩者的其中一個,甚至是全部兩個,其規模已經超過單獨一臺資料庫伺服器所能夠應對的程度,必須要依靠由多臺伺服器協同工作所構成的分散式環境來進行應對。 在這樣的環境中,不使用SQL的NoSQL資料庫很受歡迎。像SQL這樣複雜的查詢訪問是受限的,取而代之的則是多個NoSQL資料庫自動分佈到多臺伺服器上的架構。這種方式對大規模分散式環境擁有更強的親和力。

SQL資料庫的極限

那麼,SQL資料庫真的不適合大規模分散式環境嗎?在雲端計算環境中,它真的就不如NoSQL資料庫嗎?事實上並不一定。在雲端計算環境下最大限度利用現有SQL資料庫的技術,目前已經在實用化方面取得了一定的進展。 其中一個基本的思路是對資料庫進行分割。在專業領域,這種資料庫分割被稱為Sharding或者Partitioning。這種手法的目的,是通過將資料庫中大量的記錄分別存放到多臺伺服器中,從而避免資料庫伺服器的瓶頸。以“mixi”這樣的社交網站(SNS)為例,可以理解為將使用者編號為偶數的使用者和編號為奇數的使用者分別存放到不同的資料庫中。這樣就避免了對單獨一臺資料庫伺服器的集中訪問,從而提高了處理速度。第一步的分割可以在應用程式級別上完成,在上述例子中,對編號為偶數和奇數的記錄分別訪問不同的資料庫,而這樣的邏輯可以編寫在應用程式中。

不過,仔細想想就會發現,其實資料庫的分割和應用程式邏輯的本質毫無關係,是需要在資料庫層面上解決的問題。將這樣的邏輯混入應用程式中的話,說實話是很“拙劣”的。資料庫的問題,就應該在資料庫中解決,不是嗎?像這樣能夠實現自動分割的方法有很多種,這裡我們介紹一下為MySQL提供分割功能的“Spider” 。

儲存引擎Spider

Spider是由ST Global公司的斯波健德(Kentoku Shiba)先生開發的一種儲存引擎。在MySQL中,用於查詢處理的資料庫引擎和實際負責儲存資料的儲存引擎是相互獨立的,對於每張資料表都可以採用不同的儲存引擎。可能大家都聽說過“InnoDB”、“MyISAM”之類的名字,這些都是MySQL的儲存引擎。 Spider和它們一樣,也是在MySQL上工作的儲存引擎的一種。不過,Spider自身並不執行實際的資料儲存操作,而是將這些操作交給其他的MySQL伺服器來完成。也就是說,在使用Spider的時候,表面上看起來是一個資料庫,實際上卻可以將資料自動分割儲存在多臺資料庫中(sharding),而且只要對一臺資料庫儲存資料,也會同時在其他伺服器的資料庫中儲存(replication)。比起在應用程式端實現分割來說,用Spider來實現有下列這些優點:

  • 邏輯和資料庫相分離:使用Spider,就意味著從應用程式端看起來,對資料庫的訪問和通常的MySQL訪問是完全一樣的。因此,在應用程式端不需要進行任何特殊的應對。
  • 可維護性高:和分割相關的資訊都只維護在表定義中,而且,資料庫分割策略也可以在表定義中進行設定。關於資料庫的設定都集中在一個地方,這一點從可維護性的角度來說,是非常重要的。

剛才我們介紹了利用MySQL的儲存引擎“Spider”進行自動分割的手法。其實實現自動分割的軟體不僅只有這一種,單在MySQL資料庫中,除了Spider之外,還有像“MySQL Cluster”、“SpockProxy”等其他方案。

SQL資料庫之父的反駁

儘管通過Sharding技術將資料庫進行分割,就能夠在分散式環境中運用SQL資料庫,但卻無法做到像一部分NoSQL資料庫那樣,能夠根據需要自動增加節點來實現效能的擴充。此外,如果用SQL資料庫來實現NoSQL中這種簡單的查詢處理,大多數情況下在效能上(如每秒查詢數)都不及NoSQL。

雖說SQL和NoSQL各自所擅長的領域不同,但很多人曾經認為“在大規模分散式環境中使用NoSQL是板上釘釘的事”。在這個時候,邁克爾•斯通布雷克(Michael Stonebraker,1943~)站了出來。斯通布雷克是最早的RDB系統Ingres的開發者,在Ingres商用化之後,他開發了Ingres的後續版本Postgres,後者演變為現在的PostgreSQL。斯通布雷克應該被稱為“PostgreSQL之父”,但他的貢獻並非僅僅如此。由於Sybase以及Microsoft SQL Server中都繼承了他所開發的Ingres的程式碼,因此毫無疑問,他是一個對於SQL資料庫整體都產生了巨大影響的人物。現在,斯通布雷克擔任MIT(麻省理工學院)客座教授,同時還在幾家資料庫相關的企業中擔任董事。

斯通布雷克在計算機協會ACM 的學術期刊《Communications of the ACM》(ACM通訊)2010年4月號中刊登了一篇題為“SQL Databases vs NoSQL Databases”的專欄 。在該專欄中,斯通布雷克以“所有的技術都有其擅長的領域,沒有一種資料庫是萬能的”為前提,提出了以下觀點:

  • NoSQL的優勢在於效能和靈活性。
  • NoSQL的效能優於SQL這一說法,並非在所有情況下都成立。
  • 通常認為NoSQL是通過犧牲SQL和ACID特性 來實現其效能的,然而效能問題與SQL和ACID是無關的。

說實話,看了這些內容,我的第一反應就是:“唉?真的嗎?”。作為像我這樣寫了很多文章,給別人灌輸了“雲端計算時代非NoSQL莫屬”觀點的人來說,實在是百思不得其解。

那麼我們就來看個究竟吧。根據這篇文章,決定SQL資料庫效能的,是客戶端與伺服器之間的通訊開銷,以及伺服器上的事務處理開銷。而通訊開銷可以通過將大部分處理放在伺服器上的“儲存過程”(Stored Procedure)在一定程度上得以解決。

而對於伺服器上的處理,大致進行分類的話,主要有4個瓶頸,而對於這些瓶頸的應對就是決定效能的關鍵。這4個瓶頸具體如下:

日誌(Logging):為了防止磁碟崩潰等故障的發生,大多數關係型資料庫都會執行兩次寫入。即向資料庫執行一次寫入,再向日誌執行一次寫入。而且,為了防止日誌資訊丟失(為了實現ACID中的D),必須保證這些資料確實寫入了磁碟中。這樣,即便由於一些問題導致資料庫崩潰,也可以根據日誌的內容恢復到故障前的狀態。然而,考慮到向磁碟寫入的速度是非常慢的,因此向日志執行確定的寫入操作是非常“昂貴”的。 事務鎖(Locking):在對記錄進行操作之前,為了防止其他執行緒對記錄進行修改,需要對事務加鎖。這也形成了一項巨大的開銷。

記憶體鎖(Latching):Latch是門閂的意思,這裡是指對鎖和B樹等共享資料結構進行訪問時所需要的一種排他處理方式,斯通布雷克管這種方式叫做Latching。這也是造成開銷的原因之一。

快取管理(Buffer Management):一般來說,資料庫的資料是寫入到固定長度的磁碟頁面中的。對於哪個資料寫入哪個頁面,或者是哪個頁面的資料快取在記憶體中,都需要由資料庫進行管理。這也是一項開銷很大的處理。

斯通布雷克認為,要實現高速的資料庫系統,必須要消除上述所有4個瓶頸,而且上述瓶頸並非SQL資料庫所固有的。聽他這麼一說,好像還真是這麼回事。

NoSQL之所以被認為速度很快,是因為它在設計之初就考慮了分散式環境,通過多個節點將處理分攤了。然而,SQL資料庫也是可以將處理分攤到多個節點上的。此外,即便是NoSQL資料庫,只要涉及到磁碟寫入操作,以及多執行緒架構下的快取管理,也難以迴避上述瓶頸中的一個或幾個。

通過上面的分析,斯通布雷克的結論是,無論是SQL還是ACID特性,都不是影響雲端計算環境下資料庫效能的本質性障礙。

本文摘自已經上市的《程式碼的未來》

相關文章