30億日志,檢索+分頁+后臺展示,你是否遇到過更奇葩的需求?
沈老師,你好,想請教一個(gè)數(shù)據(jù)庫查詢?nèi)罩荆芭_頁面顯示的問題。
需求:
- 按照某些特定檢索條件查詢?nèi)罩?
- 通過前臺Web頁面查詢并顯示相關(guān)日志信息;
- 檢索需求包含用戶,時(shí)間段區(qū)間,類型等特定字段;
希望做到:
- 查詢速度盡可能快;
- 支持分頁查詢;
目前方案:
日志信息存儲在Oracle中,根據(jù)日期對Oracle做了分區(qū)處理,每天生成一個(gè)分區(qū)表,每個(gè)分區(qū)表中的數(shù)據(jù)總量大概在1000W左右。在相關(guān)查詢字段例如用戶,類型上建立索引,來滿足不同維度的查詢需求。
潛在問題:
跨分區(qū)的查詢,求記錄總數(shù)(計(jì)算分頁時(shí)的查詢),耗時(shí)要3-4分鐘,請問有什么優(yōu)化方法么?
==問題描述完==
這個(gè)需求還是非常變態(tài)的,通常日志會(huì)進(jìn)行過濾/結(jié)構(gòu)化/匯總,放入數(shù)據(jù)倉庫,建立業(yè)務(wù)寬表,寬表上的查詢,一般不會(huì)具體查一行一行的記錄。
如果要支持檢索,并一行一行在Web后臺進(jìn)行展示,至少要解決幾個(gè)方面的問題:
- 存儲問題;
- 檢索問題;
- 擴(kuò)展性問題(數(shù)據(jù)量擴(kuò)展,檢索字段擴(kuò)展);
一、存儲問題
是否可以用關(guān)系型數(shù)據(jù)庫存儲日志?
如果日志格式固定,檢索條件固定,是可以的。
例如:
- 2019-08-11 23:19:20 uid=123 action=pay type=wechat money=12
可以轉(zhuǎn)化為表:
- t_log(date, time, uid, action, type, money)
然后在相關(guān)字段上建立索引,以滿足后臺查詢與展示的需求。
數(shù)據(jù)量太大,怎么解決?
按照題目描述,日數(shù)據(jù)量大概在1000W級別,1年的數(shù)據(jù)量大概在36Y級別。
- 如果用Oracle存儲,1000W為一個(gè)分區(qū)表:一年需要365個(gè)分區(qū),跨分區(qū)的查詢性能較低,不太合適。
- 改為1個(gè)月一個(gè)分區(qū):單分區(qū)3Y記錄,大部分分區(qū)無寫操作(插入,修改,刪除),只有索引上的讀操作,讀寫性能基本能抗住。一年12個(gè)分區(qū),性能比365個(gè)分區(qū)好很多。
雖然本例的日志可以結(jié)構(gòu)化(將日志轉(zhuǎn)化表),由于數(shù)據(jù)量太大,其實(shí)關(guān)系型數(shù)據(jù)庫不太適用,可以用適合更大數(shù)據(jù)量的ES或者Hive來存儲。
二、檢索問題
日志格式固定,檢索條件固定,如果用關(guān)系型數(shù)據(jù)庫或者Hive存儲,可以在相關(guān)字段上建立索引,來滿足查詢需求。
如果用ES來存儲,其內(nèi)部用倒排表實(shí)現(xiàn),天然支持檢索。
三、擴(kuò)展性問題
1. 數(shù)據(jù)量擴(kuò)展
不管用Oracle,ES還是Hive來存儲,它們的區(qū)別只是單實(shí)例/單集群存儲容量不一樣,如果數(shù)據(jù)量無限擴(kuò)展,本質(zhì)上的解決方案還是“水平切分”。
需要注意的是,盡量不要使用自帶的“分區(qū)表”來擴(kuò)展,而在業(yè)務(wù)層自己拆分。
畫外音:《互聯(lián)網(wǎng)公司為啥都不用分區(qū)表?》。
2. 檢索字段擴(kuò)展
如果日志不是標(biāo)準(zhǔn)化的,檢索字段也不是固定的,那就麻煩了,那就變成了也“搜索引擎”的問題。
此時(shí)使用ES是更為合適的,不過結(jié)合無限的數(shù)據(jù)量,最終可能需要自己實(shí)現(xiàn)存儲于檢索引擎(類似于百度,存儲容量無限,檢索字段不固定)。
總結(jié):
結(jié)合本例,日志量大,模式固定,建議:
- 最建議,使用Hive存儲,使用索引的方式實(shí)現(xiàn)日志后臺檢索需求;
- 如果擴(kuò)展性要求稍高,可以使用ES實(shí)現(xiàn)存儲與檢索,使用水平擴(kuò)展來存儲更大的數(shù)據(jù)量;
【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】