1.1 分
很多技術都運用了分的編程思想,這里來舉幾個例子,這些都是分的思想
-
集中式服務發展到分布式服務
-
從Collections.synchronizedMap(x)到1.7ConcurrentHashMap再到1.8ConcurrentHashMap,細化鎖的粒度的同時依舊保證線程安全
-
從AtomicInteger到LongAdder,ConcurrentHashMap的size()方法。用分散思想,減少cas次數,增強多線程對一個數的累加
-
JVM的G1 GC算法,將堆分成很多Region來進行內存管理
-
Hbase的RegionServer中,將數據分成多個Region進行管理
-
平時開發是不是線程池都資源隔離
2.2 合
很多技術也運用到了合的編程思想,這里舉幾個例子,這些都是合的思想
-
TLAB(Thread Local Allocation Buffers),線程本地分配緩存。避免多線程沖突,提高對象分配效率
-
逃逸分析,將變量的實例化內存直接在棧里分配,無需進入堆,線程結束棧空間被回收。減少臨時對象在堆內分配數量
-
CMS GC算法下,雖然使用標記清除,但是也有配置支持整理內存碎片。如:-XX:UseCMS-CompactAtFullCollection(FullGC后是否整理,Stop The World會變長)和-XX:CMSFullGCs-BeforeCompaction(幾次FullGC之后進行壓縮整理)
-
鎖粗化,當JIT發現一系列連續的操作都是對同一對象反復加鎖和釋放鎖,會加大鎖同步的范圍
-
kafka的網絡數據傳輸有一些數據配置,減少網絡開銷。如:batch.size和linger.ms等等
-
平時開發是不是都個叫批量獲取接口
-
二.分區
本文一切基於MySql InnoDB
說了這么多,接下來說主體,先說分區,因為之前博主寫過一篇MySql分區的博客所以這里不會多費筆墨來寫
2.1 實現方式
具體如何實現上面鏈接里有寫,這里只需記住如果表中存在主鍵或唯一索引時,分區列必須是唯一索引的一個組成部分。
這個是數據庫分的,應用透明,代碼無需修改任何東西。
-
2.3 數據處理
分區表后,提高了MySql性能。如果一張表的話,那就只有一個.ibd文件,一顆大的B+樹。如果分表后,將按分區規則,分成不同的區,也就是一個大的B+樹,分成多個小的樹。
讀的效率肯定提升了,如果走分區鍵索引的話,先走對應分區的輔助索引B+樹,再走對應分區的聚集索引B+樹。
如果沒有走分區鍵,將會在所有分區都會執行一次。會造成多次邏輯IO!
平時開發如果想查看sql語句的分區查詢可以使用explain partitons select xxxxx語句。可以看到一句select語句走了幾個分區
-
三.分庫分表
當一張表隨着時間和業務的發展,庫里表的數據量會越來越大。數據操作也隨之會越來越大。
一台物理機的資源有限,最終能承載的數據量、數據的處理能力都會受到限制。這時候就會使用分庫分表來承接超大規模的表,單機放不下的那種。
區別於分區的是,分區一般都是放在單機里的,用的比較多的是時間范圍分區,方便歸檔。只不過分庫分表需要代碼實現,分區則是mysql內部實現。分庫分表和分區並不沖突,可以結合使用。
-
3.1 實現
3.1.1 分庫分表標准
-
存儲占用100G+
-
數據增量每天200w+
-
單表條數1億條+
3.1.2 分庫分表字段
分庫分表字段取值非常重要
-
在大多數場景該字段是查詢字段
-
數值型
一般使用userId,可以滿足上述條件
3.2 分布式數據庫中間件
分布式數據庫中間件分為兩種,proxy和客戶端式架構。proxy模式有MyCat、DBProxy等,客戶端式架構有TDDL、Sharding-JDBC等。
那么proxy和客戶端式架構有何區別呢?各自有什么優缺點呢?其實看一張圖便可知曉。
proxy模式的話我們的select和update語句都是發送給代理,由這個代理來操作具體的底層數據庫。所以必須要求代理本身需要保證高可用,否則數據庫沒有宕機,proxy掛了,那就走遠了。
客戶端模式通常在連接池上做了一層封裝,內部與不同的庫連接,sql交給smart-client進行處理。通常僅支持一種語言,如果其他語言要使用,需要開發多語言客戶端。
-
-
四.總結
分表和在用途上不一樣,分表是為了承接超大規模的表,單機放不下那種。分區的話則一般都是放在單機里的,用的比較多的是時間范圍分區,方便歸檔。
性能穩定上的話都是一個個子表,差不多,區別應該是分區表是mysql內部實現的,會比分表方案少一點數據交互。