· loki / elasticsearch / logging
Loki vs Elasticsearch: Nên chọn stack log nào?
Loki chỉ index label, giảm chi phí lưu trữ; Elasticsearch index toàn bộ, tìm kiếm bất kỳ field nào ngay lập tức. Hướng dẫn thực tế cho dev team năm 2026.
Bởi Ethan · Cập nhật 26 tháng 5, 2026
3.200 từ · 16 phút đọc
Chọn Loki nếu bạn chạy workload Kubernetes hoặc Docker, đã dùng Prometheus và Grafana, và muốn chi phí lưu trữ log rẻ nhất có thể trên S3 hoặc GCS mà không cần vận hành cluster phức tạp. Chọn Elasticsearch nếu bạn cần full-text search ad-hoc trên mọi field của mọi dòng log, chạy workload bảo mật hoặc compliance, hoặc cần analytics nâng cao vượt ra ngoài “hiển thị lỗi của pod X.”
Bài này dành cho ai
SRE, DevOps engineer, và backend developer đang chọn stack log aggregation cho Kubernetes hoặc Docker — đã nghe đến cả Loki lẫn Elasticsearch (hoặc ELK stack) nhưng cần phân tích rõ ràng về cost/complexity/capability để thuyết phục team.
Version được dùng
| Tool | Version | Ghi chú |
|---|---|---|
| Grafana Loki | 3.5.5 | Patch release ngày 11/9/2025 (release) |
| Elasticsearch | 8.19 / 9.x | 8.19 là minor cuối của dòng 8.x (tháng 7/2025); 9.x là dòng hiện tại |
| Grafana | 11.x | Visualization layer cho Loki |
| Kibana | 8.19 / 9.x | Visualization layer cho Elasticsearch |
| Grafana Alloy | latest | Thay thế Promtail làm collection agent cho Loki (Promtail EOL: 2/3/2026) |
Nguồn kiểm chứng: Loki 3.5 release notes — grafana.com/docs/loki/latest/release-notes/v3-5/; Elasticsearch 8.19 EoL note — elastic.co/subscriptions.
Tại sao lựa chọn này quan trọng lúc này
Volume log tăng theo số container. Một Kubernetes cluster 50 node có thể dễ dàng đẩy 50–500 GB/ngày. Ở mức đó, sự khác biệt giữa “index tất cả” (Elasticsearch) và “chỉ index label” (Loki) ảnh hưởng trực tiếp đến chi phí cloud và gánh nặng vận hành — thường chênh lệch một bậc độ lớn.
Loki vượt ngưỡng CNCF Graduated và ra phiên bản 3.x vào năm 2024, với các thay đổi kiến trúc đủ lớn để các bài so sánh viết cho Loki 2.x phần lớn đã lỗi thời. Những thay đổi chính trong 3.x:
- Promtail → Grafana Alloy: telemetry agent hợp nhất metrics, logs, traces, và profiles trong một binary. Promtail vào LTS tháng 2/2025, EOL tháng 3/2026. (InfoQ: Grafana Loki 3.4)
- TSDB index format (khuyến nghị thay cho BoltDB): indexing theo time-series dẫn xuất từ Prometheus, mở khóa các tính năng query mới cho Loki.
- Thanos Object Storage Client tích hợp (3.4): đồng bộ cấu hình storage của Loki với Grafana Mimir và Pyroscope.
- Out-of-order log ingestion (3.4+):
time_sharding_enabled: truechấp nhận log từ bất kỳ thời điểm nào, loại bỏ một điểm đau vận hành lớn.
So sánh kiến trúc: cách mỗi hệ thống index log
Loki — dựa trên label, nén theo chunk
Nguyên tắc thiết kế của Loki: không index nội dung log, chỉ index metadata.
Mỗi log stream được định nghĩa bằng một tập label duy nhất (ví dụ: {namespace="prod", app="api", pod="api-7d9f4b-xyz"}). Loki lưu các dòng log của một tập label nhất định dưới dạng chunk — container nén theo khối — trong object storage (S3, GCS, Azure Blob, hoặc filesystem cục bộ). Index chỉ là một “mục lục” nhỏ ánh xạ từ tập label sang vị trí chunk.
Write path: Grafana Alloy scrape log, gắn label, và đẩy đến Loki Distributor. Distributor hash stream để route đến đúng Ingester, Ingester buffer chunk trong memory. Chunk được flush lên object storage và TSDB index được ghi khi đầy hoặc theo lịch.
Read path: Query Frontend tách LogQL query thành các sub-query và gửi đến Querier. Querier kiểm tra Ingester đang chạy trong memory trước, sau đó lazy-load chunk từ object storage, giải nén, và scan bằng regex/filter. Kết quả được deduplicate và merge.
Ba deployment mode (Loki architecture docs):
| Mode | Phù hợp | Ghi chú |
|---|---|---|
| Single binary | Dev, cluster nhỏ (<100 GB/ngày) | Một process, dễ vận hành nhất |
| Simple scalable | Trung bình (100 GB–1 TB/ngày) | Tách Read/Write/Backend |
| Microservices | Production quy mô lớn | Mỗi component scale độc lập |
Hạn chế then chốt: Loki không được thiết kế cho label có cardinality cao. Dùng pod IP, request ID, hoặc user ID làm label gây ra “cardinality explosion” — hàng nghìn chunk nhỏ, index phình to, hiệu năng giảm. Giới hạn cardinality mặc định là 100,000 stream mỗi tenant; workload thực tế chạm giới hạn này khi team không giữ kỷ luật gắn label. (GitHub issue #2863, Loki cardinality docs)
Elasticsearch — inverted index, full-text search
Elasticsearch dùng inverted index: mỗi từ trong mọi dòng log đều được index, tạo ra ánh xạ term → document. Bất kỳ field nào cũng có thể query ngay — không cần định nghĩa label trước.
Write path: Logstash (hoặc Elastic Agent / Beats) parse và transform log, sau đó ship đến Elasticsearch. Mỗi document được parse dưới dạng JSON, field được extract, và inverted index được build trên mỗi shard. Index shard được lưu trên NVMe/SSD cục bộ cho hiệu năng hot-tier.
Read path: KQL hoặc Lucene query đánh đến coordinating node, node này fan-out đến các shard liên quan. Mỗi shard tìm kiếm index cục bộ song song. Kết quả được merge và trả về.
Index Lifecycle Management (ILM): Elasticsearch tự động di chuyển index qua các phase hot → warm → cold → frozen → delete dựa trên tuổi hoặc kích thước. Điều này cho phép phân tầng chi phí: log mới trên NVMe nhanh, log cũ trên ổ đĩa rẻ hơn hoặc frozen snapshot. (Elastic ILM docs)
Elasticsearch 8.19 / 9.x: Tính năng Streams bổ sung tự động extract field trong Kibana và xử lý cấu hình ILM tự động — giảm đáng kể ma sát khi setup ban đầu. Tính năng vẫn đang phát triển trên dòng 9.x; xem Elastic release notes để biết trạng thái hiện tại.
Hiệu năng và chi phí
Dung lượng lưu trữ
Cấu trúc inverted index của Elasticsearch thường vượt quá kích thước log gốc vì mỗi term đều được index. Loki lưu chunk nén mà không có full-text index, giữ kích thước trên đĩa nhỏ hơn đáng kể. Các team chuyển từ ELK sang Loki liên tục báo cáo giảm đáng kể dung lượng lưu trữ, dù tỷ lệ cụ thể phụ thuộc nhiều vào độ dài log, cardinality field, và cài đặt nén. (Plural.sh comparison)
Khoảng cách thực tế nới rộng ở quy mô lớn. Kubernetes cluster tạo ra hàng trăm GB/ngày sẽ thấy sự chênh lệch lớn về yêu cầu storage giữa cluster Elasticsearch — cần SSD cục bộ cho hot tier — và Loki chạy trên object storage với giá S3/GCS phổ thông.
Latency query
- Query theo label (“hiển thị tất cả lỗi từ api pod trong 1 giờ qua”): Loki thắng — đi thẳng đến đúng tập chunk qua index.
- Full-text query ad-hoc (“tìm mọi dòng log chứa ‘NullPointerException’ trên toàn bộ service”): Elasticsearch thắng — inverted index trả kết quả ngay; Loki phải load và grep mọi chunk có thể match.
Tài nguyên hệ thống
Yêu cầu tối thiểu cho Elasticsearch production (Opster hardware guide):
- 16 GB+ RAM mỗi node (50% cho JVM heap, tối đa ~30 GB)
- 4+ CPU core mỗi node
- SSD nhanh cho hot tier
Ingestion path của Loki nhẹ hơn nhiều. Ingester là component tốn tài nguyên nhất, xử lý hàng nghìn stream mỗi GB RAM. Object storage đảm bảo durability; Loki node stateless và có thể chạy trên các instance phổ thông.
Giá cloud managed
Grafana Cloud (grafana.com/pricing):
| Gói | Bao gồm | Chi phí mỗi GB (trên mức miễn phí) |
|---|---|---|
| Free | 50 GB/tháng, lưu trữ 14 ngày | — |
| Pro | 50 GB đầu tiên bao gồm, lưu trữ 30 ngày | $0.40/GB write + $0.05/GB processing + $0.10/GB/tháng retention |
Elastic Cloud (Observability Serverless) (elastic.co/pricing/serverless-observability) — hiệu lực từ 1/11/2025:
| Gói | Ingest | Retention |
|---|---|---|
| Logs Essentials | từ $0.07/GB | từ $0.017/GB/tháng |
| Complete | từ $0.09/GB | từ $0.019/GB/tháng |
TCO tự host: Các team chuyển từ Elasticsearch self-managed sang Loki trên Kubernetes + S3 thường báo cáo giảm chi phí đáng kể — chủ yếu do Loki không cần node RAM cao, IOPS cao để lưu log. (Plural.sh comparison)
Độ phức tạp vận hành
Cài đặt
Loki (Helm, Kubernetes):
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install loki grafana/loki-stack \
--set loki.persistence.enabled=true \
--set loki.persistence.size=10Gi
Single binary mode đủ dùng cho hầu hết team bắt đầu. Thêm Grafana Alloy làm collection agent (bắt buộc trong Loki 3.x — Promtail EOL tháng 3/2026).
Elasticsearch (ECK operator, Kubernetes):
Lưu ý: ECK ra bản mới thường xuyên. Các lệnh dưới đây dùng v3.4.0 (phiên bản hiện tại tính đến tháng 5/2026). Kiểm tra ECK quickstart để lấy version mới nhất trước khi cài.
# Install ECK operator
kubectl create -f https://download.elastic.co/downloads/eck/3.4.0/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/3.4.0/operator.yaml
# Deploy via Helm
helm repo add elastic https://helm.elastic.co
helm install es-quickstart elastic/eck-stack \
-n elastic-stack --create-namespace \
--set=eck-kibana.enabled=true
Cần quản lý persistent volume với storage nhanh cho hot tier. ILM policy cần cấu hình ngay từ đầu cho production.
Alerting
Loki có component Ruler native (Loki alerting docs) liên tục đánh giá LogQL expression và bắn alert qua Alertmanager — quy trình giống hệt Prometheus. Không cần tool bổ sung. Hỗ trợ:
- Alert rule dựa trên LogQL
- Recording rule (metrics tính sẵn, ghi vào Prometheus/Mimir/Thanos)
- Horizontal scaling qua hash ring
Elasticsearch alerting cần Watcher của Kibana (X-Pack, bao gồm trong Basic license) hoặc Kibana Alerts & Rules UI mới hơn. Tính năng alerting đầy đủ (action connector cho PagerDuty, Slack, v.v.) có sẵn từ gói Basic miễn phí. Alerting phát hiện anomaly ML-based nâng cao cần Platinum/Enterprise. (Elastic subscriptions)
Dashboard
- Loki: Grafana là UI native. Tích hợp sâu: Explore view, tương quan logs-metrics, dashboard hợp nhất trộn Prometheus metrics và Loki logs.
- Elasticsearch: Kibana. Mạnh hơn cho data exploration ad-hoc, Lens visualization, Canvas cho custom report. Tích hợp metrics lỏng hơn (dù Elastic Observability bundle APM + metrics + logs).
Kỷ luật cardinality (điểm đau vận hành đặc thù của Loki)
Vấn đề lớn nhất sau ngày đầu với Loki: cardinality. Team nào gắn label log với giá trị cardinality cao (user ID, IP address, request ID) sẽ chạm giới hạn 100,000 stream mặc định và gặp memory spike, query chậm, và chunk storm. (GitHub issue #2863, cardinality docs)
Cách xử lý: Giữ label set nhỏ và tĩnh. Dùng relabeling rule của Grafana Alloy để drop hoặc hash giá trị cardinality cao trước khi chúng đến Loki. Để mọi thứ khác trong dòng log và dùng LogQL filter expression.
Bảng so sánh nhanh
| Tiêu chí | Loki 3.5 | Elasticsearch 8.19/9.x |
|---|---|---|
| Model index | Chỉ label (metadata) | Full-text inverted index |
| Query language | LogQL | KQL / Lucene |
| Storage backend | Object storage (S3, GCS) | SSD / NVMe cục bộ + tiering tùy chọn |
| Chi phí storage | Nhỏ hơn đáng kể (chunk nén, không full-text index) | Thường vượt kích thước log gốc (inverted index overhead) |
| RAM self-hosted (prod) | Thấp (stateless, instance phổ thông) | 16 GB+ mỗi node |
| Full-text search ad-hoc | Chậm (chunk scan) | Nhanh (inverted index) |
| Query theo label | Nhanh | Nhanh (nếu đã index) |
| Hỗ trợ high-cardinality | Kém (giới hạn thiết kế) | Tốt |
| Alerting | Native (Ruler + LogQL) | Native (Watcher, Kibana Rules) |
| Visualization | Grafana | Kibana |
| Kubernetes-native | Có (Alloy DaemonSet) | Có (Elastic Agent / Beats) |
| Cloud managed | Grafana Cloud (50 GB miễn phí) | Elastic Cloud (Serverless, pay-per-use) |
| Open-source license | AGPLv3 | SSPL / Elastic License 2.0 |
Khi nào nên chọn Loki
- Bạn đã dùng Prometheus + Grafana — Loki tích hợp mà không cần thêm tool. Nếu bạn muốn hoàn thiện stack observability, kết hợp Loki với HTTP check là hướng phổ biến; xem Best Uptime Monitor 2026 để so sánh các lựa chọn tích hợp được với Grafana alerting.
- Query của bạn theo label: “hiển thị lỗi từ namespace=prod, app=payments trong 2h qua.” Đây là 90% trường hợp troubleshooting vận hành.
- Bạn chạy Kubernetes và muốn collection DaemonSet với Grafana Alloy — label từ pod metadata (namespace, app, pod name) ánh xạ tự nhiên vào model của Loki.
- Chi phí là ràng buộc: log trên object storage theo giá S3 so với Elasticsearch node SSD là khoảng cách TCO lớn ở quy mô.
- Bạn bắt đầu greenfield: Loki single-binary mode hoạt động trong vài phút.
- Bạn muốn dùng free tier của Grafana Cloud: 50 GB/tháng — đủ cho dự án nhỏ đến trung bình.
Khi nào nên chọn Elasticsearch
- Bạn cần full-text search ad-hoc: “tìm mọi occurrence của ‘out of memory’ trên toàn bộ service mà không biết namespace hay pod nào.” Không cần định nghĩa label trước.
- Bạn chạy workload security / SIEM: threat hunting, forensics, và compliance thường cần query field tùy ý sau sự kiện. ELK stack có hệ sinh thái bảo mật trưởng thành (Elastic SIEM, Elastic Security). Nếu bạn cũng đang đánh giá APM và error tracking song song với log stack, Sentry vs Datadog so sánh chi tiết — Datadog bao gồm log management trong bộ full-stack observability.
- Bạn cần analytics nâng cao: Lens visualization của Kibana, aggregation, và aggregation framework của Elasticsearch vượt xa những gì log panel của Grafana hỗ trợ.
- Log format của bạn không có cấu trúc và biến đổi trên nhiều service: pipeline của Logstash xử lý multi-format ingestion phức tạp linh hoạt hơn relabeling rule của Alloy.
- Bạn đã có đầu tư ELK hiện tại: chuyển sang Loki không miễn phí. Nếu team đã quen Kibana và KQL, chi phí vận hành khi chuyển đổi có thể không bù lại được tiết kiệm storage.
- Bạn cần retention chi tiết theo từng index với migration tier tự động: ILM policy cho kiểm soát chính xác transition hot/warm/cold/frozen/delete.
Bắt đầu nhanh: Loki trên Kubernetes (Helm)
# 1. Thêm Grafana Helm repo
helm repo add grafana https://grafana.github.io/helm-charts && helm repo update
# 2. Cài Loki stack (Loki + Grafana Alloy làm collector)
helm install loki grafana/loki-stack \
--set loki.persistence.enabled=true \
--set loki.persistence.size=50Gi \
--set grafana.enabled=true
# 3. Lấy Grafana admin password
kubectl get secret loki-grafana -o jsonpath="{.data.admin-password}" | base64 --decode
# 4. Port-forward Grafana và đăng nhập
kubectl port-forward svc/loki-grafana 3000:80
# 5. Trong Grafana → Explore → chọn Loki datasource → query:
# {namespace="default"} |= "error"
Cho production: chuyển sang chart grafana/loki ở mode Simple Scalable và cấu hình S3 bucket làm storage backend. Xem Loki sizing guidance để ước lượng CPU/memory theo ingestion volume.
Bắt đầu nhanh: Elasticsearch + Kibana trên Kubernetes (ECK)
Lưu ý: ECK ra bản mới thường xuyên. Các lệnh dưới đây dùng v3.4.0 (phiên bản hiện tại tính đến tháng 5/2026). Kiểm tra ECK quickstart để lấy version mới nhất trước khi cài.
# 1. Cài ECK CRD và operator
kubectl create -f https://download.elastic.co/downloads/eck/3.4.0/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/3.4.0/operator.yaml
# 2. Tạo Elasticsearch cluster tối giản (1 node, dùng cho dev)
cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 8.19.0
nodeSets:
- name: default
count: 1
config:
node.store.allow_mmap: false
EOF
# 3. Cài Kibana
cat <<EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: quickstart
spec:
version: 8.19.0
count: 1
elasticsearchRef:
name: quickstart
EOF
# 4. Lấy Elasticsearch credentials và truy cập Kibana
kubectl get secret quickstart-es-elastic-user \
-o=jsonpath='{.data.elastic}' | base64 --decode
kubectl port-forward svc/quickstart-kb-http 5601
# 5. Deploy Elastic Agent dạng DaemonSet để thu thập log
# (qua Fleet trong Kibana, hoặc standalone manifest)
Cho production: thêm persistent volume claim với storage nhanh, cấu hình ILM policy, và bật multi-node topology với master và data node chuyên dụng.
Kết luận
Quyết định rút gọn về một câu hỏi: bạn có cần search nội dung log mà bạn chưa index sẵn không?
Nếu query log của bạn luôn được giới hạn bởi metadata workload (namespace, service, pod, environment), Loki đáp ứng được điều đó với chi phí storage và vận hành thấp hơn nhiều. Object storage backend, ingestion nhẹ, và tích hợp chặt chẽ với Grafana khiến nó trở thành lựa chọn mặc định phù hợp cho Kubernetes-native team năm 2026.
Nếu bạn cần đặt câu hỏi tùy ý với log sau sự kiện — ai có StatusCode=500 trên tất cả service thứ Ba tuần trước, hoặc request nào chứa một chuỗi payload cụ thể — inverted index của Elasticsearch là câu trả lời. Tốn kém hơn và đòi hỏi chăm chút vận hành hơn, nhưng khả năng query đó về mặt cấu trúc không thể thêm vào Loki mà không cần thiết kế lại.
Hướng thực tế: bắt đầu với Loki. Nếu bạn chạm trần — log shape có cardinality cao, nhu cầu forensics bảo mật, hoặc query spanning toàn bộ log corpus mà không có label định nghĩa sẵn — Elasticsearch là bước nâng cấp tiếp theo, không phải điểm xuất phát.
Lưu ý quan trọng
- So sánh chi phí storage trong bài này mang tính định tính, không phải đo lường trên workload cụ thể của bạn. Độ dài log, field cardinality, và cài đặt nén ảnh hưởng lớn đến kích thước thực trên đĩa — hãy benchmark dữ liệu của bạn trước khi cam kết ngân sách.
- Giá cloud thay đổi thường xuyên. Kiểm tra lại giá Grafana Cloud và Elastic Cloud Serverless hiện hành trước khi cam kết ngân sách.
- Chúng tôi không chạy hai stack này đối đầu trực tiếp trên workload production giống hệt nhau. Dữ liệu benchmark được trích dẫn từ các bài so sánh bên thứ ba.
- Bài viết có chứa affiliate link đến Grafana Cloud và Elastic Cloud. Điều này không ảnh hưởng đến đánh giá.
Nguồn tham khảo
- Grafana Loki overview — docs chính thức
- Grafana Loki architecture — component, storage, deployment mode
- Loki 3.5 release notes — tính năng version mới nhất
- Loki 3.4 release notes — InfoQ — Thanos storage, Alloy migration, out-of-order logs
- Loki cardinality documentation — hướng dẫn cardinality chính thức
- Loki ruler / alerting docs — kiến trúc alerting native
- Loki GitHub — grafana/loki — issue, release, changelog
- GitHub issue #2863 — cardinality limit exceeded — pain point thực tế
- Elasticsearch ILM docs — lifecycle management
- Elastic Observability Serverless pricing — giá từ tháng 11/2025
- Elastic subscriptions page — license tier, tính năng
- Grafana Cloud pricing — free tier, giá Pro
- Opster — Elasticsearch hardware requirements — sizing node production
- Plural.sh — Loki vs ELK on Kubernetes — so sánh chi phí và kiến trúc
- SigNoz — Loki vs Elasticsearch — so sánh tính năng