iLogtail 开源两周年:UC 工程师分享日志查询服务建设实践案例
作者:UC 浏览器后端工程师,梁若羽
传统 ELK 方案
众所周知,ELK 中的 E 指的是 ElasticSearch,L 指的是 Logstash,K 指的是 Kibana。Logstash 是功能强大的数据处理管道,提供了复杂的数据转换、过滤和丰富的数据输入输出支持。Filebeat 是师出同门的轻量级日志文件收集器,在处理大量日志文件、需要低资源消耗时,它们通常被一起使用。其经典使用场景如下图,Filebeat 将日志文件从各个服务器发送到 Kafka 解耦,然后 Logstash 消费日志数据,并且对数据进行处理,最终传输到 ElasticSearch,由 Kibana 负责可视化。这种架构兼顾了效率和功能。
iLogtail 的优势
请注意,iLogtail 也是轻量级、高性能的数据采集工具,也有不俗的处理能力,重要的是,压测显示,iLogtail 性能比 Filebeat 领先太多。究其原理,Polling + inotify 机制可能是 iLogtail 性能如此优秀的最重要原因。这方面,社区已经有详尽的文档,这里就不深入了。
让我们关注性能测试结果,实际的业务场景,比较贴近下面表格第四行“容器文件采集多配置”一项,可以看到,同流量输入下,随着采集配置增加,filebeat CPU 增加量是 iLogtail CPU 增加量的两倍。其它场景,iLogtail 在 CPU 方面的优势也是遥遥领先,有五倍的、有十倍的,具体数值可以参考下面的链接。
《容器场景 iLogtail 与 Filebeat 性能对比测试》:
https://ilogtail.gitbook.io/ilogtail-docs/benchmark/performance-compare-with-filebeat#dui-bi-zong-jie
《Logtail 技术分享(一) : Polling + Inotify 组合下的日志保序采集方案》:
https://zhuanlan.zhihu.com/p/29303600
iLogtail 替换 Logstash 可行性分析(What to do)
那么,iLogtail 能够在生产环境中替换 Filebeat 和 Logstash,直接采集日志到 ElasticSearch 呢?
如果是过去,答案是不能。主要有四个方面的原因。
- 插件性能。
- 配置管理。
- 容灾。
- 自身状态监控。
现在逐一分析一下。
插件性能
虽然 iLogtail 核心部分性能突出,但是它原先的 elasticsearch flusher 插件存在短板。
配置管理
- 我们生产环境有很多采集实例,缺少一个前端页面,供管理员白屏化维护采集配置。因为 Config Server 已经提供了 API 接口,所以这也是最容易实现的。
- iLogtail Agent 缺少生命周期管理,当 Agent 进程退出后,该 Agent 对应的心跳信息长期保留在 Config Server 数据库中,而且没有存活状态,即使是想清理也不知道应该清理哪些记录。
- 我们上千个应用实例是分组部署的,每个组的采集配置可能不一样,所以 Config Server 也要支持按照标签,对各个 Agent 进行分组管理。
容灾
生产环境所有节点都要求多实例部署,Config Server 也一样,而现在的 leveldb 存储方案使得它是有状态的,需要替换为 MySQL 等具有成熟容灾方案的关系数据库。
自身状态监控
在 Agent 运行过程中,需要以合适的方式上报 CPU 使用率、内存占用等信息给 Config Server,方便管理员掌握其负载状况。
目标:iLogtail 替换 Logstash(How to do)
除去 Config Server 前端页面,针对以上四个方面留存的五大问题,我们在过去一段时间做了全面优化提升,最终实现了目标。下面,参考 OKR 工作法,介绍这五大问题的解决方案。当然,留意到现在社区开始讨论 Config Server 的通信协议修改,我们的方案是在前一段时间的基础上实现的,可能与最终方案有所不同。
KR1:解决 elasticsearch flusher 性能瓶颈
方案分为三部分,分别如下:
- 使用 esapi 的 BulkRequest 接口批量向后端发送日志数据。批量之后,一个请求可以发送几百上千条日志,请求次数直接降低两三个数量级。
- Agent 在 flush 阶段之前,有聚合的过程,会自动生成一个随机的 pack id,以它作为 routing 参数,把同一批次的日志数据路由到同一个分片上,以免 ElasticSearch 按照自动生成的文档 ID 作为分片字段,减少不必要的计算和 IO 操作,降低负载,提高吞吐量。
- 启用 go routine 池,并发向后端发送日志数据。
KR2:解决 Agent 生命周期管理与存活状态判断
方案参考 HAProxy 的实现,尽量避免网络抖动带来的影响。
- Config Server 只有收到连续指定次数的心跳,才会认为该 Agent 在线。
- 只有连续指定次数的周期内都没有收到心跳,才会认为该 Agent 离线。
- Agent 离线达到一定时长后,即可自动清理该 Agent 的残余心跳信息。
KR3:解决 Agent 按标签分组
这个方案需要修改一下通信协议。原协议的相关部分如下:
message AgentGroupTag {string name = 1;string value = 2;
}message AgentGroup {string group_name = 1;...repeated AgentGroupTag tags = 3;
}message Agent {string agent_id = 1;...repeated string tags = 4;...
}
可以看到,iLogtail 的 Agent Group 和 Agent 均已经带有标签属性(tags),但两者的数据结构并不一致,Agent Group 是 Name-Value 数组,Agent 是字符串数组。
方案把它们都统一为 Name-Value 数组,并在 Agent Group 加上运算符,表达两种语义:“与”、“或”。这样,Agent Group 就拥有一个由标签和运算符组成的“表达式”,如果该表达式能够和 Agent 持有的标签匹配上,那么即可认为该 Agent 属于该分组。例如:
- 如果某个 Agent Group 的标签定义为 cluster: A 和 cluster: B,运算符定义为“或”,那么,所有持有 cluster: A 标签或者 cluster: B 标签其中之一的 Agent 都属于该分组。
- 如果某个 Agent Group 的标签定义为 cluster: A 和 group: B,运算符定义为“与”,那么,所有同时持有 cluster: A 标签和 group: B 标签的 Agent 才属于该分组。
KR4:解决 Config Server 容灾
Config Server 已经提供一套 Database 存储接口,只要实现了该接口的全部方法,即完成了持久化,leveldb 存储方案给了一个很好的示范。
type Database interface {Connect() errorGetMode() string // store modeClose() errorGet(table string, entityKey string) (interface{}, error)Add(table string, entityKey string, entity interface{}) errorUpdate(table string, entityKey string, entity interface{}) errorHas(table string, entityKey string) (bool, error)Delete(table string, entityKey string) errorGetAll(table string) ([ ]interface{}, error)GetWithField(table string, pairs ...interface{}) ([ ]interface{}, error)Count(table string) (int, error)WriteBatch(batch *Batch) error
}
于是,我们依次实现该接口的所有方法,每个方法,基本都是通过反射获得表的实体和主键,再调用 gorm 的 Create、Save、Delete、Count、Find 等方法,即完成了 gorm 的 CRUD 操作,也就是实现了持久化到 MySQL、Postgre、Sqlite、SQLServer,也实现了从数据库读取数据。
这里有一个细节,Database 接口定义了 WriteBatch 方法,本意是批量处理心跳请求,提高数据库写入的能力。如果是 MySQL,与之相应的处理办法是数据库事务。但是,在实践过程中,DBA 发现在事务中更新一批心跳数据,事务可能会变得过大,非常容易导致数据库死锁,放弃使用 WriteBatch 就恢复正常。由于心跳间隔默认 10 秒,即使一个心跳请求进行一次写入操作,在 Agent 数量上千个的规模下,那么,TPS 每秒也就上百,数据库压力并不算特别大。
KR5:iLogtail 自身状态监控
该方案可能最简单直接,在心跳请求的 extras 字段中上报 Agent 进程的 CPU 使用率和内存占用字节数。Config Server 最终会把这些信息保存到 MySQL 数据库,另外再安排一个定时任务做快照,多个快照按照时间序列形成趋势,再进行可视化分析,协助定位解决问题。
日志查询服务
上面解决了怎样把大量日志存储到 ElasticSearch 中,用户需求解决了一半。剩下一半,就是对用户提供查询服务,还需要一个界面。
理论上,Kibana 可以提供数据展示功能,但它主要面向管理员,而且是通用设计,不是面向日志服务,对于一些企业核心需求,例如:内部系统集成、多用户角色权限控制、日志库配置、多 ElasticSearch 集群管理,均无能为力,只适合在小团队、单集群使用。因此,要实现公司级别的统一界面,还需要自研一个最简版日志查询平台,才能与日志采集形成一个大的闭环,提供一个完整的解决方案。不过这一部分,基本上和 iLogtail 关系不大,暂且略过。
日志采集实践总结
逐一解决 iLogtail 替换 Logstash 的五大问题后,我们可以从容地说,iLogtail 在配置管理、采集、反馈等方面初步形成了一个小的闭环,无需过多依赖于其它工具,在技术上,是 Filebeat、Logstash 的最佳替代者。
我们使用的 iLogtail 是基于开源版 1.8.0 开发的,从 2024 年 2 月底正式上线至今,已稳定运行超过三个月,高峰期每小时采集日志超过百亿条,数据量是 TB 级别,服务业务应用 pod 上千个,ElasticSearch 存储节点数量上百个。
目前这些代码变更,在部分实现细节上,涉及到通信协议的修改,需要继续与社区负责人沟通,希望不久之后部分变更能够合并到 iLogtail 的主干分支。
以上五大问题,除了第一个 elasticsearch flusher,其它四个都与 Config Server 息息相关。因此,我曾经在社区钉钉群里说过:“Config Server 是皇冠上的明珠”,意思是它具有很高的用户价值,希望社区同学在这方面共同努力。
iLogtail 两周年系列宣传文章:
iLogtail 开源两周年:感恩遇见,畅想未来
iLogtail 进化论:重塑可观测采集的技术边界
相关文章:

