沈老師,你好,想請教一個數據庫查詢日誌,前臺頁面顯示的問題。
需求:
(1)按照某些特定檢索條件查詢日誌;
(2)通過前臺Web頁面查詢並顯示相關日誌信息;
(3)檢索需求包含用戶,時間段區間,類型等特定字段;
希望做到:
(1)查詢速度儘可能快;
(2)支持分頁查詢;
目前方案:
日誌信息存儲在Oracle中,根據日期對Oracle做了分區處理,每天生成一個分區表,每個分區表中的數據總量大概在1000W左右。在相關查詢字段例如用戶,類型上建立索引,來滿足不同維度的查詢需求。
潛在問題:
跨分區的查詢,求記錄總數(計算分頁時的查詢),耗時要3-4分鐘,請問有什麼優化方法麼?
==問題描述完==
這個需求還是非常變態的,通常日誌會進行過濾/結構化/彙總,放入數據倉庫,建立業務寬表,寬表上的查詢,一般不會具體查一行一行的記錄。
如果要支持檢索,並一行一行在Web後臺進行展示,至少要解決幾個方面的問題:
(1)存儲問題;
(2)檢索問題;
(3)擴展性問題(數據量擴展,檢索字段擴展);
一、存儲問題
是否可以用關係型數據庫存儲日誌?
如果日誌格式固定,檢索條件固定,是可以的。
例如:
2019-08-11 23:19:20 uid=123 action=pay type=wechat money=12
可以轉化為表:
t_log(date, time, uid, action, type, money)
然後在相關字段上建立索引,以滿足後臺查詢與展示的需求。
數據量太大,怎麼解決?
按照題目描述,日數據量大概在1000W級別,1年的數據量大概在36Y級別。
如果用Oracle存儲,1000W為一個分區表:
一年需要365個分區,跨分區的查詢性能較低,不太合適。
改為1個月一個分區:
單分區3Y記錄,大部分分區無寫操作(插入,修改,刪除),只有索引上的讀操作,讀寫性能基本能抗住。一年12個分區,性能比365個分區好很多。
雖然本例的日誌可以結構化(將日誌轉化表),由於數據量太大,其實關係型數據庫不太適用,可以用適合更大數據量的ES或者Hive來存儲。
二、檢索問題
日誌格式固定,檢索條件固定,如果用關係型數據庫或者Hive存儲,可以在相關字段上建立索引,來滿足查詢需求。
如果用ES來存儲,其內部用倒排表實現,天然支持檢索。
三、擴展性問題
數據量擴展
不管用Oracle,ES還是Hive來存儲,它們的區別只是單實例/單集群存儲容量不一樣,如果數據量無限擴展,本質上的解決方案還是“水平切分”。
需要注意的是,儘量不要使用自帶的“分區表”來擴展,而在業務層自己拆分。
畫外音:《互聯網公司為啥都不用分區表?》。
檢索字段擴展
如果日誌不是標準化的,檢索字段也不是固定的,那就麻煩了,那就變成了也“搜索引擎”的問題。
此時使用ES是更為合適的,不過結合無限的數據量,最終可能需要自己實現存儲於檢索引擎(類似於百度,存儲容量無限,檢索字段不固定)。
畫外音:《“搜索”的原理,架構,實現,實踐!》。
總結:
結合本例,日誌量大,模式固定,建議:
(1)最建議,使用Hive存儲,使用索引的方式實現日誌後臺檢索需求;
(2)如果擴展性要求稍高,可以使用ES實現存儲與檢索,使用水平擴展來存儲更大的數據量;
希望上述思路對星官有幫助,經驗有限,也歡迎大家貢獻更多更好的方案,思路比結論重要。
------------------------------------------------------
閱讀更多 程序員界的彭于晏 的文章