NO IMAGE

億級資料優化

情況簡介

使用者分析系統以使用者的心跳資料為依據,統計查詢使用者的各種情況。心跳資料很多,經過去重,去無效,資料量還是在2億/月的水平。普通的查詢在這個量級的資料庫上根本查不出來,為此,分表分庫、優化查詢、多執行緒查詢就很有必要了。

分表分庫

對於大資料查詢,我的第一反應就是分表分庫,我之前對分表分庫已經聽的很多了,但自己之前並沒有真的做過分表分庫。我經常說分表分庫,經常聽分表分庫,對分表分庫的技術充滿了興趣,所以這次,我的意見就是上分表分庫。分庫分表就是按一定規則把一張大表的資料切成多個小表,查詢時分組查詢多個小表再把結果集集合起來。

分表其實只是對資料表的資料量的減少。比如一個1億的表,經過分表後,會分成4個千萬級別的表,對於查詢sql,會在千萬級別的表中執行,並把結果合併起來。在億級查詢的時間比千萬級會提高很多,這個就是分表的作用。但是分表僅僅是資料量的減少,並沒有去解決查詢慢的問題,如果一個查詢慢,及時使用分表,它還是很慢。

我們最終用mycat這個資料庫中介軟體來進行分庫分表,mycat啟動後,會開啟一個模擬mysql的服務端,對於插入的sql,它可以按規則自主放入對應的表中,對應查詢的sql,它會自動的去各個資料庫查詢,並自動整合結果。

優化查詢

經過對資料庫的瞭解後,我發現,資料庫查詢的最該優化的地方還是資料庫優化。首先就是

加索引

索引要加給需要查詢的列,對於執行的sql,我們要使用EXPLAIN進行查詢分析,看查詢是否走的索引。

如果查詢返回的資料過多,會導致cpu和記憶體佔用過大,用show profile for query去檢視查詢狀態時,sending data過大時,就可能是返回資料過多。sending data的耗時來源於sending和sort的時間之和,去掉排序,時間也能快很多。還要關注一下limit這裡,比如limit 2000,60它這裡實際會走一個掃描前2000個,如果有條件就比較好了,比如id>2000 limit 1,60這樣其實就好的很多。所以對於返回結果比較大的查詢,引出了第二個策略

切分條件

切分條件就是查詢的時候將條件分的細一些,這樣查出的每段資料都很少一些,limit的時候,掃描也少一些。

多執行緒查詢

既然做了切分條件,那麼多執行緒查詢也是必不可少的。多執行緒查詢再聚合資料,這才能將時間效率提到最高,對與多執行緒,主要還是java後臺做的,多執行緒的常見操作有,

CountDownLatch同步

即在CountDownLatch中,程式碼多執行緒執行,主執行緒掛起,等CountDownLatch的那些多執行緒全部執行完畢後,在去執行主執行緒。

LinkedBlockingQueue/ConcurrentLinkedDeque佇列

LinkedBlockingQueue/ConcurrentLinkedDeque是一個執行緒安全佇列,那個block單詞是鎖的意思,其實就是堵塞的。在這裡的查詢就需要佇列呀,查詢條件是一個list,要保證list的每一個條件查詢一次,不能重複查詢,這裡,就必須要用佇列了。queue有兩個方法add()、pull(),一個出對,一個入隊。