"本文主要講解了fluentd的爲什麼選用fluentd作爲核心組件,它的優勢是什麼"
1、前言
我是標題黨,所謂佛無南北,架構沒有好壞之分,只有是否合適的區別,比如常常被人詬病的單體架構,耦合性高,可擴展性低。事實上,特別對於有成本考慮的初創企業,單體架構常常是最佳選擇,因爲簡單,它能快速幫助企業完成產品和市場的高度契合,但是當企業的用戶規模擴大後,這樣的架構往往又成爲隱患。話又說回來了,沒有一個可以適用於所有的產品和規模的完美架構,任何架構只能完成特定的一組目標,或者一系列的需求和條件。隨着時間的推移,爲了與時俱進,任何產品或者服務功能需要完善,架構也一樣,那些在普通用戶規模下的架構很少能在100倍規模下有效。
fluentd也一樣,當存在多種多樣數據源和存儲目標時比較合適,因爲它支持500+插件進行日誌輸入輸出,特別是大多數數據源都是自定義的應用,你會發現fluentd和這些應用結合起來的能力比其它日誌收集框架要簡單有效。
2、性能
fluentd的性能已經在各個領域得到了證明,其最大的用戶可以從50000+服務器中收集日誌,每天處理5TB的數據,峯值時每秒可以處理5萬行數據,可以在客戶端和服務端分別部署,客戶端收集日誌發送到服務端(目前大多采用fluent-bit作爲客戶端)
3、架構
fluentd是一個開源的數據收集器,它統一了數據的收集和使用。它的架構有以下特點(看上圖說話):
使用json統一日誌格式
可插拔的架構(靈活的插件功能,允許擴展功能)
最少資源佔用(C+Ruby編寫)
可靠性高
4、社區支持
fluentd目前由CNCF社區維護,大名鼎鼎的雲原生計算基金會,雲時代的操作系統Kubenetes就是由它發起和維護的。社區活躍,詳情見下圖:
5、安裝使用
安裝使用簡單,支持多種安裝方式,具體可以參考官網安裝方式,最簡單的方式就是直接通過鏡像運行,使用方式,如下所示:
1. 拉取鏡像
docker pull fluent/fluentd:v1.6-debian-1
2. 創建收集配置
# /tmp/fluentd.conf
<source>
@type http
port 9880
bind 0.0.0.0
</source>
<match **>
@type stdout
</match>
3. docker運行,啓動fluentd
$ docker run -p 9880:9880 -v $(pwd)/tmp:/fluentd/etc -e FLUENTD_CONF=fluentd.conf fluent/fluentd:v1.6-debian-1
2019-08-21 00:30:37 +0000 [info]: parsing config file is succeeded path="/fluentd/etc/fluentd.conf"
2019-08-21 00:30:37 +0000 [info]: using configuration file: <ROOT>
<source>
@type http
port 9880
bind "0.0.0.0"
</source>
<match **>
@type stdout
</match>
</ROOT>
2019-08-21 00:30:37 +0000 [info]: starting fluentd-1.6.3 pid=6 ruby="2.6.3"
2019-08-21 00:30:37 +0000 [info]: spawn command to main: cmdline=["/usr/local/bin/ruby", "-Eascii-8bit:ascii-8bit", "/usr/local/bundle/bin/fluentd", "-c", "/fluentd/etc/fluentd.conf", "-p", "/fluentd/plugins", "--under-supervisor"]
2019-08-21 00:30:38 +0000 [info]: gem 'fluentd' version '1.6.3'
2019-08-21 00:30:38 +0000 [info]: adding match pattern="**" type="stdout"
2019-08-21 00:30:38 +0000 [info]: adding source type="http"
2019-08-21 00:30:38 +0000 [info]: #0 starting fluentd worker pid=13 ppid=6 worker=0
2019-08-21 00:30:38 +0000 [info]: #0 fluentd worker is now running worker=0
2019-08-21 00:30:38.332472611 +0000 fluent.info: {"worker":0,"message":"fluentd worker is now running worker=0"}
4. 發送HTTP請求
$ curl -X POST -d 'json={"json":"message"}' http://localhost:9880/sample.test
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
775a8e192f2b fluent/fluentd:v1.6-debian-1 "tini -- /bin/entryp…" About a minute ago Up About a minute 5140/tcp, 24224/tcp, 0.0.0.0:9880->9880/tcp tender_leakey
$ docker logs 775a8e192f2b | tail -n 1
2019-08-21 00:33:00.570707843 +0000 sample.test: {"json":"message"}
其它安裝和使用方式可參照如下鏈接:
Kubernetes集羣環境下fluentd日誌收集方案介紹
6、線上實踐
如上圖所示,在各個節點上以DaemonSet方式部署fluent-bit,fluent-bit在各個節點上收集事件、日誌等信息,收集完成後發送到fluentd進行統一彙總、過濾、存儲處理。
示例:
fluentd指令配置信息:
<source>
@type forward
port 24224
</source>
# http://this.host:9880/myapp.access?json={"event":"data"}
<source>
@type http
port 9880
</source>
<match nginx*> #匹配有tag爲mem的類型
@type stdout #匹配成功直接標準輸出
</match>
# Match events tagged with "myapp.access" and
# store them to /var/log/fluent/access.%Y-%m-%d
# Of course, you can control how you partition your data
# with the time_slice_format option.
<match tbsm*>
@type file
path /home/logs/${tag}/${tag}
append true
<format>
@type single_value
message_key log
add_newline true
</format>
<buffer tag,time>
@type file
# timekey 5m 每隔5分鐘形成一個日誌文件
# timekey_wait 1m 生成等待時間1分鐘
chunk_limit_size 50M
# 每隔1分鐘寫一次日誌
flush_interval 1m
flush_at_shutdown true
flush_mode interval
</buffer>
</match>
以上能夠滿足把集羣節點,各個服務的日誌進行集中到fluentd節點上進行存儲。目前上述指令配置能夠把原來各個節點上的日誌原封不動的集中到fluend所在服務器,當然你也可以對日誌進行處理,比如json格式、添加時間戳、tag標籤等。那麼日誌又是如何傳遞到fluentd服務呢?
如下所示fluent-bit配置:
[SERVICE]
Flush 1
Daemon ON
Log_Level debug
[INPUT]
Name tail
Path /home/logs/tbsms1/tbsms1.log
Db /tmp/tbsms1.db
Db.sync Full
Tag tbsms1
[INPUT]
Name tail
Path /home/logs/tbsms2/tbsms2.log
Db /tmp/tbsms2.db
Db.sync Full
Tag tbsms2
[INPUT]
Name tail
Path /home/logs/tbsms3/tbsms3.log
Db /tmp/tbsms3.db
Db.sync Full
Tag tbsms3
[INPUT]
Name tail
Path /home/logs/tbsms4/tbsms4.log
Db /tmp/tbsms4.db
Db.sync Full
Tag tbsms4
[INPUT]
Name tail
Path /home/logs/tbsms5/tbsms5.log
Db /tmp/tbsms5.db
Db.sync Full
Tag tbsms5
[OUTPUT]
Name forward
Match *
Host 12.18.1.6
Port 24224
如上所示就可以把各個服務所在日誌路徑下的日誌信息發送到fluentd,當然,你可能會說,當我的服務出現問題的時候,我不僅會查看服務日誌的信息,還會查看當前機器所在節點的內存、cpu等監控信息。fluent-bit也是支持的,具體可以參考:
輕量級日誌收集轉發 | fluent-bit外部插件詳解(三)
7、問題總結
1. 如上示例所示,在使用的過程中,會發現緩存路徑${tag}沒有被替換掉,如下所示:
drwxr-xr-x 3 root root 4096 Feb 14 17:01 logs
drwxr-xr-x 4 root root 4096 Feb 14 17:41 ${tag}
但是當緩存中的數據刷新到file中之後,file中的數據以及tag是正常替換的。個人覺得這是fluentd的一個可以接受的bug。
2. fluent-bit日誌收集過程中出現如下文件被跳過問題如何處理?
2020/01/20 11:37:55] [debug] [in_tail] file=/home/logs/server/server.2019-12-17.log read=32767 lines=0
[2020/01/20 11:37:55] [debug] [in_tail] file=/home/logs/server/server.2019-12-18.log read=32767 lines=0
[2020/01/20 11:37:55] [error] [in_tail] file=/home/logs/server/server.2019-12-16.log requires a larger buffer size, lines are too long. Skipping file.
[2020/01/20 11:37:55] [error] [in_tail] file=/home/logs/server/server.2019-12-17.log requires a larger buffer size, lines are too long. Skipping file.
添加Buffer_Chunk_Size和Buffer_Chunk_Size,其中Buffer_Chunk_Size默認是32Kb,如果一行數據的長度大於這個值,可能會出現如上錯誤,其中Buffer_Max_Size默認情況下跟Buffer_Chunk_Size保持一致。當然你也可以配置自動跳過過長數據行。
[INPUT]
Name tail
Path /home/logs/server/*.log
Db /tmp/ng.db
Db.sync Full
Tag nginx-log
Buffer_Chunk_Size 320KB
Buffer_Max_Size 520KB
3. 生成如下所示大量日誌文件,而我只想每天生成一個文件。如何配置?
# append false
file.20140608.log_0
file.20140608.log_1
file.20140609.log_0
file.20140609.log_1
在fluentd配置文件中添加append true配置即可解決,按照指定時間生成,如下所示:
# append true
file.20140608.log
file.20140609.log
4. 如何把節點日誌從各個節點轉發到其中一臺機器?
在服務端fluentd配置source,其中source: 數據源配置,可接受log-tail、http、tcp、udp等方式數據如下所示:
<source>
@type forward
bind "0.0.0.0"
port 24222
</source>
在fluent-bit客戶端配置forward,如下所示:
[OUTPUT]
Name forward
Match *
Host 12.18.71.14
Port 24222
8、本文總結
本文主要簡單介紹fluent-bit&fluentd優勢以及在日誌收集過程中的總結和心得。如果有用,可以關注、後臺回覆【pdf】獲得詳細文檔。
推薦
Kubernetes中如何使用ClusterDNS進行服務發現?
從Ice到Kubernetes容器技術,微服務架構經歷了什麼?
原創不易,隨手關注或者”在看“,誠摯感謝!