库表分离
- 讀寫分離:
由于用戶的增多,數據的增多,單機的數據庫往往支撐不住快速發展的業務,所以數據集群就產生了。
讀寫分離就是讀和寫分離了,對應到數據庫集群一般都是一主一從,或者一主多從。業務服務器把需要寫的操作都寫到主數據庫,讀的操作都去從庫查詢。主庫會同步數據到從庫保證數據的一致性。
集群方式的本質就是把訪問的眼里從主庫轉移到從庫。
在單機的情況下,一般我們做數據庫優化都會加索引,但是加了索引對查詢有優化,但是會影響寫入,因為寫入數據會更新索引。所以做了主從之后,我們可以單獨的針對從庫做索引上的優化,而主庫可以減少索引而提高寫的效率。
有兩點需要注意:主從同步延遲,分配機制的考慮;
主從同步延遲
主庫有數據寫入之后,同時也寫入在binlog中,從庫是通過binlog文件來同步數據的,這期間會有一定時間的延遲,如果同事有大量數據寫入的話,時間可能更長。
解決主從同步延遲問題的方法:
- 二次讀?。阂馑季褪亲x從庫沒讀到之后再去主庫讀一下
- 寫之后的馬上讀操作訪問主庫
- 關鍵業務讀寫都由主庫承擔,非關鍵業務讀寫分離
從主集群就是讀寫分離,分擔了訪問的眼里,但是存儲的壓力沒有解決。
分庫分表
分庫可以將存儲壓力分擔多個服務器上,但是會帶來新的問題,所有的東西變復雜都會有新的問題產生。
- 聯表查詢
join,之前在一個數據庫里面可以用join來進行關聯查詢,但是現在分了多個數據庫,join就用不上了。 - 事務問題
數據庫操作基本都離不開事務,但是現在不同的數據庫事務就不是以前的那個簡單的本地事務了,而是分布式事務,而引入分布式事務也就提高了系統的復雜性。
分表
分表:就是一張表按照一定的規則分解成多個獨立的實體表,系統讀寫時需要根據定義好的規則得到對應的子表名,然后操作它
分表分為垂直分表和水平分表
1) 垂直分表:垂直分表適合表中存在不常用并且占用了大量空間的字段拆分出去。
垂直分表影響就是之前只要一個查詢的,現在需要兩次查詢才能拿到分表之前的完整數據信息。
2) 水平分表:水平分表就是適合表行數很多的情況,一般單表行數超過5000萬就得分表。當一個表行數超過千萬級別的時候,關注一下,如果沒有性能問題就可以在等等看,不要急著分表,因為分表會帶來更過的問題。
看路由 - 按照id,也就是范圍路由。這種分法的好處是容易切,簡單粗暴,以后新增的數據分表都不會影響到之前的數據,之前的數據都不需要移動。
- 哈希路由 就是取幾列哈希一下看看數據哪個庫,比如拿id來做哈希。這種分法好處是分的很均勻,基本上每個表的數據都差不多,但是以后新增的數據又得分表了怎么辦,以前的數據都得動,比較麻煩。
- 搞一張表來存儲路由關系,這種方式也簡單,之后又要分表了之后改改路由表,遷移一部分數據。但是這種方法導致每次查詢都得查詢兩次,并且如果路由表太大了,那路由表又成為瓶頸了。
分庫分表之后面臨的問題 - 事務支持
分庫分表之后,就成了分布式事務了,如果依賴數據庫本身的分布式事務管理功能區執行事務,將付出高昂的性能代價;如果由應用程序去協助控制,形成程序邏輯上的事務,又會造成編程上的負擔。 - 多庫結果集合并(group by order by)
- 跨庫join
分庫分表后,表之間的關聯操作將受到限制,我們無法join位于不同分庫的表,也無法join分表粒度不同的表,結果原本一次查詢能夠完成的業務,可能需要多次查詢才能完成。粗略的解決方法,
全局表:基礎數據,所有庫都拷貝一份。
字段冗余:這樣有些字段就不用join去查詢了。
系統層組裝:分別查詢出所有,然后組裝起來,較復雜。 - 分庫分表方案產品
目前市面上分庫分表中間件想對較多,其中基于代理方式的有Mysql Proxyhe Amoeba,基于Hibernate框架的是Hibernate Shards,基于JDBC的有當當的sharding-jdbc,基于mybatis的類似maven插件式的有蘑菇街的蘑菇街TSharding,通過重寫spring的ibatis template類的Cobar Client。
總結
- 上一篇: 如何快速优化几千万数据量的订单表
- 下一篇: finally中的代码一定会执行吗?