走向無伺服器資料庫—如何以及為何

大家好! 我的名字是戈洛夫·尼古拉。 在此之前,我在 Avito 工作並管理資料平台六年,也就是說,我負責所有資料庫:分析型(Vertica、ClickHouse)、串流處理和 OLTP(Redis、Tarantool、VoltDB、MongoDB、PostgreSQL)。 在此期間,我處理了大量的資料庫 - 非常不同和不尋常,以及它們的使用非標準情況。

我目前在 ManyChat 工作。 本質上,這是一家新創公司——新的、雄心勃勃的、快速成長的。 當我第一次加入公司時,出現了一個經典問題:“一家年輕的新創公司現在應該從 DBMS 和資料庫市場中獲得什麼?”

在這篇文章中,基於我的報告 線上音樂節 RIT++2020,我來回答這個問題。 該報告的視訊版本可在以下網址取得: YouTube.

走向無伺服器資料庫—如何以及為何

2020年常見資料庫

現在是 2020 年,我環顧四周,看到了三種類型的資料庫。

第一種類型— 經典OLTP資料庫:PostgreSQL、SQL Server、Oracle、MySQL。 它們是很久以前編寫的,但仍然具有相關性,因為它們對開發者社群來說非常熟悉。

第二種是 從“零”開始。 他們試圖透過放棄 SQL、傳統結構和 ACID、添加內建分片和其他有吸引力的功能來擺脫經典模式。 例如,這是 Cassandra、MongoDB、Redis 或 Tarantool。 所有這些解決方案都希望為市場提供一些全新的東西並佔據自己的利基市場,因為事實證明它們對於某些任務來說非常方便。 我將用總稱 NOSQL 來表示這些資料庫。

「零」時代已經過去,我們已經習慣了 NOSQL 資料庫,從我的角度來看,世界邁出了下一步—— 託管資料庫。 這些資料庫與經典 OLTP 資料庫或新的 NoSQL 資料庫具有相同的核心。 但它們不需要 DBA 和 DevOps,並且在雲端中的託管硬體上運行。 對於開發人員來說,這“只是一個在某處工作的基礎”,但沒有人關心它如何安裝在伺服器上、誰配置了伺服器以及誰更新了它。

此類資料庫的範例:

  • AWS RDS 是 PostgreSQL/MySQL 的託管包裝器。
  • DynamoDB 是基於文件的資料庫的 AWS 類似物,類似於 Redis 和 MongoDB。
  • Amazon Redshift 是一個託管分析資料庫。

這些基本上是舊資料庫,但在託管環境中提出,不需要使用硬體。

筆記。 這些範例針對的是 AWS 環境,但它們的類似物也存在於 Microsoft Azure、Google Cloud 或 Yandex.Cloud 中。

走向無伺服器資料庫—如何以及為何

這有什麼新鮮事嗎? 到了2020年,這些都沒有了。

無伺服器概念

2020 年市場上真正的新鮮事是無伺服器或無伺服器解決方案。

我將嘗試使用常規服務或後端應用程式的範例來解釋這意味著什麼。
要部署常規後端應用程序,我們購買或租用伺服器,將代碼複製到其上,將端點發佈到外部並定期支付租金、電費和資料中心服務費用。 這是標準方案。

還有其他辦法嗎? 借助無伺服器服務,您就可以做到。

這種方法的重點是什麼:沒有伺服器,甚至沒有在雲端租用虛擬實例。 要部署服務,請將程式碼(函數)複製到儲存庫並將其發佈到端點。 然後我們只需為該函數的每次呼叫付費,完全忽略執行該函數的硬體。

我將嘗試用圖片來說明這種方法。
走向無伺服器資料庫—如何以及為何

經典部署。 我們有一個具有一定負載的服務。 我們提出兩個實例:實體伺服器或AWS中的實例。 外部請求被傳送到這些實例並在那裡處理。

