mysql - 海量日志數據如何處理統計?
問題描述
項目需要做一個dashboard圖表網站,展示日志的相關統計信息。這個頁面圖表很多,一次性會加載出很多數據。
日志表有很多種,都是一些入侵攻擊日志、惡意站點訪問日志等等,需要統計出當前時間、過去24小時、過去一周被攻擊主機個數、惡意站點數(這是其中兩個需求)等等數據。
比如被攻擊主機個數,需要查多張數據表,然后統計出這個數據。
日志存儲在PostgreSQL里面,已經基于時間做了分表,但是每天的的日志量都在100W以上。
寫入數據庫的模式是隨時從其他的系統中寫入。
根據這個應用場景,如果設計這個后端統計呢?還請大神提供一點思路,謝謝。
問題解答
回答1:雖然是一個PostgreSQL的問題,但是打了各種數據庫標簽。那么我就從MongoDB和NoSQL的角度說說這個問題。因為一些情況不是特別清楚,基于自己的假設來回答,如果有和你情況不符的地方再提出來。數據庫的日常應用無非OLAP和OLTP兩大類,你的應用是一個比較典型的OLAP應用。通常OLAP的特點是對時效性的要求不是非常高,對系統資源占用比較重。你沒有提對時效性要求到底有多高,還有你們數據的寫入模式是怎樣的。每天某個時間批量導入?或是隨時從其他系統寫入?不管怎樣,還是有一些通用的辦法來應對的。以下是無論使用哪種數據庫都可以做的一些事情:
預聚合從你的描述來看這是個比較典型的時序數據,過去的數據是不會變的。所以可以在每天結束時把這一天的數據先聚合好,某年某月某日有多少次攻擊多少次惡意訪問之類。如果要查一段時間的,則可以把已經按天統計好的數據再聚合一次。比如一個月的就是30條數據再次聚合,這比30x100w=3000w條數據的聚合要輕松很多。如果你的統計粒度需要比天還小,那就要看具體小到什么程度。如果是精確到時,那我可能還是會考慮按小時預聚合,這樣統計比如過去30天的數據,就會有30x24=720條數據,也在接受范圍內。但是如果統計范圍允許到年,則有365x24=8760,情況就不是很樂觀了。當然如果需要精確到分鐘,那又是更麻煩的事情。但即使這樣,預聚合仍然能有效減少數據量從而降低運算所需的時間和資源。為了解決小粒度聚合的問題,實際應用中可能需要進行多個層次的預聚合。比如按月,按天,按時,按分分別聚合好,這樣在需要某分鐘到某分鐘的數據時,可以把大粒度的范圍通過月、天、時先消化掉,剩下的兩頭零碎部分再用時、分鐘處理,這樣最大程度上減小需要聚合的數據量。
索引優化無論使用哪種數據庫,索引優化都是很重要的步驟。按上述方法預聚合后,各種時間因素肯定都是需要在索引中的。如果在時間基礎上還需要對某個主機或域名等篩選,則最好是有這些字段的聯合索引。具體問題具體分析,這個還需要你根據自己的表結構和查詢去優化。
讀寫分離無論怎么優化,OLAP對資源的占用都是不能忽略的。如果你的數據是實時寫入,聚合期間很容易受到I/O瓶頸的影響。所以最好是把接受數據和分析數據的結點分開。
安利時間說說如果使用MongoDB還有哪些事情可以做。
分片。水平擴展是NoSQL的特色之一,理論上所需時間和結點數量成反比。而數據量的增長在分布式環境中也不是一個問題。
Tag Aware Sharding。MongoDB分片的特色,可以把舊數據自動歸集到容量大,但是性能相對差的硬件上,這樣讓熱數據始終保持在性能較好的機器上達到更好的效果。
天然的讀寫分離和高可用。復制集本身就可以實現讀寫分離和高可用。相信這兩個特性對任何應用都是很有意義的。
最后還是要提醒一點,理論歸理論,沒有一個方案是完美的,實際應用時肯定還會遇到各種各樣奇怪的問題。編程是一項創造性的工作,需要你自己在實踐中不斷尋找最優的解決方案,在實踐中成長。
回答2:1、個人感覺按天分區比較好,為了提升性能,統計SQL不要直接查詢父表,而是將子表進行 union 統計。2、另一點是合理設計索引;
回答3:沒做過,覺得可以用定時器然放到redis里,現查的話確實太慢。多個查詢條件都加上索引會好些吧
回答4:這個日志數據處理是主業還是副業?
如果是主業,那就要學習下 @Mongoing中文社區 的方案,尤其是時序數據進行預處理的概念。
如果是副業,那直接上 ELK 套件就好了,投入低見效快。
相關文章:
1. 如何修改phpstudy的phpmyadmin放到其他地方2. java 排序的問題3. 我的html頁面一提交,網頁便顯示出了我的php代碼,求問是什么原因?4. 網絡傳輸協議 - 以下三種下載方式有什么不同?如何用python模擬下載器下載?5. angular.js - Angular路由和express路由的組合使用問題6. 我在centos容器里安裝docker,也就是在容器里安裝容器,報錯了?7. tp6表單令牌8. 老哥們求助啊9. php - mysql中,作為主鍵的字段,用int類型,是不是比用char類型的效率更高?10. django - 后臺返回的json數據經過Base64加密,獲取時用python如何解密~!