iLogtail 开源两周年:UC 工程师分享日志查询服务建设实践案例
作者:UC 浏览器后端工程师,梁若羽 传统 ELK 方案 众所周知,ELK 中的 E 指的是 ElasticSearch,L 指的是 Logstash,K 指的是 Kibana。Logstash 是功能强大的数据处理管道,提供了复杂的数据转换、过滤和丰富…...

【MySQL】入门篇—基本数据类型:NULL值的概念
在关系数据库中,NULL值是一个特殊的标记,表示缺失或未知的值。 NULL并不等同于零(0)或空字符串(),它表示一个字段没有任何值。 这一概念在数据库设计和数据管理中至关重要,因为它影…...

Java设计模式10 - 观察者模式
观察者模式 观察者模式也叫作发布-订阅模式,也就是事件监听机制。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自…...

LabVIEW示波器通信及应用
基于LabVIEW平台开发的罗德与施瓦茨示波器通信与应用系统实现了示波器的远程控制及波形数据的实时分析,通过TCP/IP或USB接口与计算机通信,利用VISA技术进行指令传输,从而实现高效的数据采集与处理功能。 项目背景 随着现代电子测试需求的日益…...

西门子PLC中Modbus通讯DATA_ADDR通讯起始地址设置以及RTU轮询程序设计。
1 DATA_ADDR通讯起始地址设置 因为西门子PLC保持型寄存器的是40001~49999和400001~465536, 那么什么时候用40001什么时候用400001呢? 当需要的地址超过49999的话就用400001。 比如从站的某个地址是#16 48D518645 4000118645超过了49999 这边因为前…...

