二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • 最佳实践

    • 运维最佳实践

      • 一句话经验
      • 基于CNAME解析实践的域名优雅方案
      • 如何配置历史命令中有详细的时间戳
      • 建设一个运维外挂的最佳实践
      • 关于打包压缩几种格式(gzip,bzip2,xz)的试验对比
      • 利用谷歌浏览器自定义agent监听日志来调试服务
      • fdisk,parted使用非交互式方式对磁盘进行分区操作
      • GitLab部署的最佳实践
      • GitLab全局搜索之SourceGraph
      • vector实践-性能吊打logstash
        • 0. 前言
          • 0.1 vector 是什么
          • 0.2 为什么用 vector
        • 1. 安装部署
          • 1.1 使用 docker-compose 安装 vector
          • 1.2 vector 配置文件
          • 1.2.1 来源(sources)
          • 1.2.2 变换[可选](transforms)
          • 1.2.2.1 remap
          • 1.2.2.2 filter
          • 1.2.3 水槽(sinks)
        • 2. 实践
          • 2.1 将结果输出到 console
          • 2.2 多配置文件启动
          • 2.3 多 topic 使用正则匹配
          • 2.4 索引使用日志中的字段值作为索引名称
          • 2.5 查看 vector 各任务的处理情况
          • 2.6 vector 更加详细的 metrics 指标
          • 2.7 vector 的自动均衡 kafka 消费[重要]
          • 2.8 自适应并发请求
          • 2.9 性能效果对比[重要]
        • 3. 小结
      • 规范编码之利用pre-commit给项目添加提交前检查
      • CMDB平台建设指南
      • 用上赛博菩萨CNB,咱直接起飞
    • 成本优化实践

  • 迎刃而解

  • Nginx

  • Php

  • Zabbix

  • AWS

  • Prometheus

  • Grafana

  • Loki

  • CentOS

  • Supervisord

  • Systemd

  • Docker

  • Docker-Compose

  • Rancher

  • Ansible

  • OpenLdap

  • GitLab

  • GitHub

  • Etcd

  • Consul

  • RabbitMQ

  • Kafka

  • Mysql

  • MongoDB

  • OpenVPN

  • Kvm

  • VMware

  • 配置文件详解

  • Other

  • 运维观止
  • 最佳实践
  • 运维最佳实践
lius
2022-03-22
目录

vector实践-性能吊打logstash

文章发布较早,内容可能过时,阅读注意甄别。

# 0. 前言

简单来说 vector 扮演着类似 logstash 的角色,但有着比 logstash 强悍太多的性能、简单明了的配置文件、强大的数据处理函数、智能均衡 kafka 分区消费等等!下面请跟随笔者的脚步,对 vector 实践一番吧。

# 0.1 vector 是什么

vector 是什么?以下描述翻译自 vector 官网:https://vector.dev (opens new window)

Vector 是一种高性能的可观察性数据管道,可以收集、转换所有日志、指标和跟踪信息( logs, metrics, and traces),并将其写到您想要的存储当中;Vector 可以实现显着的成本降低、丰富的数据处理和数据安全;且开源,比所有替代方案快 10 倍。
1

简单来说,它扮演着类似 logstash 的角色,但有着比 logstash 强悍太多的性能、简单明了的配置文件、强大的数据处理函数、智能均衡 kafka 分区消费等等;在这些特性中,性能直接关乎成本,相信这是每一家公司都会重点关注的;而从官方介绍中我们已经可以窥探一二,以下是官网给出的一些实践数据:

企业微信截图_05a601d3-7b3f-4952-b647-8ec8af14bbb1

image-20220322205250675

# 0.2 为什么用 vector

如果说官方有自卖自夸之嫌,那么我给出自身实践的数据以供参考:

本人所在公司每天产生约 15T 的日志量,在公司日志架构中 logstash 起着这样的作用:从 kafka 中消费数据,然后进行清洗、格式转换,最终写入 elasticsearch;公司一共有 34 台 16c64g 规格的 logstash 机器,然而这样的高配集群在晚高峰的时候会显得很吃力,每晚必定会报一堆 kafka 堵塞的告警;经过调研决定使用 vector 替换 logstash,最终只用了 10 台 16c16g 的机器便完成替换,并且之后再也没有报过 kafka 堆积告警!

# 1. 安装部署