正如您在圖片中看到的,伺服器的處理方式並不均衡。 一種是 100% 利用率,有兩個請求,一種是僅 50% - 部分閒置。 如果不是三個請求到達,而是 30 個,那麼整個系統將無法應對負載並開始變慢。

走向無伺服器資料庫—如何以及為何

無伺服器部署。 在無伺服器環境中,此類服務沒有實例或伺服器。 有一定的熱資源池 - 已部署功能程式碼的小型準備好的 Docker 容器。 系統接收外部請求,對於每個請求,無伺服器框架都會產生一個帶有程式碼的小容器:它處理這個特定的請求並殺死該容器。

一個請求 - 提出一個容器,1000 個請求 - 1000 個容器。 而在硬體伺服器上的部署已經是雲端提供者的工作了。 它被無伺服器框架完全隱藏。 在這個概念中,我們為每次通話付費。 例如,一天打個電話 - 我們為一個電話付費,每分鐘打一百萬個電話 - 我們為一百萬個電話付費。 或者下一秒,也會發生這種情況。

發布無伺服器函數的概念適用於無狀態服務。 如果您需要(狀態)全狀態服務,那麼我們會向該服務新增資料庫。 在這種情況下,當涉及狀態時,每個有狀態函數只需從資料庫中寫入和讀取。 此外,來自本文開頭描述的三種類型中任何一種的資料庫。

所有這些資料庫的共同限制是什麼? 這些是經常使用的雲端或硬體伺服器(或多個伺服器)的成本。 無論我們使用經典資料庫還是託管資料庫,無論我們是否有 DevOps 和管理員,我們仍然需要 24/7 支付硬體、電力和資料中心租金。 如果我們有一個經典的基地,我們就為主人和奴隸付費。 如果是高負載的分片資料庫,我們會為 10、20 或 30 台伺服器付費,而且會持續付費。

成本結構中永久保留伺服器的存在以前被認為是一種不可避免的罪。 傳統資料庫還有其他困難,例如連線數量限制、擴展限制、地理分散式共識——這些問題可以在某些資料庫中以某種方式解決,但不能一次全部解決,而且效果也不理想。

無伺服器資料庫 - 理論

2020年問題:資料庫也可以無伺服器化嗎? 每個人都聽說過無伺服器後端...讓我們嘗試使資料庫無伺服器?

這聽起來很奇怪,因為資料庫是一個有狀態服務,不太適合無伺服器基礎架構。 同時,資料庫的狀態非常大:千兆位元組、太字節,在分析資料庫中甚至是拍字節。 在輕量級 Docker 容器中提升它並不容易。

另一方面,幾乎所有現代資料庫都包含大量邏輯和元件:事務、完整性協調、過程、關係依賴和大量邏輯。 對於相當多的資料庫邏輯來說,一個小的狀態就足夠了。 千兆位元組和太字節僅由直接執行查詢所涉及的一小部分資料庫邏輯直接使用。

因此,這個想法是:如果部分邏輯允許無狀態執行,為什麼不將基礎分為有狀態和無狀態部分。

用於 OLAP 解決方案的無伺服器

讓我們透過實際範例來看看將資料庫分為有狀態部分和無狀態部分會是什麼樣子。

走向無伺服器資料庫—如何以及為何

例如,我們有一個分析資料庫:外部資料(左側紅色圓柱體)、將資料載入到資料庫中的 ETL 過程以及向資料庫發送 SQL 查詢的分析人員。 這是一個經典的資料倉儲操作方案。

在這個方案中,ETL 有條件地執行一次。 然後,您需要不斷地為運行資料庫並填充 ETL 資料的伺服器付費,以便有東西可以向其發送查詢。

讓我們來看看 AWS Athena Serverless 中實作的替代方法。 沒有永久專用的硬體來儲存下載的資料。 而不是這個:

  • 使用者向 Athena 提交 SQL 查詢。 Athena 優化器分析 SQL 查詢並在元資料儲存(Metadata)中搜尋執行查詢所需的特定資料。
  • 優化器根據收集到的數據,從外部來源下載必要的數據到臨時儲存(臨時資料庫)。
  • 使用者發出的SQL查詢在暫存中執行,並將結果傳回給使用者。
  • 暫時儲存被清除,資源被釋放。

