集中式日志分析平台 - ELK Stack - Filebeat 压测

前言

任何一款采集 agent 进行公司内全面推广前都需要进行性能测试以及资源限制功能测试,以保证:

  • 清楚了解性能瓶颈在哪里;
  • 清楚了解数据暴涨时的性能瓶颈在哪里;
  • 清楚了解数据暴涨时的资源限制功能是否生效;

对于 Filebeat 这款号称 golang 编写,性能强于 logstahs-forwarder 的采集 agent,我们也需要这样进行严谨对待。

测试详情

硬件环境和版本

硬件选择虚拟机,6cores + 16GB Mem + 175GB SSD + 1000Mbps 带宽;

  • Filebeat 为 5.2.1 版本,Kafka 为 2.11-0.10.1.1;
  • 172.16.134.3: kafka broker
  • 172.16.134.8: Filebeat

测试方案

  • Filebeat 输出到 console,6 进程写入采集文件,单行数据 247B;
  • Filebeat 输出到 kafka,6进程写入采集文件,单行数据 247B,采用 gzip 压缩;
  • Filebeat 输出到 kafka,限制只使用 1 core,6进程写入采集文件,单行数据 247B,采用 gzip 压缩;
  • Filebeat 输出到 kafka,限制只使用 1 core,6进程写入采集文件,单行数据 1KB,采用 gzip 压缩;
  • Filebeat 输出到 kafka,限制只使用 1 core,6进程写入采集文件,单行数据 5KB,采用 gzip 压缩;

测试配置

Filebeat 配置,输出到 console:

Filebeat.prospectors:
 - input_type: log
  paths:
    - /home/admin/soft/Filebeat-5.2.1-linux-x86_64/logs/test
  document_type: Filebeat
output.console:
  pretty: true

Filebeat 配置,输出到 Kafka:

Filebeat.prospectors:
 - input_type: log
  paths:
    - /home/admin/soft/Filebeat-5.2.1-linux-x86_64/logs/test
  document_type: Filebeat
output.kafka:
  hosts: ["172.16.134.3:9092"]
  topic: '%{[type]}'
  partition.round_robin:
    reachable_only: false
  required_acks: 1
  compression: gzip
  max_message_bytes: 1000000

统计方式

我们开启 Filebeat 的 6060 端口,并使用 python 脚本进行指标采集。
expvar_rates.py,每秒统计出 Filebeat 指标,主要看:

  • libeat.publisher.published_events, avg
  • publish.events, avg
  • libbeat.kafka.published_and_acked_events, avg
    系统指标方面我们主要关注 CPU 使用率,这块使用 top 或者 tsar 都OK。
import requests
import argparse
import time
import curses
import re


def main():
    parser = argparse.ArgumentParser(
        description="Print per second stats from expvars")
    parser.add_argument("--url", default="http://localhost:6060",
                        help="The URL from where to read the values")
    parser.add_argument("--filter", default=None,
                        help="Filter metrics by this search regexp")
    args = parser.parse_args()

    stdscr = curses.initscr()
    curses.noecho()
    curses.cbreak()

    last_vals = {}

    # running average for last 30 measurements
    N = 30
    avg_vals = {}
    now = time.time()

    while True:
        try:
            time.sleep(1.0)
            stdscr.erase()

            r = requests.get(args.url + "/debug/vars")
            json = r.json()

            last = now
            now = time.time()
            dt = now - last

            for key, total in json.items():
                if args.filter is not None:
                    if re.search(args.filter, key) is None:
                        continue

                if isinstance(total, (int, long, float)):
                    if key in last_vals:
                        per_sec = (total - last_vals[key])/dt
                        if key not in avg_vals:
                            avg_vals[key] = []
                        avg_vals[key].append(per_sec)
                        if len(avg_vals[key]) > N:
                            avg_vals[key] = avg_vals[key][1:]
                        avg_sec = sum(avg_vals[key])/len(avg_vals[key])
                    else:
                        per_sec = "na"
                        avg_sec = "na"
                    last_vals[key] = total
                    try:
                        stdscr.addstr("{}: {}/s (avg: {}/s) (total: {})\n"
                                      .format(key, per_sec, avg_sec, total))
                    except Exception, e:
                        raise Exception("curses.addstr fail. Resize the " +
                                        "terminal window or use the filter" +
                                        "option: {}".format(e))
            stdscr.refresh()
        except requests.ConnectionError:
            stdscr.addstr("Waiting for connection...\n")
            stdscr.refresh()
            last_vals = {}
            avg_vals = {}

