1. 程式人生 > 其它 >百度BaikalDB在同程藝龍的成功應用實踐剖析

百度BaikalDB在同程藝龍的成功應用實踐剖析

導讀:文章主要介紹 BaikalDB在同程藝龍的完整落地實踐,文章把BaikalDB總結為六個核心特性,分別是《BaikalDB高可用與HTAP特性實踐》、《BaikalDB 高效能與擴充套件性實踐》、《BaikalDB 低成本的思考》,希望對大家有幫助。

全文14032字,預計閱讀時間 19分鐘。

一、BaikalDB高可用與HTAP特性實踐

我們從2019年開始調研開源NewSQL資料庫BaikalDB,嘗試解決工作中遇到的一些實際問題,例如OLAP業務跑在行存資料庫上查詢速度慢,資料庫跨中心部署高可用方案待完善,在近6個月的研究與實踐中,我們向社群提交了列存特性,並使用BaikalDB分別部署了基於列存的OLAP類業務,基於行存的OLTP類業務,及基於雙中心的高可用部署方案,有效的解決了相關問題,在這裡做一個相關使用經驗的分享,希望可以給遇到類似問題的同學提供參考。

1、BaikalDB選型考慮

1.1業界紛紛佈局NewSQL

1.2 NewSQL資料庫核心技術對比

  • 注1:ShardingSphere基於MySQL MGR的Paxos複製協議尚未釋出。

  • 注2:TiDB 3.0起已同時支援樂觀事務與悲觀事務。

  • 注3:由於筆者精力所限,尚有很多NewSQL未參與對比:Amazon Aurora,Aliyun PolarDB, AnalyticDB,Apple FoundationDB, CockroachDB, 華為GaussDB, Yandex ClickHouse等。

1.3 NewSQL技術選型

路徑選擇:

  • 純自研:能力有限,投入有限

  • 純開源:無法及時滿足定製化需求

  • 雲服務:安全與成本考慮,短期核心心業務自建IDC,k8s化

  • 半自研:我們的選擇,不重複造輪子,主體功能交由社群完成,集中有限力量滿足公司需求,可供選擇的NewSQL有:TiDB,BaikalDB,CockRoachDB等。

從以上幾款開源DB中,最終選擇BaikalDB的原因有:

  • 背景相似:BaikalDB來源於百度鳳巢廣告業務團隊,由於廣告業務的增長走過了從單機到分庫分表到分散式的全過程,而我們面臨類似的問題。

  • 經受考驗:已經有百度廣告平臺多個業務實際使用經驗,千級別叢集節點,PB級資料規模,我們跟進使用,風險可控。

  • 技術棧匹配:BaikalDB(c++實現, 10萬行程式碼精煉),依賴少而精(brpc,braft,rocksdb),社群友好,部署簡單,技術棧匹配。

  • 特性比較完善:基本滿足我們需求,我們可以專注於滿足公司需求。

1.4 BaikalDB簡介

BaikalDB是一款百度開源(github.com/baidu/BaikalDB )分散式關係型HTAP資料庫。支援PB級結構化資料的隨機實時讀寫。

架構如下:

其中:

  • BaikalStore 負責資料儲存,用 region 組織,三個 Store 的 三個region形成一個 Raft group 實現三副本,多例項部署,Store例項宕機可以自動遷移 Region資料。

  • BaikalMeta 負責元資訊管理,包括分割槽,容量,許可權,均衡等,Raft保障的3副本部署,Meta 宕機隻影響資料無法擴容遷移,不影響資料讀寫。

  • BaikalDB 負責前端SQL解析,查詢計劃生成執行,無狀態全同構多例項部署,宕機例項數不超過 qps 承載極限即可。

核心特性:

  • 強一致:實現Read Committed 級別的分散式事務,保證資料庫的ACID 特性

  • 高可用:Multi Raft協議保證資料多副本一致性,少數節點故障自愈, 支援跨機房部署,異地多活,可用性>99.99%, RTO=0, RPO<30s

  • 高擴充套件:Share-nothing架構,儲存與計算分離, 線上縮擴容不停服 5分鐘內完成,動態變更schema 30s生效

  • 高效能:表1000張,單表:10億行,1千列情況下:QPS >1W 點查 P95 < 100ms

  • 易用性:相容MySQL 5.6協議

2、BaikalDB線上遷移過程

我們在線上已部署了50個儲存節點百億行資料規模的BaikalDB叢集,本章將重點講述業務遷移到BaikalDB的步驟以確保上線過程平穩與業務無縫遷移。整體的上線過程可分為如下幾個階段:

2.1 列存特性開發

由於我們上線的首個業務是分析類業務,適合列式儲存,在社群的幫助與指導下,我們開發並提交了列存特性,原理見列式儲存引擎

2.2 配套運維工具

  • 部署工具:線上暫以自研部署指令碼為主,未來會對接公司k8s;

  • 監控工具:Prometheus,BaikalDB對接Prometheus非常簡單,參見監控指標匯出到Prometheus

  • 資料同步工具:Canal + 資料同步平臺,原理類似不再展開;

  • 物理備份工具:SSTBackup,使用說明見基於SST的備份與恢復,可以實現全量+增量的物理備份,內部資料格式,僅適用於BaikalDB;

  • 邏輯備份工具:BaikalDumper,模擬MySQLDumper,匯出的是SQL語句,可以匯入到其他資料庫,目前只支援全量匯出;

  • 測試工具:Sysbench 使用說明見BaikalDB Sysbench

  • 欠缺的工具:基於MySQL binlog的資料訂閱工具,開發中。

2.3 資料遷移

資料同步採用全量+增量同步方式,全量採用批量插入,增量原理類似於MySQL binlog訂閱,採用Replace模式同步。共計80億條資料全量同步約3天,增量同步穩定在10ms以內。

2.4 業務測試

經過資料同步環節,BaikalDB已經具備與線上等價資料集,業務測試階段重點在於對待上線系統真實SQL的支援能力,我們採用全流量回放的方式進行。

如下圖:

通過實時回放線上真實流量我們主要驗證了:

  • 業務使用SQL的100%相容性

  • 業務峰值的效能承載能力

  • 7*24小時的穩定性

2.5 業務上線

經過以上環節,業務上線需要的唯一操作就是更改資料庫連線配置。

2.6 運維與監控

下圖是上線後部分指標Prometheus監控截圖,可以看到從qps,響應時間,環比變化看均十分平穩。

2.7 注意事項

BaikalDB尚在完善的功能:

  • 子查詢:開發中

  • information_schema:圖形化工具支援與系統變數支援不全,開發中

  • 行列並存:一張表可選擇行存或列存,但不能並存,開發中

  • 分散式時鐘:影響事務隔離級別,與Follower一致性讀,開發中

  • 檢視:排期中

  • 觸發器,儲存過程等傳統關係型資料庫功能,暫無規劃

使用BaikalDB需要注意的事項:

  • 資料建模:DB並不能取代資料庫使用者的角色,好的資料模型,表結構的設計,主鍵與索引的使用,SQL語句,在我們實際測試中比壞的用法會有10倍以上的提升;

  • 寫放大:與RocksDB層數有關,建議單store資料大小控制在1T以內;

  • 引數調優:預設配置已非常合理,僅有少量引數建議根據實際情況修改:

export TCMALLOC_SAMPLE_PARAMETER=524288 #512kexport TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=209715200 #200M,當大value時,調大可以避免執行緒競爭,提高效能-bthread_concurrency=200 # 建議(cpu核數- 4)* 10-low_query_timeout_s=60 # 慢查詢閾值,建議根據需求設定-peer_balance_by_ip=false # 預設為false,單機多例項時建議開啟-max_background_jobs = 24 #建議(cpu核數- 4)-cache_size = 64M #建議不超過單例項記憶體空間40%
  • 大事務限制:行鎖限制:per_txn_max_num_locks 預設100w;DB與Store RPC 包的大小限制:max_body_size預設256M;訊息體限制:max protobuf size =2G,此為protobuf限制不可修改。一般建議事務影響行數不超過10M;

  • 雙機房資源預留Buffer:資源使用率建議40%左右,容災時單機房需要承載double的壓力,分配副本時disk_used_percent 超過80%的store將被剔除。

3、高可用與HTAP部署方案

我們的BaikalDB一套叢集部署在兩個城市4個IDC機房,同時支撐基於行存的OLTP業務與基於列存的OLAP業務,本章將說明我們是如何通過設計部署方案來發揮BaikalDB高可用與HTAP能力的。

雙中心HTAP部署示意圖:

  • 注1:圖中省去了meta節點部署

  • 注2:每個IDC會實際部署了多個store與db節點。