官方提供了安装包、docker 等多种安装方式,这里我们使用 docker 安装等方式来进行演示

# 1.1 使用 docker-compose 安装 vector

准备好 docker-compose.yaml 文件

version: '3'
services:
  vector:
    image: timberio/vector:latest-alpine        # 镜像
    container_name: vector                      # 容器名
    volumes:
      - /data/vector/config/:/etc/vector/       # 挂载配置文件
      - /etc/localtime:/etc/localtime           # 跟宿主机时区保持一致
    ports:
      - 9598:9598                               # metrics信息暴露端口,后面会讲到
#    environment:                               # 开启DEBUG模式,这里不开启
#      VECTOR_LOG: debug
    entrypoint: "vector -c /etc/vector/*.toml -w /etc/vector/*.toml"    # 启动命令
    restart: always
1
2
3
4
5
6
7
8
9
10
11
12
13
14

然后在 docker-compose.yaml 文件所在目录执行以下命令即可启动 vector:

docker-compose up -d
1

使用 docker logs -f vector 可以看到一些信息,如果 vector 无法启动一般先从这里获取报错信息

# 1.2 vector 配置文件

在上述 docker-compose.yaml 中,我们挂载了本地准备好的配置文件,接下来我们便来讲一讲配置文件一般如何配置;在此之前我们大概讲一讲配置文件的组成,大概可以分为这么几个模块:

tips:注意,以下任何模块(source、transforms、sinks)都可以配置多个元素,但是要保证不能同名

# 1.2.1 来源(sources)

即 vector 的数据来源,它支持文件、kafka、http、各类 metrics 等等数据源,详细请看:https://vector.dev/docs/reference/configuration/sources/ (opens new window),各类数据源均可在文档中找到配置方式,这里我们使用 kafka 演示:

[sources.kafka-nginx-error]     # “数据源”名称
type = "kafka"      # 类型
bootstrap_servers = "10.xxx.xxx.xxx:9092,10.xxx.xxx.xxx:9092"       # kafka链接地址
group_id = "consumer-group-name"        # 消费组id
topics = [ "^(prefix1|prefix2)-.+" ]        # topic,支持正则
1
2
3
4
5

# 1.2.2 变换[可选](transforms)

如果原始数据足够完美无需任何处理,那么这一块可以忽略,但是实际上大部分情况下还是需要这一步的,这里我们讲几个最常用的“变换”,详细请看:https://vector.dev/docs/reference/configuration/transforms/ (opens new window)

# 1.2.2.1 remap

remap 在 vector 中使用 VRL(Vector Remap Language,一种面向表达式的语言,旨在以安全和高性能的方式处理可观察性数据)来实现,这里我们看一看公司使用 vector 处理 nginx 错误日志的配置:

[transforms.remap-nginx-error]      # “变换”名称
  type = "remap"        # 类型
  inputs = ["kafka-nginx-error"]        # 输入,这里的输入自然是上一层的“来源”
source = '''        # 正式开始处理
  . = parse_json!(.message)     # 首先将每一条错误日志解析成json,message的值就是从kafka中读取到的原始值
  del(.@metadata)               # 删除Vector自动携带的一些信息
  .parse = parse_nginx_log!(.message, "error")      # 解析nginx错误日志
'''
1
2
3
4
5
6
7
8

可以看到,在上述处理过程中,只是用了 parse_json、del、parse_nginx_log 三个函数便将错误日志处理完成,实际上解析 nginx 错误日志是一个非常困难的事情,因为 nginx 错误日志的格式不固定,我们很难通过通用的步骤来指定字段、取值,而 Vector 自带来解析 nginx 错误日志函数,一行代码搞定!我们可以对比之前使用 logstash 时的处理方式:

grok {
    match => [
        "message", "(?<time>\d{4}/\d{2}/\d{2}\s{1,}\d{2}:\d{2}:\d{2})\s{1,}\[%{DATA:err_severity}\]\s{1,}(%{NUMBER:pid:int}#%{NUMBER}:\s{1,}\*%{NUMBER}|\*%{NUMBER}) %{DATA:err_message}(?:,\s{1,}client:\s{1,}(?<client_ip>%{IP}|%{HOSTNAME}))(?:,\s{1,}server:\s{1,}%{IPORHOST:server})(?:, request: %{QS:request})?(?:, host: %{QS:client_ip})?(?:, referrer: \"%{URI:referrer})?",
        "message", "(?<time>\d{4}/\d{2}/\d{2}\s{1,}\d{2}:\d{2}:\d{2})\s{1,}\[%{DATA:err_severity}\]\s{1,}%{GREEDYDATA:err_message}"]
}
1
2
3
4
5

