新版日志系统建设,利用clickhouse替换ES架构

发布时间 2024-01-04 16:20:36作者: 我有酒,你有故事吗?

背景

随着业务量的大幅提升,日志存储要求越来越大,写入IO越来越高,需要对整个日志系统进行升级,使用ES作为存储引擎的成本也越来越高,需要一个针对日志场景,更高性价比的存储引擎来替换ES,经过调研,选用clickhouse作为存储引擎用于新日志平台的建设,在整个日志平台升级过程还需要对采集端、消费端等进行整体优化。

采集端

采集端依然采用的filebeat组件,在应用到工程中的时候,我们要解决filebeat配置文件的动态变更问题,filebeat进程的监控问题。做到日志管理后台配置随时可以更新到业务机器上。所以在采集端对filebeat进行封装,对filebeat进程进行启动、关闭、重启、等控制。定时请求日志管理后台服务获取最新的配置生成配置文件,重启filebeat采集。

消费端

消费端经过了3个比较大的版本,每次版本的升级都是考虑到运维成本、资源利用率、写入速度等因素。

版本迭代

1.0 版本使用的是开源项目heka的二次开发,写入速度在20w/s左右,资源利用率较低
2.0 版本使用的是开源项目gogstash的二次开发,写入速度在55w/s,资源利用率较高
3.0 版本使用的是开源项目Vector,写入速度可以达到150w/s, 可以使用lua进行扩展,资源利用率也是极高。

性能对比

Vector

Vector 是一个高性能的可观测性数据管道,可帮助企业控制其可观测性数据,在实际使用中,vector的部署相对简单,经过简单的参数调整就可以满足大部分的任务需求,不需要反复的编译和开发,其次vector的写入IO非常高,对机器资源也可以充分利用,可以快速的消耗掉存量日志数据,最后是vector有动态调整的特性,可以根据下游存储端的反馈进行动态写入调整,这是一个我个人认为非常非常厉害的功能,这样可以避免压垮下游存储集群,解决存量数据压垮集群的担忧。Vector有非常丰富的可视化数据API,可以配置grafana生成完善的可视化图表


存储端

ClickHouse是一种专注于列式存储和分析的开源数据库管理系统,它以其卓越的查询性能和出色的可扩展性而备受关注,尤其适用于大规模数据的复杂分析场景,ClickHouse通过优化存储和查询引擎,提供了更高的吞吐量和更低的查询延迟,从而使业务能够以更低的成本获得更好的性能。

引擎支持

ClickHouse 支持多种存储引擎,在日志场景下我们分别选择MergeTree和Distributed引擎,MergeTree是ClickHouse的默认存储引擎,广泛用于时间序列数据的存储和分析。MergeTree将数据按照主键顺序分区存储,使用了基于LSM树(Log-Structured Merge Tree)的存储结构来提供高性能的写入和查询。并且能够压缩数据以节省存储空间。Distributed引擎允许数据在多个节点间进行分布式存储和查询。它可以分配数据到不同节点,并自动将查询分发到合适的节点上进行处理,从而实现数据的分布式和并行处理,我们用该引擎来读数据。

数据模型

我们尽量用一张大的宽表去存放所有的数据,Clickhouse的表需要提前创建,并且字段固定,不像ES一样可以随时增加字段,所以结构化日志变成很重要。在表设计时分成数据存储表分布式表,数据存储表作为本地表用于数据写入,分布式表用于读取数据,分布式表不存真实的数据,只是绑定数据存储表用于将查询请求分散到各个数据存储表中。

我们为什么不写分布式表?
原因是分布式表在接收到数据会将数据拆分多个parts,并转发数据到其它服务器,这样首先会导致我们无法进行日志数据的云内自制,跨云流量会带来网络带宽压力和成本的提高,其次服务器的merge的工作量增加,导致写入速度变慢,并且增加了Too many parts的可能性。

架构设计

在多云环境中,我们既要保证多云日志数据云内自治又要保证多云查询的可行性,整体架构如下:

