哈布羅夫斯克的居民們大家好。 像往常一樣,我們在新課程開始之前繼續分享有趣的材料。 今天,為了配合課程的推出,我們特別為您發布了一篇有關 Google Cloud Spanner 的文章
原發表於
作為一家為世界各地的零售商、餐廳和線上賣家提供各種基於雲端的 POS 解決方案的公司,Lightspeed 使用多種不同類型的資料庫平台來處理各種交易、分析和搜尋用例。 這些資料庫平台都有自己的優點和缺點。因此,當Google 將Cloud Spanner 推向市場時,它帶來了關聯式資料庫領域中前所未見的功能,例如幾乎無限的水平可擴展性和99,999% 的服務等級協定(SLA), ——我們不能錯過這個機會!
為了全面概述我們使用 Cloud Spanner 的經驗以及我們使用的評估標準,我們將涵蓋以下主題:
- 我們的評價標準
- 雲端扳手簡而言之
- 我們的評估
- 我們的發現
1. 我們的評價標準
在深入了解 Cloud Spanner 的具體情況及其與市場上其他解決方案的異同之前,我們首先討論一下在考慮在基礎設施中部署 Cloud Spanner 時想到的主要用例:
- 作為(主要的)傳統 SQL 資料庫解決方案的替代品
- 如何使用 OLAP 支援進行 OLTP 解決方案
注: 為了簡單且易於比較,本文將 Cloud Spanner 與 GCP Cloud SQL 和 Amazon AWS RDS 解決方案系列的 MySQL 變體進行了比較。
使用 Cloud Spanner 取代傳統 SQL 資料庫解決方案
在環境中 傳統的 在資料庫中,當資料庫查詢回應時間接近甚至超過預先定義的應用程式閾值(主要是由於使用者和/或請求數量的增加)時,有多種方法可以將回應時間減少到可接受的水平。 然而,這些解決方案大多數都涉及手動幹預。
例如,第一步是查看各種與效能相關的資料庫參數,並將它們調整為最匹配應用程式用例模式。 如果這還不夠,您可以選擇垂直或水平擴展資料庫。
垂直擴展應用程式需要升級伺服器實例,通常透過添加更多的處理器/核心、更多的RAM、更快的儲存等。增加更多的硬體資源會提高資料庫效能,主要以秒級事務和OLTP 系統的事務延遲來衡量。 MySQL 等關係型資料庫系統(使用多執行緒方法)可以很好地垂直擴展。
這種方法有幾個缺點,但最明顯的是市場上最大的伺服器尺寸。 一旦達到最大伺服器實例的限制,就只剩下一個選擇:水平擴展。
水平擴展是一種將更多伺服器添加到叢集中的方法,理想情況下隨著伺服器數量的添加線性提高效能。 多數 傳統的 資料庫系統不能很好地水平擴展或根本不能擴展。 例如,MySQL可以透過新增從屬讀取器來水平擴展讀取操作,但無法水平擴展寫入操作。
另一方面,由於其性質,Cloud Spanner 可以以最少的干預輕鬆水平擴展。
功能齊全 DBMS 即服務 必須從不同角度進行評估。 作為基礎,我們採用了雲端中最受歡迎的 DBMS - 對於 Google,GCP Cloud SQL 和對於 Amazon,AWS RDS。 在我們的評估中,我們將重點放在以下類別:
- 特徵映射:範圍SQL、DDL、DML; 連接庫/連接器、事務支援等等。
- 開發支援:輕鬆開發和測試。
- 管理支援:實例管理 - 例如,擴大/縮小和升級實例; SLA、備份和復原; 安全/存取控制。
使用 Cloud Spanner 作為支援 OLAP 的 OLTP 解決方案
雖然 Google 沒有明確聲稱 Cloud Spanner 是為分析處理而設計的,但它與其他引擎共享一些屬性,例如 Apache Impala & Kudu 和 YugaByte,這些引擎是為 OLAP 工作負載設計的。
即使 Cloud Spanner 包含一致的橫向擴展 HTAP(混合事務/分析處理)引擎和(或多或少)可用的 OLAP 功能集的可能性很小,我們也認為它值得我們關注。
考慮到這一點,我們研究了以下類別:
- 資料載入、索引和分區支持
- 查詢效能和 DML
2. Cloud Spanner 簡而言之
Google Spanner 是一個叢集關聯式資料庫管理系統 (RDBMS),Google 將其用於自己的多項服務。 谷歌於 2017 年初向Google雲端平台用戶全面開放。
以下是 Cloud Spanner 的一些屬性:
- 高度一致的可擴展RDBMS叢集:使用硬體時間同步來確保資料的一致性。
- 跨表事務支援:事務可以跨越多個表 - 不一定限於單一表(與 Apache HBase 或 Apache Kudu 不同)。
- 基於主鍵的表:所有表都必須有一個聲明的主鍵(PC),它可以由表中的多個列組成。 表格資料按照PC順序存儲,使得PC搜尋非常有效率、快速。 與其他基於 PC 的系統一樣,必須根據預先設計的用例對實作進行建模,以實現
最棒的表演 . - 條帶錶:表之間可以具有物理依賴性。 子表中的行可以與父表中的行進行比對。 這種方法可以加快搜尋在資料建模階段可以識別的關係,例如共同定位客戶及其發票。
- 索引:Cloud Spanner 支援二級索引。 索引由索引列和所有 PC 列組成。 如果需要,索引還可以包含其他非索引列。 索引可以與父表交錯以加快查詢速度。 有幾個限制適用於索引,例如索引中儲存的附加列的最大數量。 此外,透過索引的查詢可能不像其他 RDBMS 那麼簡單。
「Cloud Spanner 僅在極少數情況下自動選擇索引。 特別是,如果查詢請求的任何欄位未儲存在 Cloud Spanner 中,則 Cloud Spanner 不會自動選擇二級索引。
- 服務等級協定(SLA):在一個區域部署,SLA達到99,99%; 具有 99,999% SLA 的多區域部署。 雖然 SLA 本身只是一項協議,而不是任何形式的保證,但我相信 Google 的人員確實有一些確鑿的數據來做出如此強有力的聲明。 (僅供參考,99,999% 表示每月有 26,3 秒的服務不可用。)
- 更多:
https://cloud.google.com/spanner/
注: Apache Tephra 專案為 Apache HBase 新增了增強的事務支援(現在也在 Apache Phoenix 中作為測試版實作)。
3. 我們的評估
因此,我們都讀過 Google 關於 Cloud Spanner 優勢的聲明 - 幾乎無限的水平擴展,同時保持高一致性和非常高的 SLA。 儘管這些要求無論如何都很難實現,但我們的目的不是反駁它們。 相反,讓我們專注於大多數資料庫使用者關心的其他事情:奇偶性和可用性。
我們評估 Cloud Spanner 作為 Sharded MySQL 的替代品
Google Cloud SQL 和 Amazon AWS RDS 是雲端市場上最受歡迎的兩種 OLTP DBMS,擁有大量功能。 但是,要將這些資料庫擴展到超出單一節點的大小,您需要執行應用程式分區。 這種方法為應用程式和管理帶來了額外的複雜性。 我們研究了 Spanner 如何適應將多個分片組合成單一實例的場景,以及可能需要犧牲哪些功能(如果有)。
SQL、DML 和 DDL 支持,以及連接器和函式庫?
首先,在開始使用任何資料庫時,您需要建立一個資料模型。 如果您認為可以將 JDBC Spanner 連接到您最喜歡的 SQL 工具,您會發現您可以使用它來查詢數據,但不能使用它來建立表格或修改 (DDL) 或任何插入/更新/刪除操作(DML)。 Google 的官方 JDBC 不支援其中任何一個。
“驅動程式目前不支援 DML 或 DDL 語句。”
扳手文檔
GCP 控制台的情況也好不了多少 - 您只能發送 SELECT 查詢。 幸運的是,社區有一個支援 DML 和 DDL 的 JDBC 驅動程序,包括事務
幾乎強制使用 Cloud Spanner 自訂 API(由於 JDBC 中缺乏 DDL 和 DML)導致相關程式碼區域(例如連線池或資料庫綁定框架(例如 Spring MVC))受到一些限制。 通常,在使用 JDBC 時,您可以自由選擇您喜歡的經過測試且運作良好的連線池(例如 HikariCP、DBCP、C3PO 等)。 對於自訂 Spanner API,我們必須依賴我們自己建立的框架/綁定池/會話。
以主鍵 (PC) 為中心的設計使得 Cloud Spanner 在透過 PC 存取資料時速度非常快,但也引入了一些查詢問題。
- 您無法更新主鍵值; 您必須先從原始 PC 中刪除該條目,然後使用新值重新插入。 (這與其他面向 PC 的資料庫/儲存引擎類似。)
- 任何 UPDATE 和 DELETE 語句都必須在 WHERE 中指定 PC,因此不能為空 DELETE all 語句 - 必須始終有一個子查詢,例如: UPDATE xxx WHERE id IN (SELECT id FROM table1)
- 缺少自動增量選項或任何類似的設定 PC 欄位順序的選項。 為此,必須在應用程式端建立相應的值。
二級指標?
Google Cloud Spanner 內建了對二級索引的支援。 這是一個非常好的功能,在其他技術中並不總是存在。 Apache Kudu 目前完全不支援二級索引,Apache HBase 也不直接支援索引,但可以透過 Apache Phoenix 新增索引。
Kudu 和 HBase 中的索引可以建模為具有不同主鍵組合的單獨表,但對父表和關聯索引表執行的操作的原子性必須在應用程式層級完成,並且正確實作並不簡單。
正如 Cloud Spanner 評論中所提到的,它的索引可能與 MySQL 索引不同。 因此,在建立查詢和分析時應特別小心,以確保在需要的地方使用正確的索引。
表示?
資料庫中一個非常流行且有用的物件是視圖。 它們對於大量用例很有用; 我最喜歡的兩個是邏輯抽象層和安全層。 不幸的是,Cloud Spanner 不支援視圖。 但是,這僅部分限制了我們,因為列層級的存取權限沒有粒度,而視圖可能是可行的解決方案。
請參閱 Cloud Spanner 文檔,以了解詳細介紹配額和限制的部分 (
開發支援?
Cloud Spanner 為其 API 的使用提供了相當不錯的程式語言支援。 官方支援的函式庫包括 C#、Go、Java、node.js、PHP、Python 和 Ruby。 文件非常詳細,但與其他先進技術一樣,與最受歡迎的資料庫技術相比,社群相當小,這可能導致花費更多時間來解決不太常見的用例或問題。
那麼支持當地發展呢?
我們尚未找到在本地建立 Cloud Spanner 實例的方法。 我們得到的最接近的是 Docker 映像。
行政支援?
建立 Cloud Spanner 實例非常簡單。 您只需選擇建立多區域或單區域實例,指定區域和節點數量。 不到一分鐘,您的執行個體就會啟動並執行。
可以從 Google Console 中的 Spanner 頁面直接存取幾個基本指標。 透過 Stackdriver 可以獲得更詳細的視圖,您還可以在其中設定指標閾值和警報策略。
獲取資源?
MySQL 為使用者權限/角色提供了廣泛且非常精細的設定。 您可以輕鬆配置對特定表甚至其列的子集的存取。 Cloud Spanner 使用 Google 的身份和存取管理 (IAM) 工具,該工具僅允許您在非常高的層級設定策略和權限。 最細粒度的選項是資料庫層級解析,它不適合大多數生產用例。 此限制迫使您為程式碼、基礎設施或兩者添加額外的安全措施,以防止未經授權使用 Spanner 資源。
備份?
簡而言之,Cloud Spanner 中沒有備份。 儘管Google的高SLA要求可以確保您不會因為硬體或資料庫故障、人為錯誤、應用程式缺陷等而丟失任何資料。我們都知道規則:高可用性並不能取代健全的備份策略。 目前,備份資料的唯一方法是以程式設計方式將其從資料庫串流傳輸到單獨的儲存環境。
查詢效能?
我們使用 Yahoo! 載入資料並測試查詢。 雲端服務基準。 下表顯示了 YCSB 工作負載 B,讀取比率為 95%,寫入比率為 5%。
* 負載測試在 n1-standard-32 計算引擎 (CE)(32 vCPU、120 GB 記憶體)上運行,測試實例從來都不是測試中的瓶頸。
** 單一 YCSB 實例中的最大執行緒數為 400。必須執行總共 2400 個並行的 YCSB 測試實例才能獲得總共 XNUMX 個執行緒。
查看基準測試結果,特別是 CPU 負載和 TPS 的組合,我們可以清楚地看到 Cloud Spanner 的擴充性相當好。 Cloud Spanner 叢集中的大量節點抵消了大量線程產生的重負載。 雖然延遲看起來相當高,尤其是在使用 2400 個執行緒運行時,但可能需要使用 6 個較小的運算引擎實例重新測試才能獲得更準確的數字。 每個執行個體將執行一個 YCSB 測試,而不是一個具有 6 個並行測試的大型 CE 實例。 這樣,就可以更輕鬆地區分 Cloud Spanner 請求延遲和 Cloud Spanner 與運行測試的 CE 執行個體之間的網路連線所增加的延遲。
Cloud Spanner 作為 OLAP 的表現如何?
分區?
將資料劃分為物理和/或邏輯上獨立的段(稱為分區)是大多數 OLAP 引擎中非常流行的概念。 分區可以顯著提高查詢效能和資料庫可維護性。 深入探討分區將是一篇單獨的文章,所以我們只提一下分區和子分區方案的重要性。 將資料分解為分區甚至進一步分解為子分區的能力是分析查詢效能的關鍵。
Cloud Spanner 本身不支援分區。 它將資料內部劃分為所謂的 分裂-s 基於主鍵範圍。 自動執行分區以平衡 Cloud Spanner 叢集中的負載。 Cloud Spanner 的一個非常有用的功能是拆分父表的基本負載(不與另一個表交錯的表)。 Spanner自動偵測是否包含 分裂 比其他數據更頻繁讀取的數據 分裂-啊,可能會決定進一步分離。 這樣就可以讓更多的節點參與到一個請求中,這也有效地提高了吞吐量。
載入資料中?
批量資料的 Cloud Spanner 方法與正常載入相同。 為了實現最佳效能,您需要遵循一些準則,包括:
- 按主鍵對資料進行排序。
- 將它們除以 10*節點數 單獨的部分。
- 建立一組並行載入資料的工作任務。
此資料載入使用所有 Cloud Spanner 節點。
我們使用 YCSB 工作負載 A 產生 10M 行的資料集。
* 負載測試在 n1-standard-32 計算引擎(32 vCPU、120 GB 記憶體)上運行,測試實例從來都不是測試的瓶頸。
**不建議對任何生產工作負載使用單節點設定。
如上所述,Cloud Spanner 根據負載自動處理拆分,因此在連續幾次重複測試後結果會有所改善。 這裡給出的結果是我們得到的最佳結果。 查看上面的數字,我們可以看到 Cloud Spanner 如何隨著叢集中節點數量的增加而擴展。 最引人注目的數字是極低的平均延遲,這與上一節所述的混合工作負載(95% 讀取和 5% 寫入)的結果形成對比。
縮放?
增加和減少 Cloud Spanner 節點數量是一項一鍵式任務。 如果您想要快速載入數據,您可以考慮將執行個體提升到最大值(在我們的範例中,美國東部地區有 25 個節點),然後在所有資料都載入完畢後,減少符合正常載入條件的節點數量資料庫,指2TB/節點限制。
即使資料庫小得多,我們也會注意到這個限制。 經過幾次運行負載測試後,我們的資料庫大小約為 155 GB,當縮小到 1 節點實例時,我們收到以下錯誤:
我們設法將實例從 25 個縮減到 2 個,但我們陷入了兩個節點。
可以使用 REST API 自動增加和減少 Cloud Spanner 叢集中的節點數量。 這對於減少繁忙工作時間增加的系統負載特別有用。
OLAP 查詢的效能?
我們原本計劃在這部分花費大量時間來評估 Spanner。 經過幾次 SELECT COUNT 後,我們立即意識到測試時間會很短,而且 Spanner 不適合 OLAP。 無論叢集中有多少節點,僅選擇 10M 行表中的行數就需要 55 到 60 秒。 此外,任何需要更多記憶體來儲存中間結果的查詢都會失敗並出現 OOM 錯誤。
SELECT COUNT(DISTINCT(field0)) FROM usertable; — (10M distinct values)-> SpoolingHashAggregateIterator ran out of memory during new row.
TPC-H 查詢的一些數字可以在 Todd Lipcon 的文章中找到
4. 我們的結論
鑑於 Cloud Spanner 功能的當前狀態,很難想像它會成為您現有 OLTP 解決方案的簡單替代品,尤其是當您的需求超出它的範圍時。 必須花費大量時間圍繞 Cloud Spanner 的缺點來建立解決方案。
當我們開始評估 Cloud Spanner 時,我們預期其管理功能與其他 Google SQL 解決方案相當,或至少相去不遠。 但我們對完全缺乏備份以及對資源存取的控制非常有限感到驚訝。 更不用說沒有視圖、沒有本地開發環境、不支援的序列、不支援 DML 和 DDL 的 JDBC 等等。
那麼需要擴展事務資料庫的人該去哪裡呢? 市場上似乎沒有一個適合所有用例的解決方案。 有許多封閉和開源解決方案(本文中提到了其中一些),每個解決方案都有自己的優點和缺點,但沒有一個提供具有 99,999% SLA 和高一致性的 SaaS。 如果高 SLA 是您的主要目標,而您不傾向於建立自訂多雲解決方案,那麼 Cloud Spanner 可能是您正在尋找的解決方案。 但您應該意識到它的所有限制。
公平地說,Cloud Spanner 在 2017 年春季才向公眾發布,因此可以合理地預期它當前的一些缺陷最終可能會消失(希望如此),而當它們消失時,它可能會改變遊戲規則。 畢竟,Cloud Spanner 不僅僅是 Google 的副業項目。 谷歌使用它作為其他谷歌產品的基礎。 當 Google 最近用 Cloud Spanner 取代 Google Cloud Storage 中的 Megastore 時,它使得 Google Cloud Storage 在全球範圍內的物件清單變得高度一致(但對於
所以,仍然有希望……我們希望。
就這樣。 和文章作者一樣,我們也繼續希望,但是你對此怎麼看呢? 寫在評論裡
我們邀請大家參觀我們的
來源: www.habr.com