类似的处理函数还有很多,这里不一一列举!

# 1.2.2.2 filter

很多时候从数据源采集过来的数据我们并不是全部都需要,filter 顾名思义便是用来解决这一问题的,下面的配置也很好理解:包含 spanID 字段的数据才保留,不包含的丢弃

[transforms.filter-jaeger-span]
  type = "filter"
  inputs = [ "remap-ssd" ]
  condition = "exists(.spanID) == true"
1
2
3
4

# 1.2.3 水槽(sinks)

可以理解为数据往哪发送,它支持 console(如果是 docker 启动直接打到 docker log 中)、elasticsearch、kafka、vector、http 等等,详细请看:https://vector.dev/docs/reference/configuration/sinks/ (opens new window),这里使用 elasticsearch 来演示

[sinks.elasticsearch-ssd]       # “水槽”名称
  type = "elasticsearch"        # 类型
  inputs = [ "remap-ssd" ]      # 输入,这里的输入是上一层的“变换”名称
  endpoint = "http://10.xxx.xxx.xxx:9200"       # 输出的链接地址
  bulk.index = "{{ project_name }}-{{ env }}-%Y-%m-%d"      # 索引名称,这里看到我们使用了日志当中的字段作为变量、以及日期来作为索引名称
1
2
3
4
5

申明

原创文章eryajf,未经授权,严禁转载,侵权必究!此乃文中随机水印,敬请读者谅解。

Copyright 二丫讲梵 (opens new window) 版权所有

# 2. 实践

经过以上介绍,相信你已经可以搞定单个日志的 vector 配置,但是实际使用场景中,会有太多日志,而且各个部门的日志格式也不尽相同,所以实际使用场景中需要用到一些实用技巧,这里列举几个比较典型的

# 2.1 将结果输出到 console

这是我们调试时的利器,我们经常需要掌握我们拿到了什么样的数据,或者了解我们将要写入下游的数据是否符合我们的预期:

[sinks.console]
  type = "console"
  inputs = [ "remap-ssd" ]
  encoding.codec = "json"		# 可选json 或者 text
1
2
3
4

# 2.2 多配置文件启动

实际上聪明的你已经发现,在上文介绍 docker-compose 中,已经使用了该配置

