整理了一些Java方面的架構、面試資料(微服務、集羣、分佈式、中間件等),有須要的小夥伴能夠關注公衆號【程序員內點事】,無套路自行領取程序員
更多優選面試
微服務、分佈式大行其道的當下,中、高級Java工程師面試題中高併發、大數據量、分庫分表等已經成算法
了面試的高頻詞彙,這些知識不瞭解面試經過率不會過高。你能夠不會用,但你不能不知道,就是這麼sql
一種現狀。技術名詞大多晦澀難懂,不要死記硬背理解最重要,當你捅破那層窗戶紙,發現其實它也就數據庫
那麼回事。網絡
關係型數據庫以MySQL爲例,單機的存儲能力、鏈接數是有限的,它自身就很容易會成爲系統的瓶數據結構
頸。當單表數據量在百萬以裏時,咱們還能夠經過添加從庫、優化索引提高性能。一旦數據量朝着千萬架構
以上趨勢增加,再怎麼優化數據庫,不少操做性能仍降低嚴重。爲了減小數據庫的負擔,提高數據庫響併發
應速度,縮短查詢時間,這時候就須要進行分庫分表
。框架
分庫分表就是要將大量數據分散到多個數據庫中,使每一個數據庫中數據量小響應速度快,以此來提高數
據庫總體性能。核心理念就是對數據進行切分(Sharding
),以及切分後如何對數據的快速定位與整合。
針對數據切分類型,大體能夠分爲:垂直(縱向)切分和水平(橫向)切分兩種。
垂直切分又細分爲垂直分庫
和垂直分表
垂直分庫
垂直分庫是基於業務分類的,和咱們常聽到的微服務治理觀念很類似,每個獨立的服務都擁有本身的
數據庫,須要不一樣業務的數據需接口調用。而垂直分庫也是按照業務分類進行劃分,每一個業務有獨立數
據庫,這個比較好理解。
垂直分表
垂直分表
是基於數據表的列爲依據切分的,是一種大表拆小表的模式。
例如:一個order
表有不少字段,把長度較大且訪問不頻繁的字段,拆分出來建立一個單獨的擴展表work_extend
進行存儲。
order
表:
id | workNo | price | describe | ..... |
---|---|---|---|---|
int(12) | int(2) | int(15) | varchar(2000) |
拆分後
order
核心表:
id | workNo | price | ..... |
---|---|---|---|
int(12) | int(2) | int(15) |
work_extend
表:
id | workNo | describe | ..... |
---|---|---|---|
int(12) | int(2) | varchar(2000) |
數據庫是以行爲單位將數據加載到內存中,這樣拆分之後核心表大可能是訪問頻率較高的字段,並且字段
長度也都較短,能夠加載更多數據到內存中,增長查詢的命中率,減小磁盤IO,以此來提高數據庫性能。
優勢:
缺點:
前邊說了垂直切分仍是會存在單表數據量過大的問題,當咱們的應用已經沒法在細粒度的垂直切分時,依舊存在單庫讀寫、存儲性能瓶頸,這時就要配合水平切分一塊兒了。
水平切分將一張大數據量的表,切分紅多個表結構相同,而每一個表只佔原表一部分數據,而後按不一樣的條件分散到多個數據庫中。
假如一張order
表有2000萬數據,水平切分後出來四個表,order_1
、order_2
、order_3
、order_4
,每張表數據500萬,以此類推。
order_1
表:
水平切分又分有庫內分表
和分庫分表
庫內分表
庫內分表雖然將表拆分,但子表都仍是在同一個數據庫實例中,只是解決了單一表數據量過大的問題,並無將拆分後的表分佈到不一樣機器的庫上,還在競爭同一個物理機的CPU、內存、網絡IO。
分庫分表
分庫分表則是將切分出來的子表,分散到不一樣的數據庫中,從而使得單個表的數據量變小,達到分佈式的效果。
優勢:
缺點:
分庫分表之後會出現一個問題,一張表會出如今多個數據庫裏,到底該往哪一個庫的表裏存呢?
按照時間區間
或ID區間
來切分,舉個栗子:假如咱們切分的是用戶表,能夠定義每一個庫的User表
裏只存10000條數據,第一個庫userId
從1 ~ 9999,第二個庫10000 ~ 20000,第三個庫20001~ 30000......以此類推。
優勢:
缺點:
hash取模mod(對hash結果取餘數 (hash() mod N))的切分方式比較常見,還拿User表
舉例,對數據庫從0到N-1進行編號,對User表
中userId
字段進行取模,獲得餘數i
,i=0
存第一個庫,i=1
存第二個庫,i=2
存第三個庫....以此類推。
這樣同一個用戶的數據都會存在同一個庫裏,用userId
做爲條件查詢就很好定位了
優勢:
缺點:
因爲表分佈在不一樣庫中,不可避免會帶來跨庫事務問題。通常可以使用"XA協議"和"兩階段提交"處理,可是這種方式性能較差,代碼開發量也比較大。
一般作法是作到最終一致性的方案,每每不苛求系統的實時一致性,只要在容許的時間段內達到最終一致性便可,可採用事務補償的方式。
平常開發中分頁、排序是必備功能,而多庫進行查詢時limit
分頁、order by
排序,着實讓人比較頭疼。
分頁需按照指定字段進行排序,若是排序字段剛好是分片字段時,經過分片規則就很容易定位到分片的位置;一旦排序字段非分片字段時,就須要先在不一樣的分片節點中將數據進行排序並返回,而後將不一樣分片返回的結果集進行彙總和再次排序,最終返回給用戶,過程比較複雜。
因爲分庫分表後,表中的數據同時存在於多個數據庫,而某個分區數據庫的自增主鍵已經沒法知足全局
惟一,因此此時一個可以生成全局惟一ID的系統是很是必要的。那麼這個全局惟一ID就叫分佈式ID
。可
以參考我以前寫的這篇文章《一口氣說出 9種 分佈式ID生成方式,面試官有點懵了》
本身開發分庫分表工具的工做量是巨大的,好在業界已經有了不少比較成熟的分庫分表中間件,咱們可
以將更多的時間放在業務實現上
----
今天就說這麼多,若是本文對您有一點幫助,但願能獲得您一個點贊👍哦
您的承認纔是我寫做的動力!
整理了一些Java方面的架構、面試資料(微服務、集羣、分佈式、中間件等),有須要的小夥伴能夠關注公衆號【程序員內點事】,無套路自行領取