如上圖城市 A與城市 B雙中心採用完全對稱的部署結構,在BaikalDB裡Region是儲存的基本單位,每張表至少有一個Region組成,每個Region有若干個peer合在一起構成了一組Raft Group。每個store即可建立行存表也可以建立列存表,業務建表時可以根據場景的不同進行選擇,另外業務也可以根據地域的不同選擇副本的分佈,例如城市 A的業務可以選擇城市 A 2副本+城市 B 1副本,城市 B的業務可以選擇城市 A 1副本+城市 B 2副本。

假設有2家業務在使用BaikalDB叢集,業務A是一個部署在城市 A的OLAP類業務建立了表ctable用Region1代表。業務B是一個部署在城市 B的OLTP類業務建立了表rtable用Region2代表。則相關的配置過程如下:

  1. 初始化meta機房資訊
echo -e "場景:新增邏輯機房bj sz\n"curl -d '{"op_type": "OP_ADD_LOGICAL","logical_rooms": {"logical_rooms" : ["bj", "sz"]}}' http://$1/MetaService/meta_managerecho -e "插入bj物理機房\n"curl -d '{"op_type": "OP_ADD_PHYSICAL","physical_rooms": {"logical_room" : "bj","physical_rooms" : ["bj1","bj2"]}}' http://$1/MetaService/meta_managerecho -e "\n"echo -e "插入sz物理機房\n"curl -d '{"op_type": "OP_ADD_PHYSICAL","physical_rooms": {"logical_room" : "sz","physical_rooms" : ["sz1","sz2"]}}' http://$1/MetaService/meta_manager
  1. 設定每個baikalstore的物理機房資訊
#IDC1 store的機房資訊配置#vim store/conf/gflag-default_physical_room=bj1
  1. 設定每個baikaldb的物理機房資訊
#IDC1 db的機房資訊配置#vim db/conf/gflag-default_physical_room=bj1
  1. 建立表時根據需要指定副本策略與儲存型別
--業務A是一家部署在城市 A的OLAP型別請求採用列存表,建表語句如下:CREATE TABLE `TestDB`.`ctable` (`N_NATIONKEY` INTEGER NOT NULL,`N_NAME` CHAR(25) NOT NULL,`N_REGIONKEY` INTEGER NOT NULL,`N_COMMENT` VARCHAR(152),PRIMARY KEY (`N_NATIONKEY`))ENGINE=Rocksdb_cstore COMMENT='{"comment":"這是一張列存表", "resource_tag":"bizA", "namespace":"TEST_NAMESPACE","dists": [ {"logical_room":"bj", "count":2}, {"logical_room":"sz", "count":1}] }';--業務B是一家部署在城市 B的OLTP型別請求採用行存表,建表語句如下:CREATE TABLE `TestDB`.`rtable` (`N_NATIONKEY` INTEGER NOT NULL,`N_NAME` CHAR(25) NOT NULL,`N_REGIONKEY` INTEGER NOT NULL,`N_COMMENT` VARCHAR(152),PRIMARY KEY (`N_NATIONKEY`))ENGINE=Rocksdb COMMENT='{"comment":"這是一張行存表", "resource_tag":"bizB", "namespace":"TEST_NAMESPACE","dists": [ {"logical_room":"bj", "count":1}, {"logical_room":"sz", "count":2}] }';

優點:

  • 容災能力:任何少數節點故障,無論是機器級,機房級還是城市級故障,均可做到RPO(資料丟失時長) = 0s,RTO(資料恢復時長)< 30s。

  • Async Write:由於Raft多數Peer寫成功即可返回,雖然3peer會有1個peer分佈在另一個城市存在延遲,但寫操作一般寫完同城的2個peer即可,異地的peer在進行非同步寫,寫效能接近同城寫效能。

  • Follower Read:由於每個城市至少有一個副本,對於讀業務需要分別部署在兩個城市的場景,BaikalDB提供了就近讀功能,路由選擇時會優先選擇與DB同在一個邏輯機房的Region進行讀操作,所以讀效能可以在兩地均得到保證。

  • HTAP能力:業務可以根據業務場景分別選擇行存表與列存表,每個store可以同時支援這兩種表。

  • 資源隔離:如果擔心HTAP的業務workload會互相影響,業務可以通過resource_tag欄位對store進行分組,例如store1的resource_tag = bizA, 那麼store1只會給建表時指定resource_tag = bizA的表分配Region。

