Oracle專家談MySQL Cluster如何支持200M的QPS
Andrew Morgan 是Oracle MySQL首席產品經理。 近日,他 撰文 介紹了MySQL Cluster如何支持200M的QPS。
MySQL Cluster簡介
MySQL Cluster 是一個實時可擴展且符合ACID的事務型內存數據庫。該數據庫有高達99.999%的可用性和低廉的開源軟件總擁有成本。在設計方面,它采用了一種分布 式、多主節點的架構,消除了單點故障,能夠在商用硬件上橫向擴展,并借助“自動分片(auto-sharding)”功能為通過SQL和NoSQL接口訪 問數據的讀/寫密集型工作負載提供服務。
最初,MySQL Cluster被設計成一個嵌入式的電信數據庫,用于網內應用程序,需要具備運營商級的可用性和實時性能。之后,其功能隨著新功能集的增加迅速增強,其應 用領域隨之也擴展到了本地或云上的Web、移動和企業應用程序,包括:大規模OLTP、實時分析、電子商務(庫存管理、購物車、支付處理、訂單追蹤)、在 線游戲、金融交易(欺詐檢測)、移動與微支付、會話管理&緩存、流式推送、分析及推薦、內容管理與交付、通信與在線感知服務、訂閱者/用戶信息管 理與權益等。
MySQL Cluster體系結構
在MySQL Cluster內部,總共有三種類型的節點為應用程序提供服務。下面是一張MySQL Cluster體系結構簡圖,其中包含6個節點組,共12個“數據節點(Data Node)”:
數據節點是MySQL Cluster的主要節點。它們提供如下功能:內存內及基于磁盤的數據存儲與管理、表的自動“分片(sharding)”及按用戶定義分區、數據節點間數據同步復制、事務與數據檢索、自動故障恢復、自我修復(故障解決后自動重新同步)。
表會自動跨數據節點分區,每個數據節點都是一個可以接受寫操作的主節點。這使得寫密集型工作負載很容易在節點之間分配,而且對于應用程序而言,這個過程是透明的。
MySQL Cluster采用了一種無資源共享的體系結構(比如不使用共享磁盤)存儲和分發數據,并同步生成至少一個數據副本,如果某個數據節點出現故障,則總是有 另一個數據節點存儲了同樣的信息, 使得請求和事務可以繼續而不被中斷。任何在數據節點故障期間短暫中斷(亞秒級)的事務都可以回滾并重新執行。
MySQL Cluster允許用戶選擇如何存儲數據:全部在內存中或者部分在磁盤上(僅限于未索引數據)。內存內存儲對于經常變化的數據(活動工作集)而言尤其有 用。存儲在內存中的數據會定期地(本地檢查點)寫入本地磁盤,并在所有數據節點之間協調,這樣,MySQL Cluster可以從系統完全失效(比如停電)的情況下恢復過來。基于磁盤的存儲可以用于存儲性能要求不那么嚴格的數據,其數據集大于可用內存。與其它大 多數數據庫服務器一樣,為了提高性能,MySQL Cluster使用頁緩存將經常使用的、基于磁盤存儲的數據緩存在數據節點的內存中。
應用節點提供從應用邏輯到數據節點的連接。應用程序可以使用SQL訪問數據庫,通過一臺或多個MySQL服務器對存儲在MySQL Cluster中的數據執行SQL接口的功能。當訪問MySQL服務器時,可以使用任何一種標準的 MySQL連接器 ,這使用戶有許多種訪問技術可選擇。NDB API是其中一個可選的方案。這是一個基于C++的高性能接口,可以提供額外控制、更好的實時行為及更高的吞吐能力。NDB API還提供了一個層,使NoSQL接口可以繞過SQL層直接訪問MySQL Cluster,降低了延遲,提高了開發靈活性。現有接口包括Java、JPA、Memcached、JavaScript與Node.js、 HTTP/REST(借助Apache Module)。所有應用節點都可以訪問所有數據節點的數據,所以,它們即使出現故障也不會導致服務中斷,因為應用程序只要使用剩下的節點就可以了。
管理節點負責向MySQL Cluster中的所有節點發布集群配置信息以及節點管理。管理節點在啟動、向集群加入節點及系統重新配置時使用。管理節點關閉和重啟不會影響數據節點和應用節點的運行。在默認情況下,在遇到導致“集群分裂(split-brain)”或 網絡分區 的網絡故障時,管理節點還提供仲裁服務。
通過透明分片實現可擴展性
任何表的行都可以透明地分成多個分區/片段。對于每一個片段,都會有一個單獨的數據節點保存它所有的數據,并處理所有針對那些數據的讀寫操作。每 個數據節點還有一個伙伴節點,它們共同組成了一個節點組;伙伴節點存儲了那個片段的第二個副本以及一個它自己原有的片段。MySQL Cluster使用同步兩段提交協議確保事務提交的變化同時存儲到兩個數據節點。
MySQL Cluster默認使用表的主鍵作為“分片鍵(shard key)”,并對分片鍵執行MD5散列,從而選擇數據應該存儲的片段/分區。如果一個事務或查詢需要訪問多個數據節點的數據,那么其中一個數據節點將承擔 事務協調器的角色,并將工作委派給其它所需的數據節點;結果會在提供給應用程序前合并。需要注意的是,事務或查詢可以連接來自多個分片和多個表的數據,這 與傳統的、實現了分片機制的NoSQL數據存儲相比是一個巨大的優勢。
當單個節點就可以滿足高強度查詢/事務的數據操作需求時,就實現了最理想的(線性)擴展(因為這減少了數據節點間消息傳遞的網絡延遲)。要做到這 一點,應用程序應該清楚地知道數據分布——這實際上就是說定義模式的人可以指定用作分片鍵的列。比如,上圖中的表使用了由user-id和服務名組合而成 的主鍵;如果只使用user-id作為分片鍵,那么表中特定用戶的所有行將會總是存儲在同一個片段中。更為強大之處在于,如果其它表中也使用了同樣的 user-id列,并將其設定為分片鍵,那么所有表中特定用戶的數據都會存儲在同一個片段中,那個用戶的查詢/事務就可以由單個數據節點處理。
利用NoSQL API最大限度地提高數據訪問速度
MySQL Cluster提供了許多種數據訪問方式;最常用的方法是SQL,但從下圖可以看出,還有許多原生API可供應用程序從數據庫直接讀/寫數據,避免了向 SQL轉換并傳遞給MySQL服務器的低效和開發復雜度。目前,MySQL Cluster提供了面向C++、Java、JPA、JavaScript/Node.js、HTTP及Memcached協議的API。
基準測試:每秒2億次查詢
根據設計,MySQL Cluster用于處理以下兩種工作負載:
- OLTP(在線事務處理) :內存優化型表可以提供次毫秒級的低延遲以及極高水平的OLTP工作負載并發能力,并且仍然可以提供良好的穩定性;此外,它們也能夠用于基于磁盤存儲的表。
- 即時搜索 :MySQL Cluster提高了執行表掃描時可以使用的并發數,極大地提高了未索引列的搜索速度。
話雖如此,MySQL Cluster旨在處理OLTP工作負載方面達到最佳,特別是在以并發方式發送大量查詢/事務請求的情況下。為此,他們使用 flexAsynch 基準測試,測量更多數據節點加入集群后NoSQL訪問性能的提升。
在該基準測試中,每個數據節點運行在一個專用的56線程Intel E5-2697 v3(Haswell)機器上。上圖顯示了在數據節點從2增加到32(注意:MySQL Cluster目前最多支持48個數據節點)的過程中吞吐量的變化。從中可以看出,吞吐量呈線性增長,在32個數據節點時,達到了 每秒2億次NoSQL查詢 。
讀者可以登錄 MySQL Cluster基準測試頁面 ,查看關于這次測試的最新結果及更詳細的描述。
每秒2億次查詢的基準測試是在MySQL Cluster 7.4(最新的正式版本)上得出的,關于該版本的更多信息請查看 這里 。