架構(gòu)師之路,從「存儲選型」起步
經(jīng)常有人問,架構(gòu)師的學習路線是什么?
我一般推薦架構(gòu)師的基本功,是從「存儲選型」開始的。
本文整理了存儲選型的思路和整體框架,主要包括幾個部分內(nèi)容:
- ?了解目前的存儲技術(shù)趨勢,以及對開發(fā)人員新的要求
- 存儲選型的原則,避免日常的經(jīng)典誤區(qū)
- 結(jié)合典型數(shù)據(jù)庫特點,說明如何進行存儲選型,提高業(yè)務(wù)開發(fā)效率
- 常見的場景和解決方案?
1.存儲技術(shù)發(fā)展看存儲選型
1.1 存儲類型多元化
DB-Engines數(shù)據(jù)庫排名并不代表數(shù)據(jù)庫的安裝數(shù)量,或者使用量。但某數(shù)據(jù)庫越來越受歡迎則代表在一定時間范圍內(nèi)更加廣泛的使用。
這里貼了一張2022年5月份的排行榜(https://db-engines.com/en/ranking)。
我們對于排名前10的數(shù)據(jù)庫中,比較熟悉的應(yīng)該是MySQL、Redis和ES,這三個數(shù)據(jù)庫在我們?nèi)粘i_發(fā)中占據(jù)絕大多數(shù)的比例。
但是,這三個數(shù)據(jù)庫只代表了一小部分的數(shù)據(jù)庫類型,我們是不是可以把視野打開更多一些,看看沒有更多的數(shù)據(jù)庫類型,可以適合我們不同的業(yè)務(wù),包括Relational、Document、Key-value、Search engine、Wide column、Time Series、Graph等等不同數(shù)據(jù)庫類型。
1.2 云原生存儲多元化
除去上面的傳統(tǒng)數(shù)據(jù)庫之外,云時代存儲技術(shù)又有了更多的變化。
除了簡單的把上面的數(shù)據(jù)庫托管到云上之外,還多了許多充分利用云的基礎(chǔ)設(shè)施產(chǎn)生的云原生數(shù)據(jù)庫,比如aws的Amazon Aurora、阿里云的PolarDB、騰訊云的TDSQL等。
另外,云時代還產(chǎn)生了更多類型的數(shù)據(jù)庫,比如阿里云的多模數(shù)據(jù)庫Lindorm、Pingcap的HTAP數(shù)據(jù)庫TiDb等。
多類型數(shù)據(jù)庫是各個云廠商發(fā)展的趨勢,他們?yōu)槭裁磿С衷絹碓蕉嘤猛镜臄?shù)據(jù)庫呢?
供給側(cè)的改變一定是來源于需求側(cè),因為隨著互聯(lián)網(wǎng)、物聯(lián)網(wǎng)等場景發(fā)展,有很多業(yè)務(wù)需求不是任何單一的數(shù)據(jù)庫能解決的了。
1.3 告訴我們什么?
「數(shù)據(jù)庫類型多元化」 & 「云原生數(shù)據(jù)庫類型多元化」 是一個必然的發(fā)展趨勢。
我們要解決的場景會越來越多,我們需要掌握的數(shù)據(jù)庫領(lǐng)域也越來越廣,只有這樣,我們才能面對在線事務(wù)、離線分析、海量存儲、成本與效率等因素,真正做好存儲選型。
2.存儲選型原則:不要耍流氓存儲
2.1 不講場景的選型都是耍流氓
大家可能都知道,數(shù)據(jù)庫的選型一定是基于實際的業(yè)務(wù)場景的。但是,可能也遇到過類似的對話:
上面的對話可能有些夸張,但是實際生產(chǎn)中,可能是對場景的理解有誤,也可能是為了快速完成任務(wù)開發(fā),結(jié)果是在「特定場景」選擇了錯誤的數(shù)據(jù)庫的情況時有發(fā)生。
常見的特定場景包括:
- 離線業(yè)務(wù):日志、搜索、統(tǒng)計等。
- 事務(wù)需求:強事務(wù)型、分析型。
- 數(shù)據(jù)熱度:全熱數(shù)據(jù)、冷熱明顯等。
- 數(shù)據(jù)讀寫偏好:多讀、多寫。
數(shù)據(jù)增長方式:按日期、按用戶、按位置類型等。
對于存儲選型來說,一定需要識別特定場景的特點,是在線業(yè)務(wù)還是離線業(yè)務(wù)?數(shù)據(jù)冷熱是否明顯?數(shù)據(jù)訪問方式特點?數(shù)據(jù)增長方式等等。
如果沒有根據(jù)場景特點來做存儲選型,可能會帶來不良后果,包括無法滿足業(yè)務(wù)需求、存儲成本暴漲等,然后就需要花大代價做不停機數(shù)據(jù)遷移和代碼重構(gòu)。
因此,針對特定業(yè)務(wù)場景的存儲選型一定要仔細、慎重,并在一開始就設(shè)計好。
2.2 不講數(shù)據(jù)規(guī)模的選型都是耍流氓
除了特定場景外,「數(shù)據(jù)規(guī)模」是存儲選型的另一個核心要素。
這樣的對話非常常見。
雖然在一些新業(yè)務(wù)場景下,確實很難準確評估業(yè)務(wù)的數(shù)據(jù)規(guī)模,但是無法評估的數(shù)據(jù)規(guī)模,往往意味著無法做好正確的存儲選型。
因此,如果有一定的先驗知識,我們需要盡量做好數(shù)據(jù)規(guī)模的評估。比如,之前有沒有類似的業(yè)務(wù)、其他組有沒有類似的需求或功能,它們目前的數(shù)據(jù)規(guī)模大致如何,然后進行評估。
常見的數(shù)據(jù)規(guī)模指標有三個:
- 數(shù)據(jù)總量
- QPS
- rt
不同的數(shù)據(jù)規(guī)模指標,往往意味著不同的存儲選型。
2.3 不講掌控度的選型都是耍流氓
對于存儲選型,「掌控度」是非常重要的選型原則。
這里其實包括了兩個維度,開發(fā)同學對存儲的掌控度 & DBA對存儲的掌控度。
1)開發(fā)同學的掌控度
對開發(fā)同學來說,選擇一個存儲,一定是基于對該存儲的基本認知&最佳實踐的了解。
一定不是其他人也這么用所以我這么用。
如果盲目使用一個自己不了解的存儲,很容易帶來不良后果,輕則造成資源浪費,重則引起線上故障(比如Mysql的慢sql、HBase的熱點訪問等)。
2)DBA對存儲的掌控度
對DBA來說,對一個存儲的基本認知&最佳實踐是基礎(chǔ)要求了。在此之上,還有其他更多的要求。
一個是社區(qū)活躍度。社區(qū)活躍度決定著你獲取信息的難易程度,也決定到出現(xiàn)了故障后的定位速度甚至是能不能定位出來,如果社區(qū)很活躍,自然就能得到更多的幫助。
第二個是有沒有案例背書。最好是一些中廠、大廠最新的案例實踐(千萬不要被大廠多年前的案例迷惑,技術(shù)發(fā)展往往意味著更新更合適的解決方案)。如果案例與存儲不匹配,或者沒有什么案例來支持你的存儲選型,那么這個選型可能就是不合適的。
第三個是存儲組件的上手成本。團隊具備了什么樣的技術(shù)儲備?選擇的是自研還是云產(chǎn)品?云產(chǎn)品是全托管的還是半托管的?畢竟每一種數(shù)據(jù)庫都不是這么簡單,如果人力有限而上手難度又很大,那么這個存儲組件目前可能不是一個好的選擇。
3.選型路線圖
結(jié)合上面的原則,我們來做一個存儲選型路線圖供大家參考。
進一步,針對各個類型數(shù)據(jù)庫,我們都需要了解它們的優(yōu)點、缺點、最佳實踐等,來結(jié)合業(yè)務(wù)場景因地制宜。
3.1 Relational
以MySQL為代表的關(guān)系型數(shù)據(jù)庫。常用于在線業(yè)務(wù)(OLTP)場景,對于強事務(wù)有較好支持。
優(yōu)點:
- 容易理解,大家基本上都用得比較熟
- 事務(wù)特性
- 配套成熟(備份恢復(fù)、數(shù)據(jù)訂閱、數(shù)據(jù)同步等)
- 服務(wù)極度穩(wěn)定
缺點:
- 不易水平擴展
- 大表表結(jié)構(gòu)變更復(fù)雜
- 全文檢索能力弱
- 復(fù)雜分析、統(tǒng)計能力弱
最佳實踐:
- 索引設(shè)計
- 避免n+1輪訓
- 避免深分頁
- 單表千萬考慮分庫分表,或者使用云數(shù)據(jù)庫(polarDB或者TDSQL)
- 冷熱數(shù)據(jù)注意歸檔
- 不直接處理統(tǒng)計、分析型操作
3.2 Key-value
KV型NoSql顧名思義就是以鍵值對形式存儲的非關(guān)系型數(shù)據(jù)庫,是最簡單、最容易理解也是大家最熟悉的一種 NoSql。
Redis是其中的代表,典型用于緩存場景。
優(yōu)點:
- 數(shù)據(jù)基于內(nèi)存,讀寫效率高
- KV型數(shù)據(jù),時間復(fù)雜度為O(1),查詢速度快
缺點:
- 查詢方式單一
- 內(nèi)存有限,且非常昂貴
- 由于存儲是基于內(nèi)存的,會有丟失數(shù)據(jù)的風險(有持久化存儲方案)
最佳實踐:
- 合理控制kv大小,避免大key
- 避免熱點key
- 設(shè)置合理的TTL
- 注意緩存雪崩、穿透、擊穿、兼容問題
- 不要用于消息隊列,異常情況無法堆積消息
- 不要將redis作為數(shù)據(jù)庫使用,可能會丟數(shù)據(jù)
3.3 Search engine
搜索型NoSql顧名思義主要是用在搜索場景下的。
盡管MySQL可以通過索引來加速查詢,但是對于全文搜索、模糊搜索等場景就比較無力,搜索型NoSql正是為了補足這個場景誕生的。
ElasticSearch是其中的代表產(chǎn)品。
優(yōu)點:
- 支持分詞場景、全文搜索,這是區(qū)別于關(guān)系型數(shù)據(jù)庫最大特點
- 支持條件查詢,支持聚合操作,適合數(shù)據(jù)分析
- 在集群環(huán)境下可以方便橫向擴展,可承載PB級別的數(shù)據(jù)
缺點:
- 讀寫之間有延遲,寫入的數(shù)據(jù)不一定能馬上讀到
- 硬件性能要求高
最佳實踐:
- 核心在線應(yīng)用強依賴ES需要考慮可行的降級方案
- 禁止使用單索引多type
- ES成本較高,因此建議僅數(shù)據(jù)庫加速、全文檢索情況下使用es
- ES中僅存儲索引字段,通過id回查數(shù)據(jù)庫,不要全量數(shù)據(jù)存儲ES
- 根據(jù)節(jié)點數(shù)量設(shè)置合理的分片數(shù)量、分片大小
3.4 Document
文檔型 NoSql 指的是將半結(jié)構(gòu)化數(shù)據(jù)存儲為文檔的一種 NoSql,通常以 JSON 或者 XML 格式存儲數(shù)據(jù)。
Mongo是其中的代表產(chǎn)品。
優(yōu)點:
- 沒有預(yù)定義的字段,擴展字段容易
- 相較于關(guān)系型數(shù)據(jù)庫,讀寫性能優(yōu)越
- 分片集群易水平擴展
缺點:
- 文檔結(jié)構(gòu)過于靈活,可能導(dǎo)致不易維護
- 客戶端控制力強,對開發(fā)、優(yōu)化上有一定要求
最佳實踐:
- 選擇合理的片鍵
- 建立合適的索引
- 正確使用寫關(guān)注設(shè)置(Write Concern)
- 正確使用讀選項設(shè)置(Read Preference)
- 正確使用更新語句(局部更新、防止大量更新集中在一條數(shù)據(jù)內(nèi))
3.5 Wide column
一般用于可靠性要求不高的海量存儲場景。
HBase是代表產(chǎn)品(國外cassandra用得多,國內(nèi)HBase用得多)。
優(yōu)點:
- 動態(tài)列調(diào)整,不受表結(jié)構(gòu)困擾
- 海量數(shù)據(jù)存儲,PB 級別數(shù)據(jù)
- 橫向擴展方便,且支持廉價存儲擴展,成本低,適用于無法預(yù)估存儲量的海量數(shù)據(jù)
缺點:
- Hadoop生態(tài)產(chǎn)品,組件依賴多,沒有云托管產(chǎn)品,運維能力要求比較高
- Rowkey設(shè)計需要一定經(jīng)驗,避免熱點
- 單集群SLA一般3個9,如果用于在線核心業(yè)務(wù),一定需要考慮降級和容災(zāi)
- 只支持行級事務(wù)
最佳實踐:
- 適用于行數(shù)多,但單個kv數(shù)據(jù)量?。?M以下)
- 特別注意Rowkey設(shè)計,避免熱點
- 大value(10M以上)禁止存入HBase,考慮對象存儲
- 表創(chuàng)建時必須預(yù)分區(qū)
- 表的列族數(shù)量不得超過 2 個
- HBase是CP型系統(tǒng),SLA一般是3個9,一般建議離線業(yè)務(wù)使用。如果核心在線業(yè)務(wù)使用,必須做好降級、容災(zāi)
4.常見場景和選型方案
上文提出了 三條選型原則 和 常見數(shù)據(jù)庫的選型依據(jù),下面結(jié)合不同場景做一下常規(guī)選型方案參考。
4.1 主要場景和方案
毋庸置疑,互聯(lián)網(wǎng)業(yè)務(wù)的主要場景,是采用mysql進行數(shù)據(jù)存儲。正如MySQL的自己所說 —— most popular open source database。
當然,為了扛住高并發(fā)場景,緩存也不可缺失。
因此,最主要的方案就是 MySQL + Redis。
適用于日常主要場景:
- MySQL滿足事務(wù)性要求
- Redis抗熱點
4.2 模糊搜索 or 全文檢索
MySQL數(shù)據(jù)庫擅長在線業(yè)務(wù)(OLTP)讀寫,不擅長做統(tǒng)計、分析型業(yè)務(wù)(OLAP)。因此,一般會通過MySQL做持久化存儲,ES構(gòu)建索引進行查詢、分析。
適用于搜索場景:
- 復(fù)雜查詢
- 模糊搜索
- 全文搜索
- 統(tǒng)計分析
4.3 大量數(shù)據(jù)場景
數(shù)據(jù)規(guī)模:100TB以內(nèi)的數(shù)據(jù)量。
1)MySQL分庫分表 + es
傳統(tǒng)MySQL橫向擴展方案,利用分庫分表中間件進行存儲擴展,利用ES進行非分表鍵查詢和復(fù)雜查詢。
適用場景:
- 數(shù)據(jù)量較大
- 有中間件使用能力
- 已有MySQL橫向擴展
2)云原生數(shù)據(jù)庫(以polarDB為例)
云時代的新方案。
PolarDB是阿里巴巴自研的新一代云原生關(guān)系型數(shù)據(jù)庫,在存儲計算分離架構(gòu)下,利用了軟硬件結(jié)合的優(yōu)勢,為用戶提供具備極致彈性、高性能、海量存儲、安全可靠的數(shù)據(jù)庫服務(wù),100%兼容MySQL 5.6/5.7/8.0。
最高100 TB,不再需要因為單機容量的天花板而去購買多個實例做分片,由此簡化應(yīng)用開發(fā),降低運維負擔。
適用場景:
- 數(shù)據(jù)量較大
- 有公有云使用基礎(chǔ)設(shè)施
3)mongo分片集群
適用場景:
- 數(shù)據(jù)量較大的NoSQL場景
- 表結(jié)構(gòu)變更頻繁場景,free-schema
- 對mongo使用有一定理解
4.4 海量數(shù)據(jù)場景
數(shù)據(jù)規(guī)模:100TB以上的數(shù)據(jù)量。
1)高可用數(shù)據(jù)庫 + HBase
由于數(shù)據(jù)量非常大,需要考慮存儲成本。因此一般會考慮冷熱數(shù)據(jù)分離。
熱數(shù)據(jù)在高可用數(shù)據(jù)庫進行讀寫,可以選擇MySQL、Mongo等。冷數(shù)據(jù)存入成本較低的HBase或者對象存儲等組件。
適用場景:
- 海量數(shù)據(jù)
- 可靠性要求高
2)直接使用HBase
如果是非核心在線業(yè)務(wù),或者離線業(yè)務(wù),可以考慮直接使用HBase。
適用場景:
- 海量數(shù)據(jù)
- 低成本
- 可靠性要求不高
5.總結(jié)
在業(yè)務(wù)開發(fā)過程中,除了常用的MySQL,一定要多關(guān)注市面上更合適的存儲方案,這是架構(gòu)師的基本功。
通過了解更多存儲組件的基本特性和使用場景,因地制宜選擇合適存儲,提高業(yè)務(wù)開發(fā)效率,降低使用成本。
希望本文能夠拋磚引玉,提供一些啟發(fā)和思考。