云环境中的日志收集和处理方案
在云环境中,高效的日志收集与处理是系统监控和运维的关键。本文围绕《云环境中的日志收集和处理方案》展开,先介绍日志收集的两种方式,再聚焦处理环节,探讨写入 kafka、共享存储、S3 等路径,分析使用 raft 组日志集群及 NewSQL 的方案,最后结合 Spark 端调度进行总结,为云日志管理提供多维度技术参考。
日志收集-两种方式
这里是将pod
中的日志收集,放到一个指定的地方首先是将程序中的日志能采集到,大致有两种方式
通过插件将日志重定向到指定目的地
用辅助程序采集 pod 中日志,并重定向
两种方式处理如下
都是将日志写到一个指定的地方
区别是由程序本身去做,还是由额外的程序去捕获

日志扩展
比如 log4j,需要实现一个自定义的 appender
修改配置文件,用 log4j 的自定义扩展,写入指定的目的地
配置如下:

对于应用程序来说,需要增加一些启动参数
记录角色, -Drole=spark,或者 flink
记录 application_id、executor_id
以及路径前缀(将日志写入到哪里)
注意这种模式下,一般需要将日志写入到 NFS 这种共享存储
当程序退出后,在这个目录下写一个标志文件,表示文件退出了
当然,程序启动的时候,如果有这个标志文件,需要先清理掉
对于 System.out 和 err ,需要做重定向
处理日志-写 kafka
这里是将日志通过插件写入到 kafkalog-service
消费 kafka,将日志写入到内部的 buffer
后面有 writer 写入到 NFS,注意这里还要有 ack 机制
其他还有 日志定期清理日志,迁移到 s3 模块

log-sumer
从 kafka 读取日志,写入到内部的 channel 中
这里的 channel 可以做限流,记录等额外的功能
之后有另外一个 writer 负责读取 channel,将日志写入 NFS
同时还需要做日志轮转处理,以及 迁移到 s3

处理日志-直接写共享存储
跟第一种差不多,但是少了 kafka 的处理部分 log-service
有一个日志查询服务,用户可以通过 application_id 来查询日志文件内容
为了解决单个目录下小文件过多问题,需要增加一个 hash 前缀
可以设置为 20,003,这是一个质数,也就是一个目录下最多有 2W 文件
目录为: hash/application_id/executor_id/xx.log
hash 最多 2W 个,一天产生 10W 个应用,算算可以用几十年了

日志清理
一个日志清理模块,可以清理 disk,NFS
以及清理策略,根据时间戳,可以目录下是否包括一个 标志文件来清理
比如: /data/spark/cluster_logs/14937/app-12345/executor-17
路径前缀是:/data/spark/cluster_logs,产生了 14937 这个 hash 目录
然后是 app-12345,清理程序根据 app-12345 是否空了,来决定是否删除 app-12345
同样逻辑,清理下面的 driver 和 executor
最后将日志复制到 S3、或者 minio;这里需要先复制到 s3,再清理
如果复制成功,没删除,下一次处理的时候会覆盖 s3 并清理文件
最后删除目录下的标志文件

多个节点处理
为防止日志太多单个节点处理不过来,可以启动多个节点
但多个节点可能会重复处理一个文件,所以每个节点处理前
先获取文件列表,然后 shuffle 一次,这样每个节点处理的目录就不一样了,这种方式最简单
也可以将文件写入 红黑树,然后转换成 一致性 hash 的环形
根据当前的节点 hash,定位到环的一个为止,然后顺时针处理,这样每段由不同节点处理
虽然每个节点都遍历了全部目录,但是非自己处理的基本都是空的(被别人处理过了),所以效率会提升
直接写 S3
这种方式比较简单
日志直接写入到 s3,但是会产生很多小文件
需要定期将小文件合并
同理提供 query 服务,可以查询 s3 上的日志文件
这里查询的话会麻烦一些了,可能需要查多个 日志小文件

使用 raft 组日志集群
这里不需要写 共享存储
日志写入到 log-service,这是包含一主-两从的三节点服务
通过 raft 实现强一致,主从同步,当主节点挂了,从节点晋升为主节点
这种方式不需要共享存储了,直接写本地磁盘就行了,三副本保证高可用
同时定期写 s3,这种方式需要处理好选主,可以用 apache 的 raft 实现

使用 NewSQL
使用 newsql
比如写入到 TiDB,mysql
或者写入到 ES,直接用这个中间设备做查询,还可以做模糊匹配查询
这种模式的查询能力强了,但是强依赖了一个中间件
同样也需要定期写入到 s3

总结-Spark 端
一个完整的 spark-submit 参数:

Spark 的 driver 和 executor 都需要设置一些 ENV 参数:
SPARK_EXECUTOR_ID ,driver 端需要手动设置,executor 是自动设置上的
SPARK_APPLICATION_ID ,driver 和 executor 都是自动设置上的
SPARK_PREFIX_DIR ,driver 和 executor 都需要手动设置上
评论