前言
自前司负责日志分析工作任务开始,我就一直深受日志存储之痛。
在整个日志分析链条之中,采集工具千千万万,无论是老牌的 flume
,中生代的 filebeat
,还是云原生新贵 fluentbit
、vector
,采集性能都相差不大,对原有服务器的性能影响和损耗都能维持在一个很低的水准,因此用谁都一样。
在日志传输、缓存、削峰、限流领域,Kafka 几乎是唯一的选择。任何日志采集和数据存储平台都得具备对接 Kafka 的能力。
偏偏在日志存储方面,自七八年前 Elasticsearch
问世以来,几乎形成了垄断地位,至今一直没有什么产品能威胁到它的地位。这么多年来版本不停迭代,功能越做越丰富,产品版图扩的越来越大,什么机器学习、AI 功能做了不少,但最基本的大容量数据存储性能、存储成本却一直拉跨。功能做的越多学习成本直线上升。咱就说不能有个开箱即用、配置简单、上手迅速、性能也不差的日志存储产品吗?
直到我发现了 Quickwit
。
有了 Quickwit
,现在日志分析链条上,前半部分从采集到 Kafka
都不变,后半部分从 Kafka
到 Elasticsearch
就改成了 Kafka
到 Quickwit
。
部署 Kafka
参见 部署 Kafka
部署单节点 Quickwit
参见 Quickwit 部署
Quickwit 对接 Kafka
Quickwit 支持从 Kafka 读取数据,这样原本通过 Filebeat 等方式采集上来的日志,送到 Kafka 后,可以不再存入 Elasticsearch,而是改为存入 Quickwit。
创建索引
参考 Create index
准备好索引配置文件,然后使用命令创建索引:
./quickwit index create --index-config gh-archive.yaml
创建 source
Kafka 支持的安全协议包括:
- PLAINTEXT 无任何安全保护,直接连
- SASL_PLAINTEXT
- SASL_SSL
- SSL
我使用的是 SASL_PLAINTEXT
,source 配置文件如下:
#
# Kafka source config file.
#
version: 0.8
source_id: "kafka-source"
source_type: kafka
num_pipelines: 2
params:
topic: kd_req_statistics
client_params:
bootstrap.servers: kafka-0.kafka-headless.svc.cluster.local:9092
security.protocol: SASL_PLAINTEXT
sasl.mechanisms: SCRAM-SHA-256
sasl.username: user
sasl.password: passwd
创建 source:
./quickwit source create --index gh-archive --source-config kafka-source.yaml
等待一会,在 Quickwit 界面能看到 Kafka 的数据已经进来了。
部署 Quickwit 集群
Kubernetes 部署
二进制部署
Quickwit 总共有 5 种角色:
Indexers
ingest documents from data sources and build indexes.Searchers
execute search queries submitted via the REST API.- The
Metastore
stores index metadata in a PostgreSQL-compatible database or cloud-hosted file. - The
Control Plane
distributes and coordinates indexing workloads on indexers. - The
Janitor
performs periodic maintenance tasks.
5 种角色启动的时候以 --service
参数指定。结构图如下:
环境规划
IP | 角色 | 启动命令 |
---|---|---|
192.168.126.128 | metastore | ./quickwit run --service metastore |
192.168.126.129 | control-plane | ./quickwit run --service control_plane |
192.168.126.130 | indexer-1, minio-1 | ./quickwit run --service indexer |
192.168.126.131 | indexer-2, minio-2 | ./quickwit run --service indexer |
192.168.126.132 | searcher, minio-3 | ./quickwit run --service searcher |
节点配置
metastore
的配置文件
version: 0.7
cluster_id: mycluster
node_id: quickwit-metastore
listen_address: 0.0.0.0
rest:
listen_port: 7280
peer_seeds:
- quickwit-metastore
- quickwit-control-plane
- quickwit-indexer-1
advertise_address: 192.168.126.128
data_dir: /data/qwdata
storage:
s3:
flavor: minio
access_key_id: exGkixAd72LLudQnC6sY
secret_access_key: pTY49ucK0L8JLl7CZJRONjdYduGMkHIvaIvNcKeU
region: pek
endpoint: http://quickwit-node-1:9000
force_path_style_access: ${QW_S3_FORCE_PATH_STYLE_ACCESS:-false}
disable_multi_object_delete: false
disable_multipart_upload: false
peer_seeds
不需要把所有节点都写全,后面扩容时也无需把新节点增加到 peer_seeds
里,quickwit 靠 listen_address
和 advertise_address
自动发现集群里设置了同一个 cluster_id
的节点。
control-plane
的配置文件
version: 0.7
cluster_id: mycluster
node_id: quickwit-control-plane
listen_address: 0.0.0.0
rest:
listen_port: 7280
peer_seeds:
- quickwit-metastore
- quickwit-control-plane
- quickwit-indexer-1
advertise_address: 192.168.126.129
data_dir: /data/qwdata
storage:
s3:
flavor: minio
access_key_id: exGkixAd72LLudQnC6sY
secret_access_key: pTY49ucK0L8JLl7CZJRONjdYduGMkHIvaIvNcKeU
region: pek
endpoint: http://quickwit-node-1:9000
force_path_style_access: ${QW_S3_FORCE_PATH_STYLE_ACCESS:-false}
disable_multi_object_delete: false
disable_multipart_upload: false
indexer-1
的配置文件
version: 0.7
cluster_id: mycluster
node_id: quickwit-indexer-1
listen_address: 0.0.0.0
rest:
listen_port: 7280
peer_seeds:
- quickwit-metastore
- quickwit-control-plane
- quickwit-indexer-1
advertise_address: 192.168.126.130
data_dir: /data/qwdata
storage:
s3:
flavor: minio
access_key_id: exGkixAd72LLudQnC6sY
secret_access_key: pTY49ucK0L8JLl7CZJRONjdYduGMkHIvaIvNcKeU
region: pek
endpoint: http://quickwit-node-1:9000
force_path_style_access: ${QW_S3_FORCE_PATH_STYLE_ACCESS:-false}
disable_multi_object_delete: false
disable_multipart_upload: false
indexer-2
的配置文件
version: 0.7
cluster_id: mycluster
node_id: quickwit-indexer-2
listen_address: 0.0.0.0
rest:
listen_port: 7280
peer_seeds:
- quickwit-metastore
- quickwit-control-plane
- quickwit-indexer-1
advertise_address: 192.168.126.131
data_dir: /data/qwdata
storage:
s3:
flavor: minio
access_key_id: exGkixAd72LLudQnC6sY
secret_access_key: pTY49ucK0L8JLl7CZJRONjdYduGMkHIvaIvNcKeU
region: pek
endpoint: http://quickwit-node-1:9000
force_path_style_access: ${QW_S3_FORCE_PATH_STYLE_ACCESS:-false}
disable_multi_object_delete: false
disable_multipart_upload: false
searcher
的配置文件
version: 0.7
cluster_id: mycluster
node_id: quickwit-searcher
listen_address: 0.0.0.0
rest:
listen_port: 7280
peer_seeds:
- quickwit-metastore
- quickwit-control-plane
- quickwit-indexer-1
advertise_address: 192.168.126.132
data_dir: /data/qwdata
storage:
s3:
flavor: minio
access_key_id: exGkixAd72LLudQnC6sY
secret_access_key: pTY49ucK0L8JLl7CZJRONjdYduGMkHIvaIvNcKeU
region: pek
endpoint: http://quickwit-node-1:9000
force_path_style_access: ${QW_S3_FORCE_PATH_STYLE_ACCESS:-false}
disable_multi_object_delete: false
disable_multipart_upload: false
启动集群
每个节点上启动 Quickwit,命令见上文环境规划,启动后任意节点的 7280
端口均可以打开 ui
测试
在现公司部署的容器版 Quickwit 对接上 Kafka
后,平均吞吐量大约在 3000docs/s
左右,目前运行稳定。
Quickwit 对原始数据具有很高的压缩比,这一点可以说完爆 Elasticsearch。一个令我没想到的是,按说对象存储上的数据查询性能是比较差的,但 Quickwit
从 Minio
上检索数据量大约在 7 千万条左右,时间能控制在毫秒级,这一点真是惊到我了。后面会再做几次扩容测试观察观察。
总体来说,Quickwit 目前已经能满足我对日志存储的所有要求了~