vector -c /etc/vector/*.toml -w /etc/vector/*.toml
1

这样我们便可以给多个日志配置相应的配置文件,最好使用 git 管理,部署时直接 pull 下来,然后所有配置文件一起启动即可;这里还是用到了-w 参数,意思是关注配置文件中的更改,并相应地重新加载;再次提醒:即使是多个配置文件,在同一个 vector 实例中各阶段的命名也不能重名

# 2.3 多 topic 使用正则匹配

各个部门可能对应的统一过日志格式,他们的处理方式可能都一样,这样我们可以在“来源”中指定消费同一类 topic

topics = [ "^(prefix1|prefix2)-.+" ]
1

# 2.4 索引使用日志中的字段值作为索引名称

topic 可以使用正则消费多个 topic,但是我们不能把这些日志一起打到同一个索引中,如果各部门日志格式统一的话,可以使用日志中的字段值作为变量名称,使用变量的方式就是,此外还可以使用%Y、%m、%d 分别表示年、月、日,这是一种很好的日志索引管理方式

bulk.index = "{{ project_name }}-{{ env }}-%Y-%m-%d"
1

# 2.5 查看 vector 各任务的处理情况

在 vector 启动之后,我们可能会关心各任务的处理情况,我们只需要在某个配置文件中(或者单独创建一个配置文件)加入以下配置,让 vector 启动时加载该配置文件,便能以命令行的方式实时查看各任务的处理情况

[api]
  enabled = true
1
2

然后执行以下命令即可:

docker exec -it vector sh
vector top
1
2

企业微信截图_76c51776-ab4f-4251-8060-ff7a873e9025

# 2.6 vector 更加详细的 metrics 指标

vector 提供了详细的自身指标供我们查看,不过截止目前,该功能还是测试版,我们可以先看看实际效果,在某个配置文件中(或者单独创建一个配置文件)加入以下配置,vector 加载后便会启动 9598 端口,配置文件中我们指定了使用 prometheus_exporter 格式的输出,熟悉 prometheus 的你一定会发现返回的数据格式非常熟悉

[sources.metrics]
  type = "internal_metrics"
  namespace = "vector"
  scrape_interval_secs = 30

[sinks.prometheus]
  type = "prometheus_exporter"
  inputs = [ "metrics" ]
  address = "0.0.0.0:9598"
  default_namespace = "service"
1
2
3
4
5
6
7
8
9
10

企业微信截图_204132da-524c-4c2e-b579-34f7b26ca263

# 2.7 vector 的自动均衡 kafka 消费[重要]

在使用 vector 之前,logstash 经常会出现消费不均匀的情况,导致部分 logstash 节点负载高、另一部分节点却又很空闲,在使用了 vector 之后这个问题自动解决了,从下图可以看出每个 vector 实例自动消费了 6 个分区;其实这是一个非常有用的功能:在使用 logstash 时,由于它不能自动均衡消费,所以我们需要评估各个 topic 的数据量,然后给其分配机器,比如 20 台机器专门消费数据量大的 topic,5 台专门消费数据小的 topic;但是这个数据量和消费能力其实都是我们根据以往的经验判断的,给 topic 分配的机器数量也是拍脑袋决定的,并不是非常准确;而 vector 就自然而然的解决了这个问题,我们无需考虑太多,无需区分机器,所有的机器都一起消费所有的 topic!

企业微信截图_f90414ab-6bb6-4ab7-a00a-022bd6770ff7

# 2.8 自适应并发请求

在 0.17.0 版本后默认启用了自适应并发,这是一个智能、强大的功能,官方介绍请看https://vector.dev/blog/adaptive-request-concurrency/ (opens new window),这里大致介绍一下:

vector往下游写数据的速度非常快,这对下游如elasticsearch等接收器提出了重大挑战,因为这些服务无法始终像vector一样快速处理事件负载;在0.11之前的vector版本中,我们可以设置限速来解决这类问题,可是这又引发了另一个问题,限速作为后备是不错,但它会将您锁定在一个永久循环中:
在这个恶性循环中,您需要不断避免两种结果:
 - 您将限制设置得太高,进而会压倒您的服务、损害系统可靠性,这时候就需要降低限制并重新评估了。
 - 将限制设置得太低并浪费资源,您的 Elasticsearch 集群可能能够处理比您提供的更多的并发性,这时候又需要重新评估了。
1
2
3
4

为了解决这个问题,vector 推出了自适应并发的功能,它会重点观察两件事:请求的往返时间 (RTT) 和 HTTP 响应代码(失败与成功),从而决策出一个最佳的速率!

image-20220323132507606

# 2.9 性能效果对比[重要]

拿同一个 topic、同一个消费组来做对比,consumergroup:mg topic:mg-sale-api 每晚都会告警 kafka 堆积,堆积量都在 2000w 以上

企业微信截图_a8fb6b0f-214f-43dc-9595-76ea9404a5d8

企业微信截图_72dd2104-dc8d-4e48-852d-8e5489490f92

在使用 vector 之后,晚高峰最大的未消费数只有不到 5k,这还是节点从 34 台 16c64g 缩容到 10 台 16c16g 的结果

企业微信截图_e4427473-73b0-4722-905e-b45bb3b0eba3

# 3. 小结

实践下来可以发现 vector 是一款功能强大、性能优秀的数据管道工具,但在国外火热的它却在国内使用的人数寥寥无几,相关资料也少之又少,不过笔者相信是金子总会发光的,相信以后 vector 会被更多人发掘,从而在更多的公司里发光发热!特此感谢微拍堂同事 -- 李秋阳在项目期间提供的指引以及鼎力支持!

微信 支付宝
上次更新: 2024/07/04, 22:40:37
GitLab全局搜索之SourceGraph
规范编码之利用pre-commit给项目添加提交前检查

← GitLab全局搜索之SourceGraph 规范编码之利用pre-commit给项目添加提交前检查→

最近更新
01
学习周刊-总第212期-2025年第21周
05-22
02
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
03
学习周刊-总第211期-2025年第20周
05-15
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式