if __name__ == "__main__":
    main()

测试详情

我们可以通过脚本

time for i in {1..10000000};do echo "${log_message}" >> /home/admin/soft/filebeat-5.2.1-linux-x86_64/logs/test;done;

执行时间得知日志写入速率为 ~ 250K/s。我们可以通过 ls -l /proc/${pid}/fd | grep -v total | wc -l 得知采集单文件的 Filebeat 的文件句柄数为 9,采集 2 个文件的句柄数为 10, 所以基础句柄数为 9,每增加一个采集点,句柄数 + 1。

Case A: Filebeat 输出到 console,6 进程写入采集文件,单行数据 247B;

Step1. 启动 Filebeat (172.16.134.8)

/home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat -c /home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat.yml -httpprof 0.0.0.0:6060 > /home/admin/soft/filebeat-5.2.1-linux-x86_64/logs/filebeat 2>&1 &

Step2. 启动统计脚本

python expvar_rates.py

Step3. 启动 tsar

tsar --cpu --live -i 1

Step4. 写入压测数据(6个进程写入,6千万条日志)

for i in {1..10000000};do echo "2017-03-16T19:21:14+08:00 INFO Non-zero metrics in the last 30s: libbeat.publisher.published_events=2 registrar.states.update=3 libbeat.kafka.call_count.PublishEvents=2 publish.events=3 libbeat.kafka.published_and_acked_events=2 registrar.writes=2" >> /home/admin/soft/filebeat-5.2.1-linux-x86_64/logs/test;done; 

在 6 进程数据写入日志文件时,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.publisher.published_events: 18014.370905/s (avg: 19641.6123106/s) 
publish.events: 21920.7951289/s (avg: 19610.1652594/s)

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
67.3    22.8     0.0     0.0     0.0    90.2 

