为什么你应该了解 Loggie
你可能对日志并不感兴趣。
不过没关系,本文也不打算介绍 Loggie 如何采集日志。
首先请不要被 Loggie 的名称限制了思维,我想重新定义一下:
什么是 Log?
从本质上,Log 即为 Data。而 Data,在我们平时的开发中无处不在。
引用知名经典野猪书《Designing Data-Intensive Applications》(还没看过这本书的请不要错过)里的一句话:
现今很多应用程序都是数据密集型(data-intensive) 的,而非计算密集型(compute-intensive) 的。因此 CPU 很少成为这类应用的瓶颈,更大的问题通常来自数据量、数据复杂性、以及数据的变更速度。
不管我们是 CRUD boy 或者 YAML 工程师,恐怕写代码的时候最常接触和思考的,还是如何设计各种数据模型,如何处理内存、磁盘或网络上的字节,通常这些过程中,会涉及到协议编解码(JSON/ProtoBuf),数据存储(SQL/NoSQL)与通信(HTTP/RPC),消息传递(MQ)等等。
但是,我们在工作中,往往会更加关注项目的业务逻辑,忽略背后的技术本质和抽象,以及工程化的难题与挑战。长期以来,很容易成为某些第三方库的熟练封装工,框架 API 的机械使用者,别人嘴里的「调包侠」。
如何避免陷入这种困境?一个好的办法是选择一个合适的开源项目,从项目里学习总结和提炼,尝试对其中的代码进行修改、补充或者优化。
真正合适的选择其实并不多,当然你也能猜到,这里我向你推荐 Loggie。
因为,Loggie 有着直观、通用的数据链路模型:source → interceptor → sink,典型的数据密集型应用,没有太多的业务属性,易于扩展开发,极致简单但却又包罗万象。
Loggie 是什么?
仅从日志的场景来解释,Loggie(https://github.com/loggie-io/loggie/) 是一个基于 Golang 的轻量级、高性能、云原生日志采集 Agent 和中转处理 Aggregator,支持多 Pipeline 和组件热插拔,提供了:
🔨 一栈式日志解决方案:同时支持日志中转、过滤、解析、切分、日志报警等
☁ 云原生的日志形态:快速便捷的容器日志采集方式,原生的 Kubernetes 动态配置下发
🔑 生产级的特性:Loggie 吸收了我们长期的大规模运维经验,形成了全方位的可观测性、快速排障、异常预警、自动化运维能力
但需要再次强调的是,Loggie 里的 Log 只是 Data 或者 Events 在一种具体场景下的称号,采集日志只是其中一个叫 file source 的组件,Loggie 里还有很多其他的 source/interceptor/sink:
所以,格局大点,我更愿意描述 Loggie 为:CloudNative Events Connector And Processor。
(云原生的数据连接器,连接了各种数据源,可以对各种数据流进行处理、转换与路由)
从使用形态上 Loggie 可划分为:
Sidecar 形态:部署在每个业务容器一起,用于采集容器日志在内的数据
Agent 形态: 每个节点一个或者每个 Pod 一个,用于采集日志或者其他数据
Aggregator 形态: 用于中转、转发和处理,可独立部署成集群
基于简单直接的 Source → Interceptor → Sink 模型,以及多 Pipeline 设计,Loggie 可以用在很多的场景:
数据采集: 采集容器日志、节点日志,采集 Prometheus metrics、Kubernetes Events 等
数据中转: 作为中转机去做数据的聚合、转发、分流
数据处理: 进行流式数据的切分、转换、处理
日志报警: 进行异常日志的检测与报警
......
但是,这些都不重要,重要的是:
为什么你应该了解一下 Loggie?
Loggie 是一个“麻雀虽小,五脏俱全”的项目,特别如果你是一个 Gopher,日常写 Golang 或者正在学习,Loggie 简直就是为你量身打造。
考虑到 Loggie 的使用场景,Loggie 需要追求极致的轻量化、极致的性能、极致的稳定性以及可维护性。Data-intensive 的各种 case,在 Loggie 中都可能有集中的体现。
比如:
队列模型的知识:如何保证队列里的事务或者 at least once 语义?在队列中如何实现重试、限流、去重、背压?如何设计一个持久化队列?
插件化设计模型:各种动态的配置(validate/defaults),各种组件的解偶与可插拔
极致的性能追求:如何写出高性能的 Golang 代码,如何做到面向 GC 编程,这其中有哪些常见的 bad taste?
可观测性:Loggie 致力于可观测性的统一采集与转发,所以这里有 prometheus metrics、openTelemetry 等等。同时如何做好项目自身的可观测性?这关系到项目是否能够真的在线上稳定运行,以及长期运行的易用性与可维护性
Golang Runtime 的一些入门,如何成为熟练使用 pprof 的一把好手,如何快速进行排障,以及在项目中怎么做持续的 profile?
流式处理:Loggie 是如何实现一个轻量级的流式处理功能,怎么去实现一个简单的带有逻辑判断的 DSL?
Kubernetes Operator:这里有分布式的 Controller,可选的集中式 Operator,还有自动的 sidecar 注入,以及基于 K8s 编程的历史与演进
各类文件系统的知识:通过探究 Loggie 最常用的 file source 设计,以及 file sink 和持久化队列,你能够了解如何高性能的和文件系统打交道
各种中间件:Loggie 的各种 source/sink,有对各种中间件 SDK 的选型,不管是 Kafka、Elasticsearch 以及后续的 Clickhouse, Pulsar 等网红中间件,你都可以找到可供参考的 code example 以及使用的最佳实践
自动化测试: 在 Golang 项目里如何集成静态代码检查,如何做 e2e、集成、Fuzz、压测自动化测试?如何处理各种依赖的外部组件?
如果你深入了解 Loggie 后,你会发现,平时里遇到的项目,或多或少都带有一点 Loggie 的影子。因为他们都遵循数据密集型应用本质的设计,都可以参考类似的解决思路,像江湖中的某种武功绝学,我们平时练习了太多花里胡哨的招式,却一直没有领悟到大师们秘而不宣的心法,Loggie 可能就是那个隐藏在石碑上的口诀。
另外,如果你在某个时刻,需要进行数据的传输和处理,请第一时间想到 Loggie,看看 Loggie 能不能满足你的需求。如果不能,可以考虑一下快速开发一个 Source、Sink 或 Interceptor 组件,复用 Loggie 的能力,可以避免大量重复的开发工作,比如:
在 Kubernetes 集群中可方便、快速的使用 CRD 下发配置,并且支持自动 reload、支持指定集群,无需考虑部署、配置更新等问题
依赖 Loggie 提供传输过程的稳定性和可靠性,保证 at-least-once 和重试机制,避免数据丢失,以及数据量过多或过大造成的隐患
使用 Loggie 提供的一系列监控指标,比如队列长度、传输延迟、发送 QPS 等,可快速接入 Prometheus,同时还可使用一些系统内置的快速排障的接口与能力
使用可插拔的 Interceptor 可用于自定义的数据处理、格式转换等,避免过多的定制化代码开发
当然,Loggie 还是一个很年轻的项目,正式开源后的这段时间,每天都有很多人在问各种问题、提各种需求、给各种建议,Loggie 还有太多的功能亟待研发,充满了各种可能性,如果你感兴趣,欢迎来提 issues 加入讨论,提 PR 为 Loggie 添砖加瓦。
接下来将有一系列文章,分享我们在开发 Loggie 的一些思考和收获,我挑了几个通用的、有意思的主题组成了这个系列,姑且命名为《A byte of Loggie》,本文可为序。
所以,实际上这是一个“挂着羊头卖狗肉”的系列,Loggie 只是一个引子,引出的是在 Loggie 实践中的沉淀、引申、抽象和总结。
最后,第一篇预告:《A byte of Loggie: 各式各样的队列及其方法论》
请加入你的延迟队列。
相关阅读:
Loggie 项目地址:https://github.com/loggie-io/loggie/
作者简介: 傅轶,网易数帆 轻舟日志平台负责人、架构师。目前专注网易数帆轻舟云原生日志平台研发,致力于云原生技术及其生态体系建设和商业化落地,对 Kubernetes、Serverless、可观测性等有较深入研究,具有丰富的云原生分布式架构设计开发经验与项目实践。
版权声明: 本文为 InfoQ 作者【网易数帆】的原创文章。
原文链接:【http://xie.infoq.cn/article/3055c9c9ab7ebac67e6b905e5】。文章转载请联系作者。
评论