在這個架構中,我們只需為執行請求的過程付費。 沒有要求 - 沒有成本。

走向無伺服器資料庫—如何以及為何

這是一種可行的方法,不僅在 Athena Serverless 中實現,還在 Redshift Spectrum(在 AWS 中)中實現。

Athena 範例表明,無伺服器資料庫可以處理數十甚至數百 TB 資料的實際查詢。 數百 TB 將需要數百台伺服器,但我們不必為它們付費 - 我們為請求付費。 與 Vertica 等專業分析資料庫相比,每個請求的速度(非常)低,但我們不會為停機時間付費。

這樣的資料庫適用於罕見的分析即席查詢。 例如,當我們自發性地決定用大量資料來檢驗一個假設。 Athena 非常適合這些情況。 對於常規請求,這樣的系統非常昂貴。 在這種情況下,請將資料緩存在一些專門的解決方案中。

用於 OLTP 解決方案的無伺服器

前面的範例著重於 OLAP(分析)任務。 現在讓我們來看看 OLTP 任務。

讓我們想像一下可擴充的 PostgreSQL 或 MySQL。 讓我們用最少的資源建立一個常規託管實例 PostgreSQL 或 MySQL。 當實例接收更多負載時,我們將連接額外的副本,我們將向其分配部分讀取負載。 如果沒有請求或負載,我們將關閉副本。 第一個實例是主實例,其餘實例是副本。

這個想法在一個名為 Aurora Serverless AWS 的資料庫中實作。 原理很簡單:代理程式佇列接受來自外部應用程式的請求。 看到負載增加後,它會從預熱的最小實例中分配計算資源 - 盡快建立連線。 禁用實例以相同的方式發生。

Aurora 中有 Aurora 容量單位 (ACU) 的概念。 這是(有條件地)一個實例(伺服器)。 每個特定的 ACU 可以是主設備或從設備。 每個容量單元都有自己的 RAM、處理器和最小磁碟。 因此,一個是主副本,其餘的是只讀副本。

運行的這些 Aurora 容量單元的數量是一個可配置參數。 最小數量可以是 XNUMX 或零(在這種情況下,如果沒有請求,資料庫將無法運作)。

走向無伺服器資料庫—如何以及為何

當基礎接收到請求時,代理程式佇列會提高 AuroraCapacityUnits,進而增加系統的效能資源。 增加和減少資源的能力使系統能夠「處理」資源:自動顯示各個 ACU(用新的 ACU 取代它們)並對撤回的資源推出所有當前更新。

Aurora Serverless 基礎可以擴充讀取負載。 但文檔並沒有直接說明這一點。 可能感覺他們可以舉起多大師。 沒有魔法。

該資料庫非常適合避免在存取不可預測的系統上花費大量資金。 例如,在創建 MVP 或行銷名片網站時,我們通常不期望穩定的負載。 因此,如果無法訪問,我們不會為實例付費。 當發生意外負載時,例如會議或廣告活動結束後,大量人訪問站點,負載急劇增加,Aurora Serverless 會自動承擔此負載并快速連接缺失的資源 (ACU)。 然後會議結束,每個人都忘記了原型,伺服器(ACU)變黑,成本降到零——方便。

此解決方案不適合穩定的高負載,因為它無法擴展寫入負載。 所有這些資源連接和斷開都發生在所謂的「擴展點」——事務或臨時表不支援資料庫的時間點。 例如,一周之內可能不會發生規模點,而基礎在相同的資源上工作,根本無法擴展或收縮。

沒有什麼魔法——它就是普通的 PostgreSQL。 但添加機器和斷開連接的過程是部分自動化的。

無伺服器設計

Aurora Serverless 是針對雲端重寫的舊資料庫,以利用 Serverless 的一些優勢。 現在我將告訴您有關該基礎的信息,該基礎最初是為雲端、無伺服器方法(無伺服器設計)編寫的。 它立即被開發出來,並沒有假設它會在實體伺服器上運行。