待完善:

  • 容災能力:多數節點故障RPO最大可到3s,BaikalDB副本的分配策略後續可以增加降級策略,如果多數機房故障,降級到在少數機房分配副本,從而保證RPO依舊為0。

  • Async Write:當寫發生在少數城市時依舊會存在延遲,但這種情況實際業務很少發生;如確有需要例如兩地業務均需對同一張表發生寫操作,必然有一個處於異地寫狀態,這種情況建議寫時拆成兩張表,讀時用Union或檢視。

  • Follower Read:可以增強為Follower一致性讀。就是對Follower可能落後與Leader的請求進行補償,需要分散式時鐘特性(開發中)的支援。

二、BaikalDB 高效能和擴充套件性實踐

核心特性

這也是我們在業務推廣中的關注次序,即

  • 首先必須(Must to)業務場景匹配精準(1一致性)和執行平穩(2高可用)

  • 其次最好(Had better)是資料多(3擴充套件性)與跑的快(4高效能)

  • 最後應該是(Should)使用友好(5高相容性)與 成本節省(6低成本)

簡稱:穩準多快好省。

本文將會通過介紹業務落地前的兩個實際測試案例,來分享總結BaikalDB在效能與擴充套件性方面的資料。

1、基於行存OLTP場景的基準測試

1.1測試目標

如果把BaikalDB看成一款產品,基準測試的目的就是加上一份產品規格說明書,在效能測試同學的參與下,我們進行了為期2個月的基準測試,並給BaikalDB這款產品的外包裝上寫下如下關於規格的資訊:

  • 設計的叢集最大規模,在1000個節點情況下,能支援18種資料型別,單節點1T資料容量,叢集整體1P容量。

  • 在基準資料測試下,叢集單點效能達到,write不低於2000QPS,單次write不超過50 ms, read效能達到不低於4000QPS,單次read不超過20 ms。

  • 對外介面基本相容MySQL 5.6版本協議。

  • 基於Multi Raft 協議保障資料副本一致性,少數節點故障不影響正常使用。

  • Share-Nothing架構,儲存與計算分離,線上縮擴容對效能影響僅限於內部的資料自動均衡,而對外部透明,新增欄位30s生效對叢集無影響。

1.2測試範圍

  • 效能測試(行式儲存,大表104欄位,小表63欄位,叢集總基礎資料1TB,2TB,3TB)

  • 與mysql基準對比測試

  • 表結構欄位個數影響(大表104欄位,小表63欄位)

  • 叢集總基礎資料大小影響(1TB,2TB,3TB)

  • 表結構影響("自增主鍵","片鍵做全域性索引","片鍵做主鍵")

  • 帶壓力的擴充套件性測試

  • 加節點(store)

  • 減節點(store)

  • 動態加列

1.3測試環境

五臺機器混合部署3 meta, 5 db, 5 store獲取基準,另有一臺機器作為增減節點機動(centos 7.4 32核 2.4GHZ,128G記憶體 1.5TSSD硬碟)

測試部署

1.4主要指標說明

  • 最佳容量(KTPS):

  • 5臺機器配置的叢集(3 meta, 5 db, 5 store)

  • 連續兩分鐘可以穩定支撐的最大吞吐能力

  • 平均讀響應時間小於20ms,平均寫響應時間小於50ms

  • 系統最大吞吐能力: 每秒dml操作請求數

  • 單位為KTPS(千次操作請求/秒)

  • 定義

  • 前置條件:

  • 響應時間:dml操作從傳送到收到返回結果所經過的時間,單位為毫秒

  • diskIOUtil 磁碟使用率: 一秒中有百分之多少的時間用於 I/O 操作,或者說一秒中有多少時間 I/O 佇列是非空的

  • 如果接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁碟可能存在瓶頸。

  • 大於30%說明I/O壓力就較大了,讀寫會有較多的wait

  • 最佳容量判定方法

繪製系統的效能指標隨著併發使用者數增加而出現下降趨勢的曲線,分析並識別效能區間和拐點並確定性能閾值。

1.5測試結論

  • 效能測試

  • 讀:片鍵做主鍵模式,5節點讀容量為72K+TPS,效能比mysql高85%+,瓶頸為CPU

  • 寫:片鍵做主鍵模式,5節點寫效能為9.6K+TPS,與mysql相當,為mysql的85%~120%之間,瓶頸為DiskIO

  • 擴充套件性測試

  • 加節點:前端吞吐平穩

  • 減節點:減節點操作需要確保叢集能力有足夠的餘量,能承載被減掉節點轉移的壓力

  • 加列:22秒新列生效(1.25億基礎資料)

1.6效能測試詳情

與mysql基準對比測試:

表結構欄位個數影響:

叢集總基礎資料大小的影響:

