针对海量数据的存储与访问瓶颈的解决方案
背景
??在當(dāng)今這個時代,人們對互聯(lián)網(wǎng)的依賴程度非常高,也因此產(chǎn)生了大量的數(shù)據(jù),企業(yè)視這些數(shù)據(jù)為瑰寶。而這些被視為瑰寶的數(shù)據(jù)為我們的系統(tǒng)帶來了很大的煩惱。這些海量數(shù)據(jù)的存儲與訪問成為了系統(tǒng)設(shè)計與使用的瓶頸,而這些數(shù)據(jù)往往存儲在數(shù)據(jù)庫中,傳統(tǒng)的數(shù)據(jù)庫存在著先天的不足,即單機(單庫)性能瓶頸,并且擴展起來非常的困難。在當(dāng)今的這個大數(shù)據(jù)時代,我們急需解決這個問題 。如果單機數(shù)據(jù)庫易于擴展,數(shù)據(jù)可切分,就可以避免這些問題,但是當(dāng)前的這些數(shù)據(jù)庫廠商,包括開源的數(shù)據(jù)庫MySQL在內(nèi),提供這些服務(wù)都是需要收費的,所以我們轉(zhuǎn)向一些第三方的軟件,使用這些軟件做數(shù)據(jù)的切分,將原本在一臺數(shù)據(jù)庫上的數(shù)據(jù),分散到多臺數(shù)據(jù)庫當(dāng)中,降低每一個單體數(shù)據(jù)庫的負(fù)載。那么我們?nèi)绾巫鰯?shù)據(jù)切分呢?
數(shù)據(jù)切分
??數(shù)據(jù)切分,簡單的說,就是通過某種條件,將我們之前存儲在一臺數(shù)據(jù)庫上的數(shù)據(jù),分散到多臺數(shù)據(jù)庫中,從而達到降低單臺數(shù)據(jù)庫負(fù)載的效果。數(shù)據(jù)切分,根據(jù)其切分的規(guī)則,大致分為兩種類型,垂直切分和水平切分。
垂直切分
??垂直切分就是按照不同的表或者Schema切分到不同的數(shù)據(jù)庫中,比如:在我們的課程中,訂單表(order) 和商品表(product) 在同一個數(shù)據(jù)庫中,而我們現(xiàn)在要對其切分,使得訂單表(order) 和商品表(product) 分別落到不同的物理機中的不同的數(shù)據(jù)庫中,使其完全隔離,從而達到降低數(shù)據(jù)庫負(fù)載的效果。如圖所示:
??垂直切分的特點就是規(guī)則簡單,易于實施,可以根據(jù)業(yè)務(wù)模塊進行劃分,各個業(yè)務(wù)之間耦合性低,相互影響也較小。
??一個架構(gòu)設(shè)計較好的應(yīng)用系統(tǒng),其總體功能肯定是有多個不同的功能模塊組成的。每一個功能模塊對應(yīng)著數(shù)據(jù)庫里的一系列表。例如在咱們的課程當(dāng)中,商品功能模塊對應(yīng)的表包括:類目、屬性、屬性值、品牌、商品、sku等表。而在訂單模塊中,對應(yīng)的表包括:訂單、訂單明細(xì)、訂單收貨地址、訂單日志等。如圖所示:
??在架構(gòu)設(shè)計中,各個功能模塊之間的交互越統(tǒng)一、越少越好。這樣,系統(tǒng)模塊之間的耦合度會很低,各個系統(tǒng)模塊的可擴展性、可維護性也會大大提高。這樣的系統(tǒng),實現(xiàn)數(shù)據(jù)的垂直切分就會很容易。
??但是,在實際的系統(tǒng)架構(gòu)設(shè)計中,有一些表很難做到完全的獨立,往往存在跨庫join的現(xiàn)象。還是上面的例子,比如我們接到了一個需求,要求查詢某一個類目產(chǎn)生了多少訂單,如果在單體數(shù)據(jù)庫中,我們直接連表查詢就可以了。但是現(xiàn)在垂直切分成了兩個數(shù)據(jù)庫,跨庫連表查詢是十分影響性能的,也不推薦這樣用,只能通過接口去調(diào)取服務(wù),這樣系統(tǒng)的復(fù)雜度又升高了。對于這種很難做到完全獨立的表,作為系統(tǒng)架構(gòu)設(shè)計人員,就要去做平衡,是數(shù)據(jù)庫讓步于業(yè)務(wù),將這些表放在一個數(shù)據(jù)庫當(dāng)中?還是拆分成多個數(shù)據(jù)庫,業(yè)務(wù)之間通過接口來調(diào)用呢?在系統(tǒng)初期,數(shù)據(jù)量比較小,資源也有限,往往會選擇放在一個數(shù)據(jù)庫當(dāng)中。而隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)量達到了一定的規(guī)模,就有必要去進行數(shù)據(jù)的垂直切分了。而如何進行切分,切分到什么程度,則是對架構(gòu)師的一個艱難的考驗。
下面我們來看看垂直切分的優(yōu)缺點:
優(yōu)點:
- 拆分后業(yè)務(wù)清晰,拆分規(guī)則明確;
- 系統(tǒng)之間容易擴展和整合;
- 數(shù)據(jù)維護簡單
缺點:
- 部分業(yè)務(wù)表無法join,只能通過接口調(diào)用,提升了系統(tǒng)的復(fù)雜度;
- 跨庫事務(wù)難以處理;
- 垂直切分后,某些業(yè)務(wù)數(shù)據(jù)過于龐大,仍然存在單體性能瓶頸;
正如缺點中的最后一條所說,當(dāng)某一個業(yè)務(wù)模塊的數(shù)據(jù)暴增時,仍然存在著單機性能缺陷。還是之前的例子,如果出現(xiàn)了一個爆款商品,訂單量急劇上升,達到了單機性能瓶頸,那么你所有和訂單相關(guān)的業(yè)務(wù)都要受到影響。這時我們就要用到水平切分。
水平切分
??水平切分相比垂直切分,更為復(fù)雜。它需要將一個表中的數(shù)據(jù),根據(jù)某種規(guī)則拆分到不同的數(shù)據(jù)庫中,例如:訂單尾號為奇數(shù)的訂單放在了訂單數(shù)據(jù)庫1中,而訂單尾號為偶數(shù)的訂單放在了訂單數(shù)據(jù)庫2中。這樣,原本存在一個數(shù)據(jù)庫中的訂單數(shù)據(jù),被水平的切分成了兩個數(shù)據(jù)庫。在查詢訂單數(shù)據(jù)時,我們還要根據(jù)訂單的尾號,判斷這個訂單在數(shù)據(jù)庫1中,還是在數(shù)據(jù)庫2中,然后將這條SQL語句發(fā)送到正確的數(shù)據(jù)庫中,查出訂單。水平切分的架構(gòu)圖如下:
??水平拆分?jǐn)?shù)據(jù),要先訂單拆分的規(guī)則,找到你要按哪個維度去拆分,還是前面訂單的例子,我們按照訂單尾號的奇偶去拆分,那么這樣拆分會有什么影響呢?假如我是一個用戶,我下了兩個訂單,一個訂單尾號為奇數(shù),一個訂單尾號為偶數(shù),這時,我去個人中心,訂單列表頁去查看我的訂單。那么這個訂單列表頁要去怎么查,要根據(jù)我的用戶d分別取訂單1庫和訂單2庫去查詢出訂單,然后再合并成一個列表,是不是很麻煩。所以,咱們在拆分?jǐn)?shù)據(jù)時,一定要結(jié)合業(yè)務(wù),選擇出適合當(dāng)前業(yè)務(wù)場景的拆分規(guī)則。那么按照用戶id去拆分?jǐn)?shù)據(jù)就合理嗎?也不一定,比如:咱們的身份變了,不是買家了,而是賣家,我這個賣家有很多的訂單,賣家的后臺系統(tǒng)也有訂單列表頁,那這個訂單列表頁要怎么樣去查?是不是也要在所有的訂單庫中查一遍,然后再聚合成一個訂單列表呀。那這樣看,是不是按照用戶id去拆分訂單又不合理了。所以在做數(shù)據(jù)水平拆分時,是對架構(gòu)師的真正考驗。
我們看看幾種水平拆分的典型的分片規(guī)則:
- 用戶id求模,我們前面已經(jīng)提到過;
- 按照日期去拆分?jǐn)?shù)據(jù);
- 按照其他字段求模,去拆分?jǐn)?shù)據(jù);
上面是按照用戶id去求模拆分的一個示意圖。咱們再來看看水平拆分的優(yōu)缺點:
優(yōu)點:
- 解決了單庫大數(shù)據(jù)、高并發(fā)的性能瓶頸;
- 拆分規(guī)則封裝好,對應(yīng)用端幾乎透明,開發(fā)人員無需關(guān)心拆分細(xì)節(jié);
- 提高了系統(tǒng)的穩(wěn)定性和負(fù)載能力;
缺點:
- 拆分規(guī)則很難抽象;
- 分片事務(wù)一致性難以解決;
二次擴展時,數(shù)據(jù)遷移、維護難度大。比如:開始我們按照用戶id對2求模,但是隨著業(yè)務(wù)的增長,2臺數(shù)據(jù)庫難以支撐,還是繼續(xù)拆分成4個數(shù)據(jù)庫,那么這時就需要做數(shù)據(jù)遷移了。
總結(jié)
世界上的萬物沒有完美的,有利就有弊,就像數(shù)據(jù)切分一樣。無論是垂直切分,還是水平切分,它們解決了海量數(shù)據(jù)的存儲和訪問性能問題,但也隨之而來的帶來了很多新問題,它們的共同缺點有:
分布式的事務(wù)問題;
跨庫join問題;
多數(shù)據(jù)源的管理問題
針對多數(shù)據(jù)源的管理問題,主要有兩種思路:
- 客戶端模式,在每個應(yīng)用模塊內(nèi),配置自己需要的數(shù)據(jù)源, 直接訪問數(shù)據(jù)庫,在各模塊內(nèi)完成數(shù)據(jù)的整合;
- 中間代理模式,中間代理統(tǒng)一管理所有的數(shù)據(jù)源,數(shù)據(jù)庫層對開發(fā)人員完全透明,開發(fā)人員無需關(guān)注拆分的細(xì)節(jié)。
基于這兩種模式,目前都有成熟的第三方軟件,代表作分別如下:
- 中間代理模式: MyCat
- 客戶端模式: sharding-jdbc
總結(jié)
以上是生活随笔為你收集整理的针对海量数据的存储与访问瓶颈的解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行如何查询电子回单
- 下一篇: 固件不兼容怎么办? 如何下载可刷版本固件