這個底座被稱為雪花。 它具有三個關鍵區塊。

走向無伺服器資料庫—如何以及為何

第一個是元資料塊。 這是一種快速的記憶體服務,可以解決安全性、元資料、事務和查詢最佳化問題(如左圖所示)。

第二個區塊是一組用於計算的虛擬計算集群(圖中有一組藍色圓圈)。

第三塊是基於S3的資料儲存系統。 S3 是 AWS 中的無量綱物件存儲,有點像商業用的無量綱 Dropbox。

讓我們看看 Snowflake 是如何運作的(假設冷啟動)。 也就是說,有一個資料庫,資料已載入到其中,沒有正在執行的查詢。 因此,如果沒有對資料庫的請求,那麼我們就提出了快速記憶體元資料服務(第一個區塊)。 我們有 S3 存儲,其中存儲表數據,分為所謂的微分區。 為簡單起見:如果表包含事務,那麼微分區就是事務的天數。 每一天都是一個單獨的微分區,一個單獨的檔案。 並且當資料庫以這種模式運行時,您只需為資料佔用的空間付費。 而且,每個座位的使用率非常低(特別是考慮到顯著的壓縮)。 元資料服務也持續運作,但您不需要大量資源來最佳化查詢,並且該服務可以被視為共享軟體。

現在我們假設一個使用者來到我們的資料庫並發送了一個 SQL 查詢。 SQL 查詢立即傳送至元資料服務進行處理。 因此,在收到請求後,該服務會分析該請求、可用資料、使用者權限,如果一切順利,則制定處理該請求的計劃。

接下來,服務啟動計算叢集。 計算集群是執行計算的伺服器集群。 也就是說,這是一個可以包含 1 台伺服器、2 台伺服器、4、8、16、32 台伺服器的叢集——任意數量。 您發出一個請求,該叢集就會立即開始啟動。 確實需要幾秒鐘。

走向無伺服器資料庫—如何以及為何

接下來,叢集啟動後,處理請求所需的微分區開始從 S3 複製到叢集。 也就是說,假設要執行 SQL 查詢,您需要一個表的兩個分區,另一個表的一個分區。 在這種情況下,只有三個必要的分區將複製到集群,而不是全部表。 這就是為什麼,正是因為所有內容都位於一個資料中心內並透過非常快的通道連接,所以整個傳輸過程發生得非常快:幾秒鐘,很少是幾分鐘,除非我們正在談論一些巨大的請求。 因此,微分區被複製到計算集群,並且完成後,在該計算集群上執行SQL查詢。 該請求的結果可以是一行、幾行或一張表——它們從外部發送給用戶,以便他可以下載它、在他的 BI 工具中顯示它或以其他方式使用它。

每個 SQL 查詢不僅可以從先前載入的資料中讀取聚合,還可以在資料庫中載入/產生新資料。 也就是說,它可以是一個查詢,例如將新記錄插入到另一個表中,這會導致計算叢集上出現新分區,而新分區又會自動保存在單一 S3 儲存中。

上述場景,從使用者到來到叢集搭建、載入資料、執行查詢、取得結果,依照搭建的虛擬計算叢集、虛擬倉庫的使用分鐘數進行計費。 費率根據 AWS 區域和群集大小而有所不同,但平均為每小時幾美元。 由四台機器組成的集群比由兩台機器組成的集群昂貴兩倍,而由八台機器組成的集群仍然昂貴兩倍。 根據請求的複雜程度,可以選擇 16 台、32 台機器。 但您只需為叢集實際運行時的幾分鐘付費,因為當沒有請求時,您就可以鬆開手,等待 5-10 分鐘(可配置參數)後,它會自行退出,釋放資源並變得自由。

一個完全現實的場景是,當你發送一個請求時,集群就彈出來,相對來說,一分鐘,又算一分鐘,然後五分鐘關閉,最後你要為這個集群的七分鐘運行付費,並且不是幾個月或幾年。