各云内组成不是单独的集群,而是一个整体集群,这样每个节点的Distributed都可以路由到所有云机器,查询时可以实现多云查询,在写入端因为我们是写入本地表所以用云内的vector写入云内的MergeTree的表,从而实现日志数据的云内自治。
【整体采用多分片单副本模式】
集群中多个分片,每个分片只有一个节点,没有副本
优势:

  • 由于做了数据分片且没有副本,一个分片只需写一份,因此在写入性能是最高的。
  • 因为数据分片,读请求可以充分利用分布式集群的算力,查询性能更快。

针对特殊数据,经常查询的数据比如服务名、文件名等增加索引提高查询效率。
缺点:

  • 数据不够高可用,在日志场景是可以接受。

集群监控

  • 部署监控系统来实时监控ClickHouse集群的状态和性能指标。使用Prometheus、Grafana等组件来收集和可视化指标。
  • 监控关键指标,如查询吞吐量、查询延迟、存储使用率和硬件资源消耗等。根据监控结果进行性能调优和故障排查。
  • 配置query log监控集群慢SQL

【监控示例】

展示端

使用开源项目ClickVisual作为日志的查询组件,用于替换Kibana的查询。
ClickVisual较高的自定义检索条件等,在日志检索场景下不逊色于Kibana,并且开源用GO编写,可以根据自己的需求进行定制化开发。
我们将ClickVisual嵌套到现有平台项目中。

在嵌套使用过程中,需要进行一些定制化开发。

子目录

在嵌套过程中,我们需要根据二级目录及行跳转,比如我们需要将ClickVisual嵌套到域名http://xxxxxxx.com下,然后将http://xxxxxxx.com/clickvisual的所有请求转发到ClickVisual项目下。
我们需要将所有ClickVisual增加一层/clickvisual 子目录。
这需要通过源码重新编译

export PUBLIC_PATH=/clickvisual/    #引入子路径
make build.ui build.dist           #编译前端
make build.api                      #编译后端

编译好之后在./bin下有clickvisual二进制文件。
部署好后,访问http://10.218.18.151:19001/query → http://10.218.18.151:19001/clickvisual/query

路由配置

在网关配置

location ~* /clickvisual {
    proxy_pass http://clickvisual_server.;
}

账号设置

嵌套的前端不能使用管理员账号,需要分配只读账号用于日志检索
主要分两步
1.管理员登录 系统管理→ 实例管理→ 修改权限→ 新建自定义角色→ 新增授权

2.新增角色授权:作用域为“全部“ → 用户

这个时候登录新用户就只能看到“日志”的菜单栏。

免密码登录

clickvisual 不支持LDAP的接入,所以选择用代理的方式接入。
官网参考:https://clickvisual.net/zh/clickvisual/04appauth/auth-proxy.html#管理员模式
clickvisual 配置文件

[auth.proxy]
enabled = true
isAutoLogin = true
headerName = "X-CLICKVISUAL-VIEW-USER"

网关路由配置,增加代理header

location ~* /clickvisual {
    proxy_set_header X-CLICKVISUAL-VIEW-USER clickvisual_view;
    proxy_pass http://clickvisual_server;
}

这样每次登录都会是以clickvisual_view的用户进行访问。

总结

本文主要讨论整个日志平台建设的方案,没有太多配置和部署细节。整个系统的架构还是比较简单,没有逃过ELK的架构,但是各部分组件随着时间和技术的演进也有了新的解决方案。在Clickhouse存储端还有很多可优化的空间,也有很多设计优化,包括还可以对日志做一些挖掘和分析,下面简单列出一些思路。
引入CHproxy代理层,查询端改由HTTP协议走代理查询,方便、可控(https://github.com/ContentSquare/chproxy)
引入用户配额,限制大查询,自动Kill慢查询 (https://clickhouse.com/docs/en/operations/quotas)
数据副本功能,引入ClickHouse Keeper增加数据副本功能(https://clickhouse.com/docs/en/architecture/replication)
存算分离,引入对象存储,将冷数据备份至对象存储进一步缩减存储资源(https://clickhouse.com/docs/en/guides/separation-storage-compute)
优化监控,增强集群管理功能(https://clickhouse.com/docs/en/guides/developer/debugging-memory-issues)