表結構影響:

擴充套件性測試詳情

不停服增減節點:

不停服增加列:

不停服加列測試過程曲線圖(22秒後所有的帶新列的insert語句全部成功,紅色曲線代表失敗數降為0)

2、基於列存OLAP場景測試

2.1測試背景

指標監控系統用於實時(定時)監控線上某實時業務資料,生成關於健康狀態的相關指標,如果指標超出閾值,則觸發報警功能。資料表約50列20億行,查詢sql10餘種均為聚合類查詢,檢索列數不超過4列,查詢條件為一定時間區間的範圍查詢,之前是跑在一款行存的分散式資料庫之上,這是一個典型的olap類場景,我們採用baikaldb的列存模式與線上進行了對比測試,測試物件均為線上真實資料,兩款DB叢集配置相當,測試查詢效能的同時,均承擔等同的寫負載。

2.2測試結果:

從測試結果可以看出,在寬表少列與聚合查詢的sql查詢,使用baikaldb的列式儲存,可以有效減少磁碟IO,提高掃表及計算速度,進而提高查詢效能,這類查詢也是olap場景sql的常見寫法。

3、效能與擴充套件性總結與思考

3.1效能分析的幾個角度

  • 資源瓶頸視角

  • 查詢及事務大小建議控制在10M以內,資料量過大會觸發事務及RPC包大小限制;

  • 若需全量匯出,用/*{"full_export":true}*/ select * from tb where id > x limit 1000;語法。

  • io.util滿可導致rocksdb的L0層檔案壓縮不過來,出現快速的空間放大,進而導致磁碟快速被寫滿。相關引數:max_background_jobs=24

  • rocksdb資料檔案不建議超過1T,按照預設配置,超過1T後rocksdb將增加1層,寫放大增大10,寫放大會導致io.util出現瓶頸。若伺服器磁碟遠大於1T,建議單機多例項部署。

  • io.util滿可導致記憶體刷盤不及時進而引起記憶體滿(store);

  • 慢查詢過多時,會導致查詢積壓於store,進而引起記憶體滿(store);相關引數db:slow_query_timeout_s=60s

  • store記憶體建議配置為所在例項的40%以上,因為記憶體直接影響cache命中率,cache miss過多的話,會增大io.util及sql用時;相關引數:cache_size=64M

  • export TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=209715200 #200M,當大value時,調大可以避免執行緒競爭,提高效能 。

  • CPU : 多發生在讀qps過大時(db,store),可監控vars/bthread_count指標

  • IO:多發生在寫qps過大時(store),可監控io.util指標,及store/rocksdb/LOG日誌。

  • Mem:

  • Disk:

  • NetWork:

3.1.1使用者視角

  • 聯合主鍵 vs 自增主鍵

  • BaikalDB是按主鍵進行分片的,主鍵的選擇影響了資料的物理分佈,好的做法是把查詢條件落在儘量少的分片上,查詢時基於字首匹配,一般建議按範圍從左到右建立聯合主鍵,例如:class表主鍵可設定為schoolid,collegeid,classid # 學校,學院,班級;

  • BaikalDB實現自增主鍵主要是為了與MySQL相容,由於全域性自增是通過meta單raft group完成,會存在rpc開銷及擴充套件性問題;另外全域性自增主鍵也容易導致資料批量插入時請求集中於最後一個Region節點,容易出現瓶頸。

  • 全域性索引 vs 區域性索引

  • 全域性索引與主表不在一起,有自己的分片規則,好處是有路由發現功能,壞處是多了與全域性索引的RPC開銷,區域性索引與主表一起,需要通過主鍵確定分片,否則需要廣播,好處是RPC開銷。

  • 小表建議用區域性索引;

  • 大表(1億以上),查詢條件帶主鍵字首,用區域性索引,否則用全域性索引。

  • 行存 vs 列存

  • 寬表少列(查詢列/總列數 小於 20%), 聚合查詢的olap請求用列存

  • 其他情況用行存

3.1.2實現視角

  • Balance:BaikalDB會週期性的進行Leader均衡與Peer均衡,負載均衡過程中若資料遷移量較大,可能是影響效能,一般發生在:

  • 增刪節點時

  • 批量匯入資料時

  • 機器故障時

  • SQL Optimizer:目前主要基於RBO,實現了部分CBO,若效能與執行計劃有關,可以使用explain,及 index hint功能調優。

