轉載於:https://www.zhihu.com/question/30934556
目前,服務器的磁盤和內存,cpu都相對較好,一台數據庫服務器可以存儲好幾億條的數據,在一個什么樣的情況下,應該考慮分布式數據庫的,百億?千億?
分別回答下,題主的三個問題:
1. 目前,服務器的磁盤和內存,cpu都相對較好,一台數據庫服務器可以存儲好幾億條的數據,在一個什么樣的情況下,應該考慮分布式數據庫的,百億?千億?
考慮用分布式數據庫,肯定是容量或者性能方面,現有的單機數據庫滿足不了業務的需求。當然,遇到了容量或者性能的問題,也不一定要用分布式數據庫,可以通過scale-up的方式,即升級數據庫服務器的CPU、內存、磁盤,將SATA/SAS盤換SSD盤等方式解決。不過相對scale-up來說, 分布式數據庫這種scale-out的方式,擴展性會更強一些,一般來說也更具性價比。
普通的X86服務器,一台數據庫服務器存好幾億條數據,問題不大,但前提是需要分庫或分表,單表幾億條數據,普通服務器基本支撐不了的,畢竟數據量一大,表對應的B樹層次就高,寫入時B樹節點的分裂和調整,開銷也大。同時,上億規模下,單台數據庫服務器的恐怕不能支持密集的讀請求,性能可能會有問題。
2. “如果單機數據庫,直接通過分布式數據庫來訪問,分布式數據庫是否能夠提高數據庫的效率呢?”
題主這里所說的分布式數據庫, 應該是指數據庫中間件這樣的軟件吧。目前比較流行的一種做法,是DBA利用開源中間件,結合自己項目的mysql或pg數據庫,來搭建出一套分布式數據庫的解決方案。主要的方法有兩種:
一種是水平拆分。當數據量大到單機數據庫已存儲不下時, 可以對數據進行拆分,化整為零,將數據均勻分布到多個數據庫節點中。由於對數據進行了拆分,每個數據庫節點上的數據量小了,自然讀寫性能就提高了。
另一種是讀寫分離。這種方法,主要用在數據量並不大,單機數據庫能夠hold得住,但讀請求很高的情況下。此時,可以配置多個只讀數據庫節點,來分擔主節點的讀請求。通過數據復制機制,在主節點和只讀節點之間進行數據的實時同步,保證主從節點的數據一致性。
兩種方法很好地解決了數據庫的容量和性能問題。當然,使用了中間件,相當於在sql的執行路徑上,多了一個處理環節,因此單條sql的延時,相對於直連數據庫節點,在非滿負載的情況下,肯定是要高的。但在實際的業務訪問中,sql的性能瓶頸,一般都出在數據庫節點上,中間件只是做單純的sql解析和路由,性能開銷不會很大。因此,通過增加數據庫節點,提升sql處理的短板,是能夠提高系統效率的。
3.“數據庫分庫后,一些復雜的sql場景,會比較難處理,而且分庫之后,sql除了查詢分庫的數據外,還要進行數據合並操作,那是否是說不分庫,比分庫更好一些呢?”
基於中間件來進行分庫, 確實對 SQL 有閹割的情況,並不是所有sql都能夠支持。主要原因是數據被拆分了。而數據一旦被拆分到多個節點,則:
1.復雜的join查詢
2. 同時更新多個數據庫節點的sql語句
這兩類SQL的支持難度,就比較高。這也是目前市面上所有中間件都無法滿足的兩點。復雜的join查詢之所以難以支持,是因為要跨節點join;同時更新多個節點的sql難以支持,是因為很難解決多個節點的並發一致性問題。但是除了這兩點之外,其他的sql類型,一款中間件是能夠努力做到的。
從中間件實現的角度,我們來對sql做一個分析,以說明這一點。
1. 按操作范圍的維度,可以把所有的SQL,分為3類:
1.1 kv類的sql: 這種sql操作很簡單,就是簡單的set/put某個表的一條記錄,大部分insert/delete/update語句,和指定primary key/key的select,都屬於這種類型。
1.2 范圍更新/查詢:這種sql不局限於操作一條記錄,但還是作用於一張表。比如update多行記錄,或者select某個時間范圍的記錄等。
1.3 多表join查詢:又包括兩種:
1.3.1 分庫分表鍵都是同一個的多表join:由於采用同一個划分鍵,因此join操作其實是發生在單節點
1.3.2 分庫分表鍵不是同一個的多表join: 此時涉及到跨節點的join,實現復雜
2.按是否要在關系運算之后,還要對結果進行聚合,把select sql分為兩類:
2.1 不需要進行結果聚合,即select sql中沒有集函數、group by、order by、limit等需要在關系運算之后,再對結果進行處理和聚合;
2.2 包括上述結果聚合語法的select sql
3.從是否對分布式事務有要求的角度,可以把SQL分為兩類:
3.1 只讀寫一個節點的sql,無分布式事務要求
3.2 跨多個節點讀寫的sql,有分布式事務要求
根據之前所述, 目前的業內的中間件,都不能支持1.3.2 和3.2(mycat對分布式事務的支持,只支持最終一致性,還是一個偽支持;阿里DRDS號稱內測版本支持分布式事務,但一直未見公測),而除去這兩點,對於類型(1.1, 1.2, 1.3.1) × (2.1,2.2)得到的6種sql類型,理論上講,中間件都是可以做到支持的。
對於OLTP應用來講,這6種類型能夠覆蓋絕大部分的業務場景,這也是中間件技術這幾年這么流行的原因。遺憾的是,目前業內的各大中間件, 對這6種類型的sql,支持程度往往都有一定的折扣。比如對於這樣一條操作單表的sql:
select distinct id, avg(price) from t1 where id>=1 group by concat(id,name) order by avg(price) limit 10;
目前主流的幾款中間件,似乎就不能支持。
目前,UCloud 的 UDB 團隊,也在打造一款基於中間件和 UDB 的,分布式數據庫產品 UDDB,協議和SQL語法,全面兼容MYSQL。我們從零開始,但目標遠大。正如 UCloud 一直強調的,用戶的需求是我們下一款產品。我們的第一個目標,是做一款業內最好用的分布式數據庫,解決用戶在使用mysql中間件構建分布式解決方案時的痛點:學習成本高,配置復雜,運維麻煩,擴容不方便。
在系統管理上,UDDB將做到一步創建,開箱即用,無需額外的管理和配置操作,並提供全自動化,無需停服的水平擴展/縮容操作;SQL支持上,我們將對類型(1.1, 1.2, 1.3.1) × (2.1,2.2)這6種sql,進行全面的支持,讓用戶在遇到帶avg集函數、group by,order dy的select sql時, 無需擔憂系統是否支持,即可放心使用。
預計在今年9月底,UDDB將開放內測,敬請大家關注。
長期來看,打造這樣一款分布式數據庫服務,是我們和客戶交流,探索未來的一種方式。誠然,相對於 Google F1,Oceanbase 等全新設計的分布式數據庫產品, 基於中間件的分布式數據庫,在技術上並非最前沿,但是我們相信,這是廣大客戶目前正需要的。我們相信只有先服務好用戶,深入到用戶的需求當中,根據用戶需求不斷迭代,同時團隊自身不斷成長,才能真正理解公有雲環境下,用戶對分布式數據庫的需求,才能做出接地氣和廣受歡迎的產品。