趋势(一)利用python绘制折线图
趋势(一)利用python绘制折线图 折线图( Line Chart)简介 折线图用于在连续间隔或时间跨度上显示定量数值,最常用来显示趋势和关系(与其他折线组合起来)。折线图既能直观地显示数量随时间的变化…...

【含文档】基于Springboot+Vue的采购管理系统(含源码+数据库+lw)
1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…...

【C++11入门基础】
我没有那么想你,那只是偶尔醉意会催人提起.......................................................................... 目录 前言 一、【C11的介绍】 二、【C11引入的一些实用语法】 2.1、【统一的列表初始化({ }的初始化)】 2.2、【initi…...

Pytest中fixture的scope详解
pytest作为Python技术栈下最主流的测试框架,功能极为强大和灵活。其中Fixture夹具是它的核心。而且pytest中对Fixture的作用范围也做了不同区分,能为我们利用fixture带来很好地灵活性。 下面我们就来了解下这里不同scope的作用 fixture的scope定义 首…...

Springboot 接入 WebSocket 实战
Springboot 接入 WebSocket 实战 前言: WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 简单理解: 1,常见开发过程中我们知道 Http协议,客户端…...

数据结构之红黑树的实现
红黑树的实现 1. 红⿊树的概念1.1 红⿊树的规则:1.2 思考⼀下,红⿊树如何确保最⻓路径不超过最短路径的2倍的?1.3 红⿊树的效率: 2. 红⿊树的实现2.1 红⿊树的结构2.2 红⿊树的插⼊2.2.1 红⿊树树插⼊⼀个值的⼤概过程2.2.2 情况1…...

智能工厂的设计软件 中的AI操作系统的“三维时间”(历时/共时/等时)构建的“能力成熟度-时间规模”平面
本文要点 “智能工厂的设计软件提出 “三维时间”的一个时间立方体(cube)。 “三维时间”的概念--历时diachronic(一维的)、共时synchronic(二维的)和等时isochronic(三维的)。 即…...

Spring Boot常见错误与解决方法
White graces:个人主页 🙉专栏推荐:Java入门知识🙉 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 目录 创建第一个SpringBoot项目 SpringBoot项目各个…...

Mac中安装以及配置adb环境
一、adb介绍 Android 调试桥 (Android Debug Bridge) 是一种功能多样的命令行工具,可让您与设备进行通信。adb 命令可用于执行各种设备操作,例如安装和调试应用。adb 提供对 Unix shell(可用来在设备上运行各种命令)的访问权限。…...

