欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

當數據庫扼住系統性能咽喉

李中冰2年前20瀏覽0評論

當數據庫扼住系統性能咽喉?

大部分的軟件架構、組件或解決方案,都是在解決一些問題的同時,會帶來另外的問題。

數據庫的分庫分表,又可以分為垂直拆分和水平拆分(可能大家常說的分庫分表主要指的是后者):

垂直拆分:這是一種比較常見的數據庫設計方法,就是把一個字段比較多的大表,拆分成多個小表,特別是在現在分布式、微服務的架構下,可以把各個小表按照業務模型,劃分到不同的數據庫中,這樣就可以利用多臺數據庫服務器的性能;但當被拆分出來小表的數據量不斷增長,到了一個極限的時候,還是需要考慮水平拆分。

水平拆分:將表中的數據,按照一定的規則分布到不同的數據庫中,比如對主鍵進行Hash和取模操作后,按照結果把數據路由到對應的數據庫上;水平分庫分表,可以降低每張表的數據量,這也是現在大部分公司所使用的方法。

數據庫擴容問題

上文中說到,水平拆分常用的手段是對主鍵進行Hash和取模操作后,按照結果把數據路由到對應的數據庫上;但如果被拆分的子表,數據量也達到極限值以后,就要面對數據庫擴容的問題,比如開始規劃分成8個庫,現在要擴到16個庫;

路由規則發生變化:hash(id)%8 變成了 hash(id)%16,那么歷史數據也就要面臨遷移的問題;這種情況,要么做數據遷移,要么增加分表算法的復雜性,讓算法可以兼容增加分表前后的數據路由。

復雜查詢、關聯查詢、order by、group by等的問題

在單庫時代,復雜的關聯查詢是很容易實現的,但是數據庫被拆分后,數據被保存在了不同的數據庫服務器上,那么夸庫的join就成了很大的問題。通常解決方案有:

如果是垂直拆分,那么可以考慮做一定程度的字段冗余,避免跨表關聯;或者可以做數據同步,把需要的表同步到同一個庫中,進行表關聯;

代碼層面組裝,也就是把兩邊的數據都拿出來,然后在代碼里面關聯組裝;或者先獲取主表數據,再把其余字段補齊;但是從實際情況來看,這個方案在大多數場景下,實現起來都比較困難;

現在一個比較主流的做法,是引入ES或ES+HBase或solr+HBase,把部分字段的全量數據保存在同一個地方。

ID問題

在水平拆分的場景下,一單一張表被拆分成多張表部署在多個數據庫中,那么就不能使用數據庫自身的主鍵生成機制了;這時候就需要由我們自己來考慮主鍵生成策略:

主鍵生成中心:可以利用數據庫、Redis、MongoDB、zookeeper等組件實現,需要生產主鍵的時候,調用主鍵生成中心的接口;缺點也很明顯,增加了網絡開銷,并且主鍵生成中心如果發生問題,后果會很嚴重。

UUID:本地生成,不需要第三方組件,生成比較簡單,性能好;不過缺點也不少,長度長,不利于存儲,并且沒有排序,是個字符串,不利于查詢。

一些唯一性ID的生成算法:比如Snowflake、UidGenerator、Leaf等等。

事務問題

單庫的時候,解決事務問題很簡單,但是現在要保證跨庫的事務問題,需要額外的成本;

這種場景下(性能要求高,一致性要求不是那么的高),大部分公司會放棄事務的【實時】一致性,只要在一定的時間內,事務【最終】一致即可。

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。