淺談 日訪問量8000萬——App插件升級統計系統

   在上一篇文章中,我們談到了Weex、ReactNative等方案,那麼如何設計一個下載量統計方案呢。

   1.傳統的tomcat + mysql批量寫入更新

   如果數據量不大很好辦,傳統的tomcat處理客戶端上報http數據,通過mysql進行存儲,在數據量較大時,可以通過定時任務批量寫入到mysql。用戶查詢上報數據時,只需要從mysql中存儲即可。

   但是數據量逐漸變大呢,如果是一個超級App怎麼辦?

  2.負載均衡+容器化+阻塞隊列+mysql索引

   前端通過HA負載均衡分發到多個docker上,每個docker有兩個tomcat實例,我們可以通過上百個實例來承載客戶端上報的數據,然後通過一個寫入線程寫入內存阻塞隊列,排隊到一定長度,通過讀取線程批量寫入數據庫,這樣的好處是非阻塞。

   但是這樣有個問題,每次App插件上報時,如果數據庫裏存儲了相關插件數據,就要更新數據,在mysql數據量過大時,更新數據涉及到查找數據,比較困難,在這裏我們可以通過建立索引字段來實現。

  數據量積累到過大,必然涉及分庫分表,多維度查找效率越來越難,問題越來越多。

   3.更新數據通過Hbase

   但是我們發現Hbase scan的效率太低,雖然有Coopressor,但是我們並沒有用過。

   在這裏Hbase的RowKey涉及也是大學問,可以參考openTSDB。

   4.異步化採用Kafka,存儲採用Elasticsearch

   在2的基礎上,我們通過Kafka生產消費實現異步化,在消費到一定長度時,ES批量存儲所有的時間積累數據。

   這裏有個問題,時間積累的數據,可能是同一個用戶uuid發過來的,數據積累越來越大。假設App上報App已經更新的10個插件數據,500個字節,每天上報8000萬次,那麼每天的數據量約爲0.5kb*8000w = 4M*1w=約爲40Gb左右,那麼假設存儲一個月,40Gb*30 = 1.2Tb,一年的數據將達到14.4Tb,數據量雖然很大,但是最大的問題並不是存儲,而是ES Aggregation中的多維度集合計數怎麼辦,ES的計數功能採用了HyperLogLog算法,節約內存,在我親測數據量在1000萬的時候查看多維度的插件升級計數還是ok的,但是上億級別已經超時。那麼怎麼辦?

   我們不能採用時間累積數據的方案,而是通過ES存儲的時候有個唯一ID,再次插入這個唯一ID的數據將覆蓋之前的數據,那麼這個ID我們設計爲 “插件名+用戶uuid”,存儲的數據就是插件的具體數據info,這樣的好處是每個用戶每個插件只能有一份數據,如果只用uuid做這個id值,壞處是,我們後面查找相關插件數據的個數時候,必須要從插件裏過濾。

   這樣的話,如果獨立用戶爲2億,1個插件,那隻能上報2億條數據,如果是50個字節一個插件數據,數據量是0.05kb*1w*1w =0.5kb*1000w = 5GB,固定在5Gb,如果10個插件,固定在50Gb,我們估計一個App中最多100個插件(這已經很多了),那麼只需要500Gb的存儲空間。

  這對ES的查詢來說,壓力並不大。 

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章