自制單機(jī)日志解決方案 1. Talog 簡介

為什么你又在造輪子?
相信看到標(biāo)題的人第一反應(yīng)肯定就是為什么又是自制?為什么又要造輪子?沒有現(xiàn)成的解決方案可以用嗎?
額...現(xiàn)成的解決方案肯定是有的,相信現(xiàn)在各大公司除了自建日志平臺(tái),用得最多的應(yīng)該是 elk 了吧。16 年的時(shí)候,我花了很多時(shí)間去學(xué)習(xí) elk,當(dāng)時(shí) elk 還被稱作是輕量級(jí)的日志解決方案,我也覺得 elk 是作為日志平臺(tái)的首選。所以后來我在我自己買的云服務(wù)器上嘗試安裝 elasticsearch,我把內(nèi)存配置為最小的 512M,雖然可以跑起來,但是幾分鐘之后就會(huì)掛掉,因?yàn)槲业姆?wù)器只有 1G 內(nèi)存。所以我覺得 elk 不適合于小微項(xiàng)目或者團(tuán)隊(duì),而我一直以來也都是買最破最小的服務(wù)器來自己玩玩,明顯也不適合使用 elk 這種對服務(wù)器有一定要求的日志解決方案。
但是再小的項(xiàng)目也都會(huì)產(chǎn)生日志,每次都上服務(wù)器查看文本日志似乎又不是很方便,所以后來我一直在找真正輕量級(jí)的日志解決方案,時(shí)間過去好幾年,我了解到了 Loki,這個(gè)日志解決方案給我最主要的印象就是只對日志做標(biāo)簽化處理,而不會(huì)做全文本的索引,這看起來就比較輕量化。但是在后續(xù)學(xué)習(xí)文檔的過程中,我發(fā)現(xiàn) Loki 的安裝、配置文檔相當(dāng)簡陋,很難完全明白如何使用,所以我沒能在自己的服務(wù)器上試驗(yàn)一下是否能跑得起來。就這樣我又開始等新的輕量級(jí)日志解決方案出現(xiàn)在我眼中。
2022 年,我在 github 上看到了一個(gè)自稱可以作為 elasticsearch 的輕量級(jí)替代品的項(xiàng)目 Sonic,聽這名字就覺得很快的樣子,而且是用 rust 開發(fā)的,感覺又快又穩(wěn)啊。于是我趕緊翻閱了下文檔,在 協(xié)議文檔 中看到支持的命令竟然只有這么幾個(gè)...我當(dāng)時(shí)在想要是只做得這么簡單,我上我也行。而且這個(gè)項(xiàng)目主要是針對全文檢索,其實(shí)對于日志查詢并不是一個(gè)太好的選擇。當(dāng)時(shí)翻閱著這個(gè)項(xiàng)目的文檔,我突發(fā)奇想:如果我自己做一個(gè)功能像這樣簡單的日志解決方案呢,那憑我一個(gè)人完成度應(yīng)該也能達(dá)到一個(gè)比較令我自己滿意的水平了吧。
于是我就在腦海中開始想自己想要做一個(gè)怎樣的項(xiàng)目,能達(dá)到怎樣的效果,應(yīng)該使用怎樣的方式去實(shí)現(xiàn)。最終我花了差不多兩個(gè)月的時(shí)間完成了 Talog 項(xiàng)目,目前項(xiàng)目基本已達(dá)到我所預(yù)期的效果,當(dāng)然還有待完善。
Talog 是個(gè)怎樣的輪子?
Talog 主要是借鑒了 Loki 將日志標(biāo)簽化的思想,并且會(huì)把具有相同標(biāo)簽的日志存放在同一個(gè)文件中。后續(xù)在查詢?nèi)罩緯r(shí),通過指定標(biāo)簽來獲取對應(yīng)的日志文件,這種方式是簡單高效的,但核心邏輯就是如此簡單。當(dāng)然僅通過標(biāo)簽來查詢?nèi)罩究隙ㄊ遣蛔阋詽M足大部分日志查詢場景的,因此 Talog 還在核心邏輯上增加了一個(gè)擴(kuò)展,后續(xù)會(huì)進(jìn)一步介紹。除了查詢?nèi)罩?,Talog 還能記錄 PageView、Metrics,這兩個(gè)功能在 elk 平臺(tái)中,可以基于 elasticsearch 的數(shù)據(jù),通過 Kibana 的儀表盤功能來實(shí)現(xiàn)。Talog 也是基于底層的標(biāo)簽化日志來實(shí)現(xiàn)這兩個(gè)功能的,主要就是將數(shù)據(jù)視為一條條日志進(jìn)行處理。
Talog 展示



其實(shí)這三個(gè)動(dòng)圖在之前的文章就展示過了,懶得再重新制作了~
Talog 核心原理
在 Talog 中,一條日志可以有多種標(biāo)簽,Talog 會(huì)把標(biāo)簽完全一致的日志存放在同一個(gè)文件中,這個(gè)文件在 Talog 中被稱為 Bucket。

Talog 提供了一個(gè)叫 Index 的概念,以供用戶將同一維度下的 Bucket(日志) 組織起來,這個(gè)維度可以是同一個(gè)項(xiàng)目或同一個(gè)業(yè)務(wù)。Index 會(huì)為每一種標(biāo)簽都建立一個(gè)字典樹 Trie,這個(gè)字典樹由標(biāo)簽的所有枚舉值構(gòu)建而成。


當(dāng)你指定了某個(gè)標(biāo)簽,向 Index 請求查詢相關(guān)日志時(shí),Index 會(huì)找到對應(yīng)標(biāo)簽的 Trie,查詢標(biāo)簽值是否存在于 Trie 中,若存在則將相應(yīng)節(jié)點(diǎn)的所有 Bucket 都取出來,這些 Bucket 所存放的日志即為指定標(biāo)簽的關(guān)聯(lián)日志了。
因此在使用 Talog 時(shí),需要對日志做好細(xì)致的標(biāo)簽化,來保證 Bucket 不會(huì)太大,從而導(dǎo)致日志讀取速度緩慢,以及后續(xù)日志篩選處理效率低下。
最后
以上介紹了 Talog 的大體情況以及核心原理,下一篇文章會(huì)介紹一下 Talog 的日志索引過程。