第一個場景描述了在單一使用者設定中使用 Snowflake。 現在我們假設有很多用戶,這樣更接近真實的場景。

假設我們有許多分析師和 Tableau 報告,它們不斷地用大量簡單的分析 SQL 查詢轟炸我們的資料庫。

此外,假設我們有富有創意的數據科學家,他們試圖利用數據做一些可怕的事情,操作數十 TB 的數據,分析數十億和數萬億行的數據。

對於上述兩種類型的工作負載,Snowflake可讓您組成多個不同容量的獨立運算叢集。 此外,這些計算集群獨立工作,但具有共同的一致數據。

對於大量的輕查詢,您可以組成 2-3 個小集群,每個集群大約 2 台機器。 除此之外,可以使用自動設定來實現此行為。 所以你說:「雪花,舉起一小簇。 如果其上的負載增加到某個參數以上,則提高類似的第二個、第三個參數。 當負載開始減弱時,消除多餘的負載。” 這樣無論有多少分析師來看報告,每個人都有足夠的資源。

同時,如果分析師睡著了,沒有人看報告,集群可能會完全變黑,你就停止為它們付費。

同時,對於繁重的查詢(來自資料科學家),您可以為 32 台機器建立一個非常大的叢集。 當您的巨大請求在那裡運行時,該叢集也將僅按分鐘和小時付費。

上述機會使您不僅可以將 2 種工作負載劃分為集群,還可以將更多類型的工作負載劃分為集群(ETL、監控、報告實現等)。

讓我們總結一下雪花。 這個基礎結合了美好的想法和可行的實施。 在 ManyChat,我們使用 Snowflake 來分析我們擁有的所有數據。 我們沒有像範例中那樣擁有三個集群,而是有 5 到 9 個不同大小的集群。 我們有傳統的16機、2機,還有超小型1機來完成某些任務。 他們成功地分配了負載,讓我們節省了很多。

資料庫成功擴展了讀寫負載。 這與同樣只承載閱讀負載的《極光》相比,是一個巨大的差異,也是一個巨大的突破。 Snowflake 讓您使用這些運算叢集來擴充您的寫入工作負載。 也就是說,正如我所提到的,我們在ManyChat中使用了幾個集群,小型和超小型集群主要用於ETL,用於載入資料。 而且分析師已經生活在中型叢集上,絕對不會受到 ETL 負載的影響,因此他們的工作速度非常快。

因此,該資料庫非常適合 OLAP 任務。 但不幸的是,它尚不適用於 OLTP 工作負載。 首先,這個資料庫是柱狀的,隨之而來的就是所有後果。 其次,不幸的是,對於每個請求,如果有必要,您會建立一個計算叢集並用資料淹沒它,該方法本身對於 OLTP 負載來說還不夠快。 對於OLAP任務來說等待幾秒鐘是正常的,但是對於OLTP任務來說這是不可接受的;100毫秒更好,或者10毫秒更好。

透過將資料庫分為無狀態和有狀態部分,可以實現無伺服器資料庫。 您可能已經注意到,在上述所有範例中,相對而言,Stateful 部分是將微分區儲存在S3 中,Stateless 是優化器,處理元數據,處理可能作為獨立輕量級無狀態服務引發的安全問題。

執行SQL查詢也可以被視為輕狀態服務,可以在無伺服器模式下彈出,就像Snowflake計算叢集一樣,只下載必要的數據,執行查詢並「出去」。

無伺服器生產級資料庫已經可供使用,並且正在運行。 這些無伺服器資料庫已經準備好處理 OLAP 任務。 不幸的是,對於 OLTP 任務,它們的使用......存在細微差別,因為存在局限性。 一方面,這是一個缺點。 但從另一方面來說,這也是一個機會。 也許其中一位讀者會找到一種方法使 OLTP 資料庫完全無伺服器,而不受 Aurora 的限制。

我希望你覺得這很有趣。 無伺服器是未來:)

來源: www.habr.com

添加評論