WebGL着色器语言中各个变量的作用
1、attribute变量 用于接收顶点数据,只能在顶点着色器中声明和使用。 attribute vec3 a_position; 2、uniform变量 用于在JavaScript代码中设置并在着色器程序中保持不变的值,可以在顶点着色器和片元着色器中声明和使用。但是要保证变量名唯一&#…...

Canmv k230 C++案例1——image classify学习笔记 初版
00 简介 用C编写代码的比mircopython要慢很多,需要编译开发环境,同时使用C更接近底层,效率利用率应该也是更高的,就是需要学习更多的内容,因为从零开始因此比较比较耗时。 注:以下为个人角度的理解&#x…...

vs2022 dump调试
程序中加入了捕获dump得代码,那么当程序crash时,通常可以捕获到dump文件。当然,也有一些崩溃是捕获不到的。本文就捕获到的dump文件,总结一下调试的流程。 前提:exe,pdb,dump 3者是放在同一目录…...

OpenCV高级图形用户界面(11)检查是否有键盘事件发生而不阻塞当前线程函数pollKey()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 轮询已按下的键。 函数 pollKey 无等待地轮询键盘事件。它返回已按下的键的代码或如果没有键自上次调用以来被按下则返回 -1。若要等待按键被按…...

nvm安装,node多版本管理
卸载nodejs win R 输入 appwiz.cpl 删除 node.js查看node.js安装路径是否有残留,有就删除文件夹 删除下列路径文件,一定要检查,没删干净,nvm安装会失败 C:\Program Files (x86)\NodejsC:\Program Files\NodejsC:\Users{User}\…...

ThingsBoard规则链节点:Assign To Customer节点详解
引言 分配给客户节点概述 用法 含义 应用场景 实际项目运用示例 结论 引言 在物联网(IoT)解决方案中,ThingsBoard平台以其高效的数据处理能力和灵活的设备管理功能而著称。其中,规则引擎是该平台的一个核心组件,…...

自监督行为识别-时空线索解耦(论文复现)
自监督行为识别-时空线索解耦(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 自监督行为识别-时空线索解耦(论文复现)引言论文概述核心创新点双向解耦编码器跨域对比损失的构建结构化数据增强项目部署准备工作数据…...

MyBatisPlus:自定义SQL
由于SQL不能写在业务层,所以可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分 ①基于Wrapper 构建Where条件 Testpublic void test7(){//需求:将id满足ids的数据项的balance字段减200int amount200;List…...

变电站谐波治理设备有哪些
在变电站中,由于非线性负载(如电力电子设备、变频器等)会引入谐波,对电网造成干扰,因此需要进行谐波治理。以下是常见的变电站谐波治理设备及其特点: 1、静止无功发生器(SVG) 工作原…...

Mybatis全局配置介绍
【mybatis全局配置介绍】 mybatis-config.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。 1、mybatis全局配置文件是mybatis框架的核心配置,整个框架只需一个;…...

error: cannot find symbol import android.os.SystemProperties;
背景:AS独立编译系统工程应用,使用了hide接口,导致编译不过。 尽管使用了framework.jar依赖。依然编译不过,导致各种类找不到。 例如: /SettingsLib/src/main/java/com/android/settingslib/location/RecentLocatio…...

债券市场金融基础设施 (2020版)
前言:我国债券市场格局简介 我国金融市场主要包括货币市场、资本市场、外汇市场、金融衍生工具市场等,其中,资本市场是金融市场重要组成部分,承担着实体经济直接融资的重责,做大做强资本市场对整个国民经济具有重要意义。债券市场是资本市场两大组成部分之一,对提高直接…...

OpenCV高级图形用户界面(8)在指定的窗口中显示一幅图像函数imshow()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在指定的窗口中显示一幅图像。 函数 imshow 在指定的窗口中显示一幅图像。如果窗口是以 cv::WINDOW_AUTOSIZE 标志创建的,图像将以原…...

for循环和while循环的区别
for循环和while循环的主要区别在于使用场景和结构。for循环适合已知循环次数的情况,而while循环则更灵活,适用于条件动态变化的情况。 for循环的特点 1. 已知迭代次数:for循环在开始前就需要知道具体的迭代次数。例如,遍历一个列…...

机器学习和神经网络的研究与传统物理学的关系
机器学习和神经网络的研究与传统物理学的关系 机器学习和神经网络是现代科学研究中非常热门的领域,它们与传统物理学在某些方面有着密切的关系,在人类科学研究中相互影响和促进作用也越来越显著。 首先,机器学习和神经网络在物理学研究中具…...

LabVIEW提高开发效率技巧----事件触发模式
事件触发模式在LabVIEW开发中是一种常见且有效的编程方法,适用于需要动态响应外部或内部信号的场景。通过事件结构(Event Structure)和用户自定义事件(User Events),开发者可以设计出高效的事件驱动程序&am…...