3.1.3****擴充套件性考慮因素

  • 穩定性

  • meta,尤其是主meta掛了情況下,將不能提供ddl, 主auto incr 掛了情況下,將不能提供自增主鍵表的insert功能。

  • store讀正常,但瞬間一半store leader掛了情況下,寫功能需要等到所有leader遷移至健康中心為止。

  • 擴容:從實測情況看,擴容情況下比較平穩

  • 縮容:縮容較少發生,但在雙中心單中心故障的情況下,相當於縮容一半,此時穩定性還是值得注意與優化的,主要包括:

  • 極限容量:

  • 計算邏輯如下

  • 理論上Meta 20G, Store 1T磁碟情況下,預計可管理 10k個store節點, 10P大小資料。

  • 實際上百度最大的叢集管理了1000個store節點,每store 1T磁碟, 共計約1P的叢集總空間。

  1. Region元資料=0.2k, Meta20G記憶體共計可管理的 Region總數 = 20G/0.2k = 100M

  2. Region資料量 = 100M,Store 1T磁碟共可管理的 Region個數每store = 1T/100M = 10k

  3. 共計可以管理的資料量 = Region總數 * Region資料量 = 100M * 100M = 10P

  4. 共計可以管理的store個數 = Region總數 / Region個數每store = 100M/10k = 10k

  • 線性

  • 固定範圍:O(1)

  • 可以下推store全量:O(n/db併發度)

  • 不可下推store全量:O(n)

  • JOIN查詢:O(n^2)

4、後記

  • 本文的效能與擴充套件性分析資料均來源於實際專案,而非TPCC,TPCH標準化測試,但測試專案具有一定的代表性。

  • BaikalDB測試資料基於V1.0.1版,最新發布的V1.1.2版又有了較多優化:

  • 優化seek效能,實測range scan速度提高1倍;

  • rocksdb升級6.8.1,使用Partitioned Index Filters,進一步提高了記憶體使用效率;

  • 增加利用統計資訊計算代價選擇索引功能(部分);

  • 事務多語句Raft複製拆分執行,提高了Follower的併發度。

三、BaikalDB 低成本思考

這也是我們在業務推廣中的關注次序,即

1、首先必須(Must to)業務場景匹配精準(1一致性)和執行平穩(2高可用);

2、其次最好(had better)是資料多(3擴充套件性)與跑的快(4高效能);

3、最後應該是(should)使用友好(5高相容性)與 成本節省(6低成本)。

簡稱:穩準多快好省。

作為系列文章的最後一篇,是關於成本的思考,如果說強一致與高可用是使用者關心的在功能上是否滿足需求,擴充套件性與高效能是老闆關心的在規格上是否值得投入,那麼相容性與成本則是專案實施者應該關心的問題,因為它關係到專案推進難度。

如果你認可NewSQL的發展趨勢,也發現了公司的實際業務場景需求,本文將會討論在專案實施中需要克服的問題,並建議用成本的角度進行評估,這樣有助於對專案的工作量進行計算。例如如果調研發現公司的潛在目標使用者均跑在mysql資料庫上,那麼是否相容mysql協議直接決定了使用者的意願,使用者的學習成本,業務程式碼的改造成本,生態的配套成本,如果潛在使用者超過10個以上則成本將會放大10倍;如果大部分潛在業務使用的是PostgreSQL,那麼最好在選型時選擇相容pg的NewSQL。這也是本文將相容性歸類到低成本一併討論的原因。

1、成本的分類

**狹義的成本:指資料庫軟體的開發,授權,運維及硬體成本,特點是可量化,**例如:1、開發投入:24人月

2、License授權:10萬/年

3、運維投入:DBA 2人

4、硬體成本:伺服器10臺

**廣義的成本:泛指在組織實施資料庫應用工程實踐過程中,所產生費用總和,**特點是與專案管理與實施有關,包括:

1、學習開發成本

2、測試驗證成本

3、業務遷移成本

4、使用者習慣

5、運維配套工具

6、軟體成熟度

7、技術前瞻性

狹義的成本可以理解為這件事值不值得做,廣義的成本可以理解為把事情做成需要做的工作,截止到本文發表為止,BaikalDB已在公司10餘家業務上進行了落地應用,這些應用實際產生的成本與收益如何評估(狹義)?專案落地過程中需要落實哪些工作(廣義)?下面將就這兩個問題展開討論。

2、狹義的成本理論上可減低100倍

由於BaikalDB是開源的,開發成本可以忽略,部署簡單,其狹義成本主要集中在硬體成本上。結合公司的雙中心建設與Kubernetes雲原生平臺戰略,我們給出了BaikalDB兩地四中心三副本行列混存的方案,理論上有望使硬體成本降低100倍,方案如下圖:

1、注1:圖中省去了meta節點部署

2、注2:每個IDC會實際部署了多個store與db節點。

3、注3:行列混存的特性還在開發中

上圖採用了完全對稱的雙中心部署方案,每個資料中心又存在2個對等IDC機房,基於BaikalDB的邏輯機房與物理機房概念,可以完成以上部署,並提供城市級別的容災能力,通過Raft Group層面的行列混存技術實現僅需3副本即可提供HTAP的能力,配置細節已經在第一篇文章HTAP部署有所描述,本文在之前基礎上增加了行列混存(功能尚未實現)的方式,進一步合併了應用場景,減少副本個數,從而達到節約成本的目的。以上方案具體成本節約主要體現在三個方面:

2.1 HTAP帶來的成本降低為5倍

為了滿足不同的應用場景,通過同步工具,資料會被分發到ETL,ES,HBASE,kafka,TiDB等不同資料元件中去,核心業務的儲存資源存在5倍以上的放大。依據資料庫使用現狀情況,核心業務一般1套OLTP主庫+資料同步平臺+5套OLAP資料庫,採用此方案後能同時滿足以上全部場景,並且省去了異構資料來源之間資料同步延遲問題,因為異構資料來源超過了5個,合併為1個後,預計收益增大5倍。

2.2 單位資源效能帶來的成本減低為4倍

  • 行存OLTP類場景效能提升85%

BaikalDB儲存層使用RocksDB的LSM-Tree儲存,相較於innodb的B+樹,通過平衡讀,寫,空間放大使得讀寫效能更加均衡,通過out-of-place update及一定的空間放大來優化寫效能(對比innodb相當於犧牲全域性有序性及儲存空間換取寫效能),能充分發揮SSD硬碟的隨機讀優勢及利用高效快取來加速點查詢,對於範圍查則主要通過data reorganization(merge/compaction)及SSD的併發讀來優化速度。參考第二篇效能測試文章的基準效能測試結果,適用於OLTP場景的行存BaikalDB綜合性能可提升85%。

  • 列存OLAP類場景效能提升10倍

OLAP類場景下的SQL查詢語句一般是寬表少列,以聚合函式為主,資料比較適合按列存放在一起,一個例子如下:

cstore vs rstore

Demo

#統計每個廣告平臺的記錄數量SELECTCounterID,count()FROMhitsGROUPBYCounterIDORDERBYcount()DESCLIMIT20;

行式

列式

使用BaikalDB的列存引擎,使我們第一家接入OLAP業務(約100億資料量的聚合查詢)查詢速度提升10倍。

業務一般會有1個OLTP場景加n個OLAP場景組成,平均來看BaikalDB可以使單位資源效能提升4倍左右。

2.3 雲原生彈效能力帶來的成本減低為5倍

以mysql為例,由於縮擴容升降配困難,為了應對少數發生的業務高峰時段(例如雙11一年只有一次)而不得不一直留夠Buffer,導致硬體資源的投入不能隨著流量的變化而動態變化,彈性不足,資源利用率普遍較低約8%的水平。公司也意識到相關問題,在積極構建基於kubernetes雲原生平臺(見下圖),具體文章參見同程藝龍雲原生 K8s 落地實踐[4]。

BaikalDB的share –nothing雲原生特效能完美的k8s的排程能力進行結合,預計可以把資源利用率提升到40%,因此彈性收益為5倍。之所以沒有提升到80%以上是為了滿足雙中心容災互備的需要,以應對城市級故障帶來的單中心雙倍壓力。

綜上所述,總收益 = HTAP收益 * 單位資源能效收益 * 資源利用率收益 = 5 * 4 * 5 = 100倍

3、實際上廣義的成本難以量化但不能有短板

在狹義成本評估值得做的情況下,需要從專案管理或專案實施的角度思考如何把專案順利推進,由於每家公司每個專案的實際情況均不一樣,專案的評估很難統一量化,但我們在進行專案實施時必須要慎重考慮這些因素,並且任何一個環節不達標均可能導致專案的失敗,在這裡把專案推進中要完成的工作量稱為廣義的成本,以我們實踐經驗進行總結評分,滿分為10分,分值越高越好,評價不同於以往的效能測試,具有很強的主觀性,僅供參考。

3.1 學習開發成本:9分

BaikalDB的學習主要包括依賴與BaikalDB程式碼本身。