我们在 top 中可以看到 Filebeat 大致占据了 0.8 cores。
在 6 进程数据写入日志文件后,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.publisher.published_events: 40691.6042823/s (avg: 39300.4436095/s) 
publish.events: 38676.4998717/s (avg: 39370.3604289/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
24.6     2.0     0.2     0.0     0.0    26.9 

我们在 top 中可以看到 Filebeat 大致占据了 1.6 cores。
小结:

  • 6 进程的日志文件写入,应用本身会吃满所有 CPU 资源,此时 Filebeat 采集速率无法跟上数据生成速度,大约为 19K/s,CPU 开销为 0.8 cores;
  • 在 6 千万条日志写入完后,Filebeat 采集数据全速推送到 console 的速率大致为 39K/s,CPU 开销为1.6 cores;
Case B: Filebeat 输出到 kafka,6进程写入采集文件,单行数据 247B,采用 gzip 压缩;

测试步骤和上述一致,区别在于配置文件需要输出到 Kafka。
在 6 进程数据写入日志文件时,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 14125.0820764/s (avg: 16282.8981012/s) 
libbeat.publisher.published_events: 17357.7280373/s (avg: 16419.7944927/s)
publish.events: 16251.4829085/s (avg: 16510.4781086/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
67.9    23.1     0.0     0.0     0.0    91.1  

我们在 top 中可以看到 Filebeat 大致占据了 0.7~0.8 cores。
在 6 进程数据写入日志文件后,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 40614.7704231/s (avg: 39698.759785/s) 
libbeat.publisher.published_events: 40722.3439941/s (avg: 39628.4561631/s) 
publish.events: 38671.5053801/s (avg: 38930.2225183/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
29.2     0.9     0.0     0.0     0.0    30.5

我们在 top 中可以看到 Filebeat 大致占据了 2.0 cores。
小结:

  • 6 进程的日志文件写入,应用本身会吃满所有 CPU 资源,此时 Filebeat 采集速率无法跟上数据生成速度,大约为 16~17K/s,CPU 开销为 0.7~0.8 cores;
  • 在 6 千万条日志写入完后,Filebeat 采集数据全速推送到 Kafka 的速率大致为 39~40K/s,CPU 开销为 2.0 cores;
Case C: Filebeat 输出到 kafka,限制只使用 1 core,6进程写入采集文件,单行数据 247B,采用 gzip 压缩;

测试步骤和上述一致,区别在于配置文件需要输出到 Kafka。
和上述步骤不同的是,启动 Filebeat 时需要 systemd 限制 CPU、句柄数,根据之前的理论,句柄数限制在 100 已经非常够用,CPU 限制在 1 core。
修改 /usr/lib/systemd/system/filebeat.service

[Unit]
Description=Filebeat
Documentation=https://www.elastic.co/guide
After=network.target

[Service]
Type=Simple
ExecStart=/home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat -c /home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat.yml -httpprof 0.0.0.0:6060
ExecStop=/bin/kill -WINCH ${MAINPID}
Restart=always
RestartSec=0
WatchdogSec=1min
LimitNOFILE=100
LimitNPROC=100

[Install]
WantedBy=multi-user.target

执行 reload:

sudo systemctl daemon-reload

对 CPU 进行限制:

sudo systemctl set-property filebeat CPUQuota=100% 

确认是否限制成功:

sudo systemctl show filebeat | grep -E "CPUQuota|LimitNOFILE|LimitNPROC"

有如下输出表示OK:

CPUQuotaPerSecUSec=1s
LimitNOFILE=100
LimitNPROC=100
DropInPaths=/etc/systemd/system/filebeat.service.d/50-CPUQuota.conf

在 6 进程数据写入日志文件时,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 19844.7720225/s (avg: 16837.4773012/s) 
libbeat.publisher.published_events: 18030.6556898/s (avg: 16764.6918644/s) 
publish.events: 15644.7977205/s (avg: 16910.2166832/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
79.2    11.3     0.0     0.0     0.0    90.6

我们在 top 中可以看到 Filebeat 大致占据了 0.7 ~ 0.8 cores。
在 6 进程数据写入日志文件后,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 18337.7079915/s (avg: 18923.3234652/s) 
libbeat.publisher.published_events: 20376.3669159/s (avg: 18848.5970484/s) 
publish.events: 20323.8510655/s (avg: 18914.4681101/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
14.4     0.5     0.0     0.0     0.0    15.2 

我们在 top 中可以看到 Filebeat 大致占据了 1.0 cores,限制生效。
小结:

  • 6 进程的日志文件写入,应用本身会吃满所有 CPU 资源,此时 Filebeat 采集速率无法跟上数据生成速度,大约为 16~17K/s,CPU 开销为 0.7~0.8 cores;
  • 在 6 千万条日志写入完后,Filebeat 采集数据全速推送到 Kfaka 的速率大致为 18~19K/s,CPU 开销为 1.0 cores;
Case D: Filebeat 输出到 kafka,限制只使用 1 core,6进程写入采集文件,单行数据 1KB,采用 gzip 压缩;

在 6 进程数据写入日志文件时,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 11954.3900946/s (avg: 13256.2128845/s) 
libbeat.publisher.published_events: 14084.2447431/s (avg: 13241.4999292/s)
publish.events: 11998.8163015/s (avg: 13205.6630096/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
85.4     5.0     0.1     0.0     0.0    90.5

我们在 top 中可以看到 Filebeat 大致占据了 0.75 ~ 0.9 cores。
在 6 进程数据写入日志文件后,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 14257.5686603/s (avg: 15411.161373/s)
libbeat.publisher.published_events: 16297.7185003/s (avg: 15475.6613026/s)
publish.events: 16292.4519132/s (avg: 15545.8192101/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
14.5     0.6     0.0     0.0     0.0    15.3

我们在 top 中可以看到 Filebeat 大致占据了 1.0 cores,限制生效。
小结:

  • 6 进程的日志文件写入,应用本身会吃满所有 CPU 资源,此时 Filebeat 采集速率无法跟上数据生成速度,大约为 13~14K/s,CPU 开销为 0.75~0.9 cores;
  • 在 6 千万条日志写入完后,Filebeat 采集数据全速推送到 console 的速率大致为 15~16K/s,CPU 开销为 1.0 cores;
Case E: Filebeat 输出到 kafka,限制只使用 1 core,6进程写入采集文件,单行数据 5KB,采用 gzip 压缩;

在 6 进程数据写入日志文件时,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 5853.48499116/s (avg: 6142.33474568/s) 
libbeat.publisher.published_events: 6052.63549446/s (avg: 6066.04758752/s) 
publish.events: 5979.76512269/s (avg: 6063.20532399/s) 

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
89.2     2.2     0.1     0.0     0.0    91.5 

我们在 top 中可以看到 Filebeat 大致占据了 0.7 ~ 0.75 cores。
在 6 进程数据写入日志文件后,我们在开启 python 统计脚本的窗口得到如下稳定的统计数据:

libbeat.kafka.published_and_acked_events: 6110.43003481/s (avg: 7030.51292764/s)
libbeat.publisher.published_events: 8144.14448334/s (avg: 7030.65813196/s) 
publish.events: 6112.44754178/s (avg: 6977.26856088/s)

我们在 tsar 看到的统计数据为:

user     sys    wait    hirq    sirq    util
12.1     0.5     0.1     0.0     0.0    12.9 

我们在 top 中可以看到 Filebeat 大致占据了 0.9 cores,未达到限制。
小结:

  • 6 进程的日志文件写入,应用本身会吃满所有 CPU 资源,此时 Filebeat 采集速率无法跟上数据生成速度,大约为 6K/s,CPU 开销为 0.7~0.75 cores;
  • 在 6 千万条日志写入完后,Filebeat 采集数据全速推送到 Kafka 的速率大致为 7K/s,CPU 开销为 0.9 cores;

测试结论

Situation Thoughput(K/s) CPU(Cores)
输出到Console, 应用写入+FB采集,247B 19 0.8
输出到Console, FB采集,247B 39 1.6
输出到Kafka, 应用写入+FB采集,247B 16.5 0.75
输出到Kafka, FB采集,247B 39.5 2.0
输出到Kafka, 应用写入+FB采集,247B,1Core 16.5 0.75
输出到Kafka, FB采集,247B,1Core 18.5 1.0
输出到Kafka, 应用写入+FB采集,1KB,1Core 13.5 0.83
输出到Kafka, FB采集,1KB,1Core 15.5 1.0
输出到Kafka, 应用写入+FB采集,5KB,1Core 6 0.73
输出到Kafka, FB采集,5KB,1Core 7 0.9

A. FB 全力采集 247B 数据(真实环境类似日志长度),速率为 ~ 40K/s,CPU 开销为 2 cores;

B. FB 在 CPU 限制 1 cores 情况下,采集 247B 数据速率为 ~ 20K/s,可以认为单核采集速率为 ~ 20K/s/core;

C. 日志单行数据越大,吞吐越小,5KB 每行已经非常夸张,即使如此,没有压缩的情况下带宽消耗 35MBps,gzip 压缩率一般为 0.3~0.4,占用带宽为 10.5~14MBps,对于千兆网卡来说压力较小;

在生产的情况下,即使有 gzip 压缩,也必须有降级措施,以避免日志因异常暴涨情况下的网络带宽占用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容