日志系统是现代运维的核心。但随着系统的复杂化和分布式架构的普及,日志量呈现指数级增长。选择一个高效的日志收集和分析工具,直接影响系统的性能和维护成本。而在这场“谁是日志收集之王”的争夺战中,Loki 和 ELK Stack 各显神通。
几个月前,我们的生产系统突然崩溃,所有服务不可用。我们有数十个微服务和数据库,日志堆积如山,想要快速找到问题源头却成了大难题。我们一开始使用的是经典的 ELK Stack,它强大但复杂,搜索效率也不太尽如人意。后来,我们尝试了 Loki,这个新生代的日志系统,给了我们一些意外的惊喜。
这篇文章将带你一起回顾 Loki 和 ELK 这两个系统的对比,从它们的架构、性能、成本到应用场景,帮助你找到适合你系统的那一款。
ELK,即 Elasticsearch、Logstash 和 Kibana,是一个经典的日志分析平台。它的诞生比 Loki 早很多,社区庞大,功能也异常丰富。我们曾在系统初期使用它,因为它能做“几乎所有事情”。
假设我们需要在 Docker 中快速启动一个 ELK Stack。以下是一个简单的 docker-compose.yml
示例:
version: '3'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.9.3
container_name: elasticsearch
environment:
- discovery.type=single-node
ports:
- "9200:9200"
networks:
- elk
logstash:
image: docker.elastic.co/logstash/logstash:7.9.3
container_name: logstash
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
ports:
- "5044:5044"
networks:
- elk
kibana:
image: docker.elastic.co/kibana/kibana:7.9.3
container_name: kibana
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200
ports:
- "5601:5601"
networks:
- elk
networks:
elk:
driver: bridge
在 logstash.conf
中可以配置如何处理日志:
input {
beats {
port => 5044
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
}
stdout { codec => rubydebug }
}
使用此配置,你可以通过 Filebeat
将日志发送到 Logstash,然后将其存储到 Elasticsearch,并在 Kibana 中可视化。
Loki 是由 Grafana Labs 开发的日志系统。相比 ELK,Loki 更加轻量化,设计理念类似于 Prometheus,但专注于日志。Loki 的一大特点是它不索引日志内容,只索引标签(Labels),这大幅减少了资源消耗。
在 Docker 中部署 Loki 也非常简单。以下是一个 docker-compose.yml
示例:
version: '3'
services:
loki:
image: grafana/loki:2.0.0
container_name: loki
ports:
- "3100:3100"
volumes:
- ./loki-config.yml:/etc/loki/local-config.yaml
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:2.0.0
container_name: promtail
volumes:
- /var/log:/var/log
- ./promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
grafana:
image: grafana/grafana:7.3.1
container_name: grafana
ports:
- "3000:3000"
loki-config.yml
文件:
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
chunk_idle_period: 5m
chunk_retain_period: 30s
max_transfer_retries: 0
schema_config:
configs:
- from: 2020-10-24
store: boltdb
object_store: filesystem
schema: v11
index:
prefix: index_
period: 168h
storage_config:
boltdb:
directory: /tmp/loki/index
filesystem:
directory: /tmp/loki/chunks
limits_config:
enforce_metric_name: false
max_cache_freshness_per_query: 10m
chunk_store_config:
max_look_back_period: 0s
promtail-config.yml
文件:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*.log
通过这个 docker-compose.yml
,我们可以快速启动 Loki 和 Promtail,并使用 Grafana 来可视化日志。
我们在生产环境中测试了两者的性能,主要考察三个指标:日志写入速度、查询性能和资源消耗。
ELK Stack 适用于需要强大搜索功能和多数据源支持的大型系统,特别是有较高硬件资源和预算的公司。它的复杂查询能力可以帮助你处理各种复杂的日志分析需求。
而 Loki 则更适合对日志量大但查询要求相对简单的场景。特别是在 Kubernetes 环境中,Loki 的轻量和与 Prometheus 的无缝集成,让它成为了首选。
回到我们当时的选择,由于我们的系统主要是微服务架构,且依赖 Kubernetes,最终我们选择了 Loki。它的简洁和低成本在我们的场景下极具吸引力。虽然在日志查询上我们牺牲了一些灵活性,但对比 ELK 的复杂性和资源占用,我们觉得这是一个可以接受的妥协。
如果你的系统环境更复杂,或者需要对日志进行深入分析,那么 ELK 依然是不二之选。但如果你追求轻量、简洁且可扩展的日志解决方案,Loki 值得一试。