BaikalDB的依賴少而精,主要有三個:

1、brpc:Apache專案,百度內最常使用的工業級RPC框架;

2、braft:百度開源的Raft一致性與複製狀態機工業級實現庫;

3、RocksDB:kv儲存引擎,集成了Google與Facebook雙方大牛的力作;

以上三款開源專案,社群都比較成熟,每一款都值得好好學習。

BaikalDB本身作為一款純開源的分散式資料庫,程式碼10萬行,以C++語言為主,程式碼架構簡潔,組織清晰。雖然目前文件不是很多還在完善中,但專案保持了良好編碼風格,程式碼可讀性強,大部分實現原理可以通過直接閱讀程式碼掌握,少部分需要結合資料庫及分散式領域的理論知識與論文學習。在模組化抽象與分層上保持清晰保持簡潔,在一些核心物件例如邏輯計劃:LogicalPlanner,表示式:ExprNode,執行運算元:ExecNode僅有一層繼承關係,具有薄膠合層顯著特點,有效的減低了軟體的學習成本,體現了Unix開源文化的KISS原則(Keep It Simple, Stupid!)

總之,BaikalDB是一款非常值得學習的DB,給9分。

3.2 測試驗證成本:7分

BaikalDB的測試驗證工作量與其它DB差不多,中規中矩給7分。

3.3業務遷移成本:8分

業務的遷移成本主要包括資料遷移與SQL改寫兩個部分,由於BaikalDB相容MySQL協議,公司已研發了基於MySQL生態的資料同步平臺,資料遷移成本不大。使用MySQL開發的業務程式碼,大部分情況不需要改寫SQL,改寫主要發生在BaikalDB尚未支援的MySQL語法例如(子查詢,一些系統函式上)和慢查詢改寫上面,業務遷移成本給8分。

3.4 使用者習慣:7分

1、影象化工具:能使用Navicat, IDEA自帶MySQL UI, DataGrip進行簡單的表瀏覽,SQL執行功能,不能進行復雜管理操作;

2、公司已有系統對接(例如工單,許可權,一站式查詢等):尚未打通;

3、對新概念的接受過程(例如新的資料檔案,部署方式,資源隔離,多租戶等)。

3.5 運維配套工具:7分

  • 備份工具:

熱備:基於SST的備份恢復

冷備:通過SQL語句邏輯備份。

/{"full_export":true}/ select * from tb where id > x limit 1000;

  • 監控工具:Prometheus

  • 運維指令碼:script[5]

  • 部署工具:Ansible

  • 壓測工具:sysbench

  • 訂閱工具:Binlog功能開發中

  • 同步工具:Canal

3.6 軟體成熟度:7分

3.7 技術前瞻性:9分

BaikalDB提供的PB級分散式擴充套件能力,動態變更Schema能力,分散式事務,異地多活,資源隔離,雲原生K8s,HTAP能力均與公司未來的需求或規劃匹配,因此給9分。

4、後記

至此BaikalDB在同程藝龍的應用實踐系列文章就結束了,BaikalDB作為一款開源兩歲的NewSQL資料庫還非常年輕,存在很大完善空間。同時作為後浪也借鑑很多前浪的設計思想,有一定的後發優勢。BaikalDB實現簡潔,功能強大,社群專業友好,無論是用來程式碼學習還是業務應用均有很大成長空間,歡迎感興趣的朋友一起參與。由於筆者水平有限,文中如有不妥之處,還望理解指正。

招聘資訊:

百度商業平臺研發部主要負責百度商業產品的平臺建設,包括廣告投放、落地頁託管、全域資料洞察等核心業務方向,致力於用平臺化的技術服務讓客戶及生態夥伴持續成長,成為客戶最為依賴的商業服務平臺。

無論你是後端,前端,還是演算法,這裡有若干職位在等你,歡迎投遞簡歷, 百度商業平臺研發部期待你的加入!

簡歷投遞郵箱:[email protected](投遞備註【百度商業】)

推薦閱讀:

|面向大規模商業系統的資料庫設計和實踐

|百度愛番番移動端網頁秒開實踐

|解密百TB資料分析如何跑進45秒

---------- END ----------

百度Geek說

百度官方技術公眾號上線啦!

技術乾貨 · 行業資訊 · 線上沙龍 · 行業大會

招聘資訊 · 內推資訊 · 技術書籍 · 百度周邊

歡迎各位同學關注

關鍵詞:站長資訊中心站長資訊站長新聞