如何做好高并發(fā)系統(tǒng)設(shè)計(jì),我總結(jié)了三點(diǎn)
本文轉(zhuǎn)載自微信公眾號(hào)「架構(gòu)精進(jìn)之路」,作者張張。轉(zhuǎn)載本文請(qǐng)聯(lián)系架構(gòu)精進(jìn)之路公眾號(hào)。
大家在面試中是不是經(jīng)常被問(wèn)到一個(gè)問(wèn)題:“如果你系統(tǒng)的流量增加 N 倍你要怎么重新設(shè)計(jì)你的系統(tǒng)?”
這個(gè)高并發(fā)的問(wèn)題可以從各個(gè)層面去解,主要包括以下幾點(diǎn)。
1、代碼層面
鎖優(yōu)化(采用無(wú)鎖數(shù)據(jù)結(jié)構(gòu)),主要是 concurrent 包下面的關(guān)于 AQS 鎖的一些內(nèi)容
數(shù)據(jù)庫(kù)緩存設(shè)計(jì)(降低數(shù)據(jù)庫(kù)并發(fā)爭(zhēng)搶壓力),這里又會(huì)有緩存、DB 數(shù)據(jù)不一致的問(wèn)題,在實(shí)際使用中,高并發(fā)系統(tǒng)和數(shù)據(jù)一致性系統(tǒng)采用的策略會(huì)截然相反。
數(shù)據(jù)更新時(shí)采用合并更新,可以在應(yīng)用層去做更新合并,同一個(gè) Container 在同一時(shí)間只會(huì)有一個(gè) DB 更新請(qǐng)求。
其他的比如基于 BloomFilter 的空間換時(shí)間、通過(guò)異步化降低處理時(shí)間、通過(guò)多線程并發(fā)執(zhí)行等等。
2、數(shù)據(jù)庫(kù)層面
根據(jù)不同的存儲(chǔ)訴求來(lái)進(jìn)行不同的存儲(chǔ)選型,從早期的 RDBMS,再到 NoSql(KV 存儲(chǔ)、文檔數(shù)據(jù)庫(kù)、全文索引引擎等等),再到最新的 NewSql(TiDB、Google spanner/F1 DB)等等。表數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì),字段類型選擇與區(qū)別。
索引設(shè)計(jì),需要關(guān)注聚簇索引原理與覆蓋索引消除排序等,至于最左匹配原則都是爛大街的常識(shí)了,高級(jí)一點(diǎn)索引消除排序的一些機(jī)制等等,B+樹(shù)與 B 樹(shù)的區(qū)別。
最后的常規(guī)手段:分庫(kù)分表、讀寫分離、數(shù)據(jù)分片、熱點(diǎn)數(shù)據(jù)拆分等等,高并發(fā)往往會(huì)做數(shù)據(jù)分桶,這里面往深了去說(shuō)又有很多,比如分桶如何初始化、路由規(guī)則、最后階段怎么把數(shù)據(jù)合并等等,比較經(jīng)典的方式就是把桶分成一個(gè)主桶+N 個(gè)分桶。
3、架構(gòu)設(shè)計(jì)層面
- 分布式系統(tǒng)為服務(wù)化
- 無(wú)狀態(tài)化支持水平彈性擴(kuò)縮容
- 業(yè)務(wù)邏輯層面 failfast 快速失敗
- 調(diào)用鏈路熱點(diǎn)數(shù)據(jù)前置
- 多級(jí)緩存設(shè)計(jì)
- 提前容量規(guī)劃等等
總結(jié)
所謂高并發(fā),常常意味著大流量,需要運(yùn)用技術(shù)手段抵抗流量的沖擊,這些手段好比操作流量,能讓流量更平穩(wěn)地被系統(tǒng)所處理,帶給用戶更好的體驗(yàn)。
高并發(fā)確實(shí)是一個(gè)復(fù)雜且系統(tǒng)性的問(wèn)題,由于篇幅有限,諸如分布式Trace、全鏈路壓測(cè)、柔性事務(wù)都是要考慮的技術(shù)點(diǎn)。另外,如果業(yè)務(wù)場(chǎng)景不同,高并發(fā)的落地方案也會(huì)存在差異,但是總體的設(shè)計(jì)思路和可借鑒的方案基本類似。
高并發(fā)設(shè)計(jì)同樣要秉承架構(gòu)設(shè)計(jì)的3個(gè)原則:簡(jiǎn)單、合適和嚴(yán)謹(jǐn)。不能脫離業(yè)務(wù)的實(shí)際情況,更不要過(guò)度設(shè)計(jì),合適的方案就是最完美的。