NoSQL已死:我们不需要他了
作者:Rick Negrin 是 MemSQL 的產品管理團隊負責人,他在微軟工作過 12 年,曾是 SQL Server 團隊的成員。
是時候承認我們早就知道的一個事實了:NoSQL 是并不適合許多現代應用使用場景的工具,是我們該翻篇的時候了。
由于當時的數據庫無力處理所需的規模,NoSQL 技術應運而生。這種新一代數據服務的興起解決了十多年前它問世時互聯網規模和數據迅速增加帶來的許多問題。NoSQL 還為冷存儲/偶爾批量訪問 PB 級數據提供了一條經濟高效的新途徑。然而,因急于解決大數據和大量并發用戶帶來的難題,NoSQL 丟棄了數據庫的一些核心功能,而這些功能使得數據庫擁有高性能和易于使用的優點。
進行這番取舍也許是 NoSQL 為數據庫領域做出的最大貢獻。NoSQL 掀起了一場變革,集最佳的大數據功能與成熟關系模型的結構和靈活性于一體,推出了一種易于擴展的關系數據庫。
關系數據庫不斷發展,打造了全新一代的系統,可處理幾乎所有的工作負載,滿足現代應用所需要的可擴展性、可靠性和可用性等要求。傳統的工作負載(比如事務應用和業務分析)轉向比較新的工作負載(比如多租戶服務和操作分析)。Google Spanner、Azure Data Warehouse 和 MemSQL,這些新的數據庫大行其道證明了這點:對于大多數使用場景而言,關系數據庫比 NoSQL 系統更易于使用,性能通常更勝一籌。
我知道這可能會引起爭議,也知道你可能立馬覺得我的觀點有偏見。不過容我仔細介紹一下這種數據庫的歷史、架構和應用,之后你自行判斷也不遲。
NoSQL 的崛起
NoSQL 在 2000 年代末大放異彩,不過它很早就問世了。它的出現主要是為了解決現有數據庫系統的規模問題。很顯然,橫向擴展(scale out)對于構建大型系統而言是一種更經濟高效的模式。對于谷歌、Facebook、微軟和雅虎構建的超大電子郵件和搜索系統而言,這是擴展規模的唯一方式。
2007 年我讀了 James Hamilton 介紹設計和部署大規模互聯網服務的一篇文章(https://www.usenix.org/legacy/event/lisa07/tech/full_papers/hamilton/hamilton_html/index.html)后,首次認識到了橫向擴展的價值。先是擴展應用層,因為無狀態系統擴展起來比較容易。擴展存儲層是另一回事。根據定義,數據庫是有狀態的,跨分布式系維護該狀態的保證機制(即 ACID)非常困難。于是在現有數據庫系統(比如 MySQL 和 SQL Server 等)的上面構建層,以創建一個分布式存儲層。
我在微軟的 SQL Server 團隊擔任產品經理期間碰到過這方面的幾個例子。第一個例子出現在微軟內部:微軟構建了 Webstore,這是 Hotmail 及相關服務使用的 SQL Server 上面的分片層。實際上,Webstore 是構建最終成為如今的 Azure SQL Database 的數據庫系統的動因。雖然 Webstore 笨拙,缺少許多核心功能,但它很管用,讓微軟既能夠針對所需的數據規模來擴展,又能夠獲得高可用性。但 Webstore 需要整個工程師團隊來構建和維護。
2000 年代中期,MySpace 使用大量的 SQL Server 服務器來管理這個迅速壯大的網站。該公司的用戶增長非常快,每天需要增加新的 SQL Server 機器。運行所有這些 SQL Server、并且跨這些系統進行查詢是一項非常復雜的工作,需要大批工程師來維護。
同樣的情況出現在了 Facebook 及其他公司,因為所有新興的科技巨頭都面臨擴展難題。
很顯然,由于用戶眾多、數據不斷增加,這些新的數字服務巨頭需要一種新的解決方案來獲取、管理和發掘數據。理想情況下,我們需要這樣的系統:可直接提供單一接口,但又能橫向擴展到許多機器上,并擁有內置的高可用性。
最終,大規模云服務(谷歌、Facebook、雅虎和微軟等)都自行構建了定制的系統,以滿足規模擴展需求。那些系統各不相同,但采用了同樣的基本思路,有的直接共享,而有的通過學術共享。最終,采用這些同樣思路的開源系統開始涌現出來,NoSQL 浪潮方興未艾。
為了解決互聯網規模問題,NoSQL 在幾個關鍵方面有悖于傳統數據庫。接下來讓我們看看為什么做出這些選擇。
最終一致性的性能和弊端
存儲系統有兩種模型:ACID 和 BASE。
ACID 代表原子性(Atomic)、一致性(Consistent)、隔離性(Isolation)和持久性(Durable)。它涵蓋了你從大多數關系數據庫獲得的保證。ACID 保證寫入操作必須等數據進入磁盤后才能向客戶端返回成功訊號。此外,如果你很在意持久性(即不丟失數據),你可以對數據庫進行配置,以便等到寫入操作通過網路傳輸到另外某臺機器,數據同樣進入該機器的磁盤。因此保證了寫入數據的正確性,但降低了寫入速度方面的性能。
BASE 是 NoSQL 系統所特有的,代表基本可用(Basically Available)、軟狀態(Soft State)和最終一致(Eventually Consistent)。由于應用程序不必等待查看寫入是否持久化,寫入時可更快地確保最終一致性。一旦數據存儲系統收到寫入操作,但在持久化到磁盤或另一個機器之前,它會告知應用程序寫入操作成功,應用程序可以進入到下一個操作。因此你獲得了性能方面的優勢,但面臨的風險是無法看到剛寫入的數據,或者數據在出錯情況下可能完全丟失。
最終一致性合理兼顧了持久性與可用性。如果貴公司與消費者互動,延遲對貴公司的收入又有直接影響(所有內容、社區和商業應用環境都面臨這個問題),你希望用戶界面(UI)有最快的響應速度。如果你要擴大規模以支持數百萬的并發用戶,就無法容忍任何瓶頸。數據庫架構中采用最終一致性帶來的缺點是偶爾丟失某人的帖子或評論,而這種風險對于這些類型的應用而言是可以接受的。
需要兼顧持久性與可用性的另一個例子是金融應用。你不希望銀行使用最終一致性來存儲 ATM 交易或股票銷售的結果。在這種情況下,用戶仍要求延遲基本為零,而銀行又不愿意接受未寫入到磁盤的交易。
最終一致性有一席之地,但并非始終是唯一的解決方案。數據系統的架構師和開發員應能夠選擇自己想要哪種級別的一致性。應在使用環境層面而不是在平臺層面進行這種選擇。
走無模式道路
目前不清楚為什么 NoSQL 潮流中不見數據庫模式(schema)的影子。是的,早期很難構建一個分布式元數據管理器以便跨分布式系統來維護模式以支持操作,比如添加列。因此,早期設計沒有模式不足為奇。但最終完全消除了模式,而不是后來設法添加模式。有人認為模式會降低敏捷性,這也可以理解。好的模式設計很困難,需要事先認真思考。情況迅速變化時,你不希望被模式所束縛。
但這是一個謬論。
誠然,沒有模式為負責將數據錄入到系統的工程師增強了敏捷性。然而,它把這個問題推給了數據的讀取者(即用戶),而用戶的數量通常高出一個數量級,而且數據寫入時常常不了解數據的狀態。這些用戶通常從數據中創造價值,因此應面臨盡量少的障礙。
打個比方,設想一下圖書館聲稱廢除杜威十進分類法,只是把書扔到地上的一個大洞里,聲稱這是一種更好的分類法,因為圖書管理員要做的工作量少得多。半結構化數據有時間和地點屬性,因為有時你事先不知道一些數據的結構,或者它是否稀疏。但如果你真的不知道任何進來的數據或數據是什么樣子,那么數據又有何啥用?
事實上,模式總是存在。數據對某人來說始終有意義。此人應該花時間將該數據編碼到一個平臺上,以便下一個人可以使用。如果數據混合已了解的數據和迅速變化的數據,那么將后者放到數據庫中的半結構化列,然后搞清楚以后從中映射哪些列。15 年前,SQL Server 和 Oracle 可以對 XML 執行這項任務。MemSQL 及其他許多現代數據庫現在可以對 JSON 數據執行這項任務。文檔數據存儲(以及鍵/值)應該是現代數據庫的一項特性,而不是產品的唯一功能。
面向查詢的非 SQL 語法
NoSQL 數據庫設計中的這個決定遵循了無模式化原則。如果你沒有模式,那么丟棄 SQL 語法還算合理。此外,很難為單單一種設備構建查詢處理器,而構建分布式查詢處理器難得多。尤其是,如果你是開發員,想讓一個新的應用程序啟動并運行起來,這種系統讓人覺得更容易。
MongoDB 在簡單安裝和首次體驗方面做得堪稱完美。但結果證明,關系模型非常強大。如果你根本不想回答“獲取 id 是 2 的對象”之外的任何問題,單單有 get 和 put 函數就行。但是外頭大多數應用程序到頭來需要的不止如此。這篇文章解釋了文檔數據庫的不足之處。
在稍復雜一點的任何系統,你總是希望以不同于存儲數據的方式來查詢數據。具有諷刺意味的是,20 世紀 60 年代發明了關系模型,就是為了解那個年代的數據存儲系統(IMS 和 Codasyl)存在的這個問題。擁有連接(join)功能的關系數據庫是取出數據的唯一合理方式。是的,一開始比較難,但比將所有數據都獲取到你的應用程序中、自行創建連接容易得多。我看到客戶一次次地對 NoSQL 這么做,結果總是讓人抓狂。
許多這些 NoSQL 系統實現了主要目標。它們提供了單一接口的數據存儲系統,可以橫向擴展到許多機器上,擁有內置高可用性。雖然已取得了一定的成功,但 NoSQL 的采用還是遇到了阻礙。
這有幾個原因。性能是關鍵因素,尤其是在有服務級別協議(SLA)的情況下進行分析查詢時。可管理性是另一個原因,因為分布式系統管理起來特別難。但是阻礙 NoSQL 采用的最主要因素還是需要對人員重新培訓。許多人原先接受的是關系數據庫方面的培訓和教育。在過去這 10 年,NoSQL 一直試圖讓關系數據庫人員改弦易轍,但收效甚微。所有 NoSQL 公司在產值 500 億美元的數據庫總共也僅占一小部分的市場份額。
雖然軟件工程師似乎喜歡 NoSQL,但數據人員(數據庫管理員、數據架構師和分析員)老大不情愿地進入 NoSQL 領域;想實現必要的規模,NoSQL 又似乎是唯一的途徑。而這意味著他們要重新學習新的 API、工具和生態系統,扔掉多年來積累的成功方法、模式和資產。他們希望使用一種成熟的模型來做事情,希望在不影響系統持久性、可用性和可靠性的情況下仍可以擴大規模。
從 NoSQL 到 NewSQL ——確保性能和規模,又沒有弊端
我們構建 MemSQL 時,假設客戶喜歡關系數據庫的功能,又想要橫向擴展型系統的可用性和可靠性。我們的目標是讓客戶可以兩全其美。
MemSQL 是一種支持事務和分析的分布式關系數據庫,可在商用硬件上橫向擴展。你可以獲得熟悉的關系模型、SQL 查詢語法和龐大的工具生態系統,以及現代云原生系統的擴展性和可用性。
不妨對照一下 NoSQL 系統的核心差異。
兼顧一致性和性能
MemSQL 有一些旋鈕(knob),讓你可以在一致和性能之間進行適當的兼顧。這種取舍始終不可避免,但如今你不必在平臺層面在這兩者進行選擇。你可以為合適的每個使用場景來進行選擇。
一致性 vs 性能并不是某個棘手的哲學命題,關鍵是哪個對你的應用和需求更重要。MemSQL 有兩個設置可以讓你對此進行調整。第一個設置讓你可以決定是否等待磁盤持久化。有一個內存中緩沖區,可以在事務被持久化到磁盤之前存儲事務。可以在數據一進入緩沖區就返回成功訊號,也可以在數據進入磁盤后返回成功訊號。如果進入緩沖區就返回,可能會在持久化之前出現機器故障或重啟,數據就會丟失。另一方面,等待數據持久化到磁盤要花更長的時間。
此外,如果是高可用性環境,有兩種復制模式:同步復制和異步復制,確保數據在另一臺機器上有第二個副本。如果你將復制設置為同步模式,你要等到輔助機器上收到事務后,才能將成功訊號返回給客戶端。如果使用異步復制模式,事務返回成功訊號之后,數據復制到輔助機器。這讓你能夠調整一致性和持久性,以獲得適合你風險/性能具體要求的性能。
MemSQL 7.0 包括快速同步復制和同步持久性
保持分布式系統中的模式
MemSQL 實現模式的方式是,將元數據存儲在小型內部數據庫中,元數據更改時就將元數據同步復制到所有節點。它使用兩階段提交來確保 DDL 更改在集群中正確地傳播,以一種不會阻塞選擇性查詢的方式來構建。
不過 MemSQL 不僅僅支持關系模型。你可以輸入一個列作為 JSON 列,并存儲一個 JSON 文檔。如果你覺得以后想要查詢幾個列,可以將屬性映射為列,并編制索引。MemSQL 還支持空間類型和全文索引。我們明白,客戶需要在一個熟悉的系統中有混合類型的數據,所有類型的數據都能自然地共存。
保留 SQL“通用語”
MemSQL 解決了在大規模環境下跨分布式數據庫使用 SQL 語法的問題。分布式查詢處理器讓你可以使用標準 SQL 語法來表達查詢,系統負責將查詢任務分配到集群中的各節點,并幫你匯總結果。MemSQL 支持所有常見的 ANSI SQL 操作符和函數,它們為你提供了可表達幾乎任何查詢的強大模型。
MemSQL 通過系統中兩種類型的節點:匯聚器(aggregator)和葉子(leaf)來做到這一點。匯聚器節點處理分布式系統的元數據、路由查詢和聚合結果。葉子節點存儲數據,并處理在分區上執行查詢這項繁重任務。如果可以,MemSQL 會在本地執行連接,這表明了為何模式設計相當重要。如果不行,MemSQL 將根據需要轉移數據。因此,客戶可以在不知道數據在底層如何分區的情況下使用 SQL 語言。
MemSQL 跨匯聚器節點和葉子節點分發數據
這意味著借助 MemSQL,你可以利用貴公司已有的技能、資源和工具,或者人們可以像使用其他關系數據庫那樣使用 MemSQL,不需要重新培訓。此外,由于 MemSQL 支持 MySQL 連線協議,現有的龐大生態系統(包括 BI、ETL 及其他中間件工具)完全與 MemSQL 兼容。你沒必要雇用新的員工、學習一堆新工具或者引進新軟件。只管用就行。
向 NoSQL 說再見!
由于 Web 應用和多租戶服務大行其道,NoSQL 應運而生,以滿足規模需求。想想解決這些問題的難度,就可以理解早期試圖在存儲層處理規模擴展的舉措為何迫使用戶作出艱難的取舍。
但關系數據庫迎來了發展。它們可以處理幾乎所有的工作負載,滿足現代應用程序所需的可擴展性、可靠性和可用性等要求。
由于所有公司意識到數據驅動的價值,它們希望所有員工都能獲得最新的數據。為此,需要一種新的分析系統,可以擴展規模以支持成百上千的并發查詢、不需要預先聚合就可以快速查詢,并且在數據創建時實時獲取數據。除此之外,它們希望向客戶和合作伙伴敞開數據,這需要切實可行的 SLA、安全功能、性能和規模,而目前的數據存儲系統卻滿足不了這個要求。幾種新的工作負載促使企業需要遺留數據庫和 NoSQL 系統無力提供的新功能,操作分析之類的工作負載只是其中之一。
關系模型經受住了時間的考驗,它在不斷添加新的創新。此外,它吸納了新的數據類型(搜索、空間和半結構化數據等)和一致性模型,那樣各種數據就可以在一個系統中共存。關系模型或 SQL 查詢語法沒有固有的可擴展性難題。它只要不同的存儲實現方法,就可以充分利用橫向擴展型架構。
MemSQL 等新的數據庫已證明,對于大多數使用場景而言,關系數據庫更容易使用,通常性能比 NoSQL 系統更勝一籌。
謝謝你,NoSQL。你對數據庫社區施加了壓力,迫使社區解決云規模領域的難題。NoSQL 很管用。然而,關系數據庫取得了發展,可以滿足那些要求。我們已進入到下一個階段。
總結
以上是生活随笔為你收集整理的NoSQL已死:我们不需要他了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 长沙生殖专科医院治疗弱精怎么样?
- 下一篇: 深圳有多少个旅游景点