Lazy loaded image
Lazy loaded imageOpenObserve
字数 5730阅读时长 15 分钟
2026-4-14
2026-4-14
type
Post
status
Published
date
Apr 14, 2026
slug
OpenObserve
summary
tags
OpenObserve
category
日志
icon
password

OpenObserve

OpenObserve 是一个云原生可观测性平台,可将日志、指标和跟踪统一到一个强大的解决方案中。OpenObserve 专为现代云环境而构建,可提供企业级可观测性,而成本和复杂性仅为传统解决方案的一小部分。与需要理解和调整大量配置的 Elasticsearch 相比,它简单且易于操作。在 2 分钟内即可启动并运行 OpenObserve。对于使用 API 获取数据并执行搜索的用户来说,OpenObserve 可以无缝替代 Elasticsearch。OpenObserve 带有自己的用户界面,无需单独安装。与 Elasticsearch 相比,使用 OpenObserve 可以将日志存储成本降低约 140 倍。
notion image
相关概念: Organizations(组织):组织是最高层的隔离单位,相当于多租户中的租户,它拥有以下特性:不同组织的数据物理隔离;每个组织有自己的存储策略、保留策略;用户只能访问所属组织。 Streams(流):逻辑数据容器,相当于数据库中的表。支持日志(logs)、指标(metrics)、追踪(traces) Functions:OpenObserve 中的函数可在摄取和查询期间使用,以帮助增强高级功能,如丰富、编辑、日志缩减、合规性等。函数是使用 VRL 脚本定义的。 Parquet:Parquet 是一种开源的列式存储文件格式,专为大规模数据处理而设计。它最初由 Cloudera 和 Twitter 共同开发,现已成为 Apache 顶级项目,是大数据生态系统的核心存储格式之一。 Timestamp(时间戳):_timestamp 在 OpenObserve 中被视为时间戳列,如果 _timestamp 或 @timestamp 不存在于正在摄取的数据中,我们会将 _timestamp 添加到每个记录,其 NOW 值为微秒精度。 User Role(用户角色):OpenObserve 中的用户可以具有 admin 或 member 角色。与具有 member 角色的用户相比,具有 admin 角色的用户拥有更大的权限,例如,具有 admin 角色的用户可以将其他用户添加到组织中。 Schemas(模式):动态模式,自动推断字段类型,支持字段添加/修改。静态模式(可选)

部署

OpenObserve 可以在集群中的单节点或 HA 模式下运行

单节点模式

单节点模式也分为几种架构,主要是数据存储方式不同,主要有以下几种: SQLite 和本地磁盘模式:如果你只需要进行简单使用和测试,或者对高可用性没有要求,可以使用此模式。当然你仍然可以在一台机器上每天处理超过 2 TB 的数据。在我们的测试中,使用默认配置,Mac M2 的处理速度为约 31 MB/秒,即每分钟处理 1.8 GB,每天处理 2.6 TB。该模式也是运行 OpenObserve 的默认模式。
notion image
SQLite 和对象存储模式:该模式和 OpenObserve 的默认模式基本上一致,只是数据存在了对象存储中,这样可以更好的支持高可用性,因为数据不会丢失。
notion image

高可用模式

HA 模式不支持本地磁盘存储,该模式下,OpenObserve 主要包括 Router、Querier、Ingester、Compactor 和 AlertManager 节点(组件),这些节点都可以水平扩展以适应更高的流量。另外使用 Etcd 或 NATS 用作集群协调器并存储节点信息,还用于集群事件。MySQL/PostgreSQL 用于存储组织、用户、函数、报警规则、流模式和文件列表(parquet 文件的索引)等元数据。对象存储(例如 s3、minio、gcs 等)存储 parquet 文件的数据
notion image
Router、Querier、Ingester、Compactor 和 AlertManager 节点都可以水平扩展以适应更高的流量。 NATS 用作集群协调器并存储节点信息,它还用于集群事件。 MySQL / PostgreSQL 用于存储元数据,如组织、用户、函数、警报规则、流模式和文件列表(parquet 文件的索引)。 对象存储(例如 s3、minio、gcs 等)存储 parquet 文件的所有数据。
notion image

Ingester

Ingester 用于接收摄取请求并将数据转换为 parquet 格式然后存储在对象存储中,它们在将数据传输到对象存储之前将数据临时存储在 WAL 中。OpenObserve 中摄取的数据默认根据年月日和小时进行分区,我们还可以指定用于对数据进行分区的分区键。
notion image
数据摄取流程如下所示:
notion image
1、从 HTTP / gRPC API 请求接收数据。 2、逐行解析数据。 3、检查是否有任何用于转换数据的函数(摄取函数),按函数顺序调用每个摄取函数 4、检查时间戳字段,将时间戳转换为微秒;如果记录中不存在时间戳字段,则设置当前时间戳。 5、检查流 schema 以确定 schema 是否需要演变。在这里,如果我们发现需要更新 schema 以添加新字段或更改现有字段的数据类型,则获取 lock 来更新 schema。 6、评估实时报警(如果为流定义了任何报警)。 7、按小时桶中的时间戳写入 WAL 文件,然后将请求中的记录转换为 Arrow RecordBatch 并写入 Memtable。为每个 organization/stream_type 创建 Memtable,如果仅为日志摄取数据,则只有一个 Memtable。WAL 文件和 Metable 是成对创建的,一个 WAL 文件有一个 Memtable 。WAL 文件位于 data/wal/logs。 8、当 Memtable 大小达到 ZO_MAX_FILE_SIZE_IN_MEMORY = 256MB 或 WAL 文件达到 ZO_MAX_FILE_SIZE_ON_DISK = 128MB 时,我们将 Memtable 移动到 Immutable 并创建一个新的 Memtable 和 WAL 文件用于写入数据。 9、每 ZO_MEM_PERSIST_INTERVAL=5 秒会将 Immutable 转储到本地磁盘。一个 Immutable 将生成多个 parquet 文件,因为它可能包含多个流和多个分区,parquet 文件位于 data/wal/files。 10、每 ZO_FILE_PUSH_INTERVAL=10 秒,我们检查本地 parquet 文件,如果任何分区总大小超过 ZO_MAX_FILE_SIZE_ON_DISK=128MB 或任何文件已在 ZO_MAX_FILE_RETENTION_TIME=600 秒前,分区中的所有此类小文件将被合并为一个大文件(每个大文件将最大为 ZO_COMPACT_MAX_FILE_SIZE=256MB) ,它将被移动到对象存储。
Ingester 包含三部分数据,这些数据都需要能够被查询到: Memtable 中的数据 Immutable 中的数据 WAL 中的 parquet 文件尚未上传到对象存储

Router

Router(路由器)将请求分发给 ingester 或 querier,它还通过浏览器提供 UI 界面,Router 实际上就是一个非常简单的代理,用于在摄取器和查询器之间发送适当的请求

Querier(查询器)

Querier(查询器)用于查询数据,查询器节点是完全无状态的。数据查询流程如下:
notion image
1、使用 http API 接收搜索请求。接收到查询请求的节点成为该查询的 LEADER 查询器。其他查询器都是 WORKER 查询器,用于查询。 2、LEADER 解析并验证 SQL。 3、LEADER 找到数据时间范围并从文件列表索引中获取文件列表。 4、LEADER 从集群元数据中获取查询器节点。 5、LEADER 对每个查询器要查询的文件列表进行分区。例如如果需要查询 100 个文件,并且有 5 个查询器节点,则每个查询器可以查询 20 个文件,LEADER 处理 20 个文件,WORKERS 各处理 20 个文件。 6、LEADER 调用每个 WORKER 查询器上运行的 gRPC 服务,将搜索查询分派到查询器节点。查询器间通信使用 gRPC 进行。 7、LEADER 收集、合并并将结果发送回用户。
默认情况下,查询器将在内存中缓存 parquet 文件。我们可以使用环境变量 ZO_MEMORY_CACHE_MAX_SIZE 配置查询器用于缓存的内存大小。默认缓存是使用特定查询器可用内存的 50% 来完成的。在分布式环境中,每个查询器节点只会缓存一部分数据。我们还可以选择在内存中缓存最新的 parquet 文件。当 Ingester 生成新的 Parquet 文件并将其上传到对象存储时,Ingester 将通知查询器缓存该文件。

Compactor(压缩器)

Compactor(压缩器)会将小文件合并成大文件,使搜索更加高效。Compactor 还处理数据保留策略、full stream 删除和文件列表索引更新。

AlertManager

AlertManager 运行标准报警查询、报告作业并发送通知

高可用部署

虽然 OpenObserve 可以在裸机服务器、虚拟机、Kubernetes 和其他可能的平台上以 HA 模式安装和运行,目前正式提供使用 helm chart 的安装。HA 模式下不支持本地磁盘存储,因此必须配置对象存储。这里我们选择使用 PostgreSQL 作为元数据存储,Minio 作为对象存储,Nats 作为集群协调器(建议使用 Nats,为了向后兼容,目前仍然支持 Etcd)。本地环境已经部署了NFS。
添加仓库
官方的这个 Helm Chart 默认会部署 PostgreSQL,但是需要提前安装对应的 cloudnative-pg operator:
检查部署好的cnpg
然后我们就可以在 Helm Chart 中使用 PostgreSQL 了,此外为了启用 Minio 和 Nats,我们需要在 values.yaml 中进行配置
修改后的 values.yaml 如下所示,这里只贴修改的代码
部署openobserve
安装完成后,我们查看是否正常运行
通过 NODE_IP:31197 访问 Openobserve 的 Web 界面,然后就可以开始使用了。这个账号密码就是刚才在 values.yaml 中配置的 auth 字段的 ZO_ROOT_USER_EMAIL、ZO_ROOT_USER_PASSWORD
notion image
现在我们还没有向 Openobserve 中发送任何数据,所以暂时没有任何数据。我们可以切换到采集页面,里面就有各种遥测数据的采集方式。数据源 → 自定义 → FluentBit
notion image
这里我们可以先使用 JSON API 来加载一些示例日志数据,来了解一下 OpenObserve 的基本使用方法。先使用下面命令下载示例日志数据:
然后使用下面命令将示例日志数据导入到 OpenObserve 中:
刷新主页就可以看到数据了
notion image
在数据流页面可以看到我们导入的数据元信息:
notion image
然后切换到日志页面,从左侧的下拉列表中选择索引为 default,就可以看到日志数据了:
notion image
现在我们就可以去根据直接的需求去查询日志了,比如要使用倒排索引搜索包含单词 error 的所有字段:在查询编辑器中使用 match_all('error')。match_all 仅搜索配置为全文搜索的字段。默认字段集包括 log、message、content、data、events、json。如果你希望全文搜索时扫描更多字段,可以在数据流页面进行配置。在特定字段中进行全文搜索应该使用 str_match 函数。
notion image
要在没有倒排索引的情况下搜索包含单词 error 的所有字段: match_all('error')区分大小写,match_all_raw_ignore_case(error)这是不区分大小写的。match_all_raw 函数仅搜索配置为全文搜索的字段。默认字段集是 log、message、content、data、events、json。如果希望全文搜索时扫描更多字段,可以在数据流设置下进行配置。应该使用 str_match 在指定字段中进行全文搜索。如果仅搜索 log 字段中的 error,可以使用 str_match(log, 'error'),这比 match_all_raw 更有效,因为它在单个字段中搜索。
同样如果我们要搜索包含 code 为 200 的所有日志条目,则可以直接使用 code=200 查询即可,其中 code 是一个数字字段。如果要搜索 code 字段不包含任何值的所有日志条目,可以使用 code is null,但是需要注意使用 code=' ' 不会产生正确的结果;同样的搜索 code 字段具有某个值的所有日志条目,则可以使用 code is not null,但是不能使用 code!=’ '。另外也可以使用 code > 399 或者 code >= 400 来搜索 code 大于 399 或者大于等于 400 的所有日志条目。此外我们还可以勾选 SQL 模式 来使用 SQL 查询语句来查询日志数据:
notion image
同样现在我们可以去 Minio 中查看数据是否已经被正确的存储,使用用户名 root 和密码 OpenObserve 即可登录成功。可以看到对象存储中已经有了我们的 parquet 文件数据
notion image

采集 Kubernetes 观测数据

部署 certmanager

Openobserve 还支持通过 OpenTelemetry 采集器导入数据。这里我们可以使用 OpenTelemetry 来采集 Kubernetes 集群的观测数据,首先我们需要安装 OpenTelemetry 的 Operator,由于 OpenTelemetry 的 Operator 依赖 cert-manager,所以我们需要先安装 cert-manager:
查看部署
notion image

部署 OpenTelemetry Operator

等待 cert-manager 安装完成后,我们就可以安装 OpenTelemetry 的 Operator 了:
查看部署
notion image
然后我们就可以来安装 OpenTelemetry 的 Collector 了,为了方便使用 Openobserve 官方的 Helm Chart 已经提供了一个定制的 Chart 包,我们可以直接使用它,该采集器可以从 Kubernetes 集群中捕获日志、指标和 Events 事件并将其发送到 OpenObserve。在集群中配置 auto-instrumentation 自动埋点,以捕获 Java、.Net、nodejs、python 和 Go 语言编写的应用程序的链路追踪。

collector 采集器

使用我们这里安装的 Openobserve 集群的认证信息覆盖默认的认证信息:
其中 endpoint 地址为 Openobserve 的 router 的 FQDN 地址,Authorization 中 Basic 后面的值为用户名:TOKEN的 base64 编码(可以在 Openoobserve 采集页面获取,如下图),stream-name 为数据流名称
notion image
然后直接使用下面命令安装 OpenTelemetry 的 Collector 即可:
查看 OpenTelemetry 的 Collector 是否正常运行:
notion image
现在我们就可以去 Openobserve 中查看我们的数据了,切换到数据流页面,可以看到我们的数据流已经被成功的导入了:
notion image
可以看到现在我们的数据流中已经有了 k8s_logs 和 k8s_events 两个日志数据流,分别对应我们的日志和事件数据。除此之外还有很多 metrics 类型的数据流,可以看到指标中的每一个标签都是一个独立的 stream 数据流。
notion image

查看 k8s 日志

我们可以切换到日志页面,选择数据流 k8s_logs,就可以看到我们采集的 K8s 集群的日志数据了:
notion image
同样我们选择数据流 k8s_events,就可以看到我们采集的 K8s 集群的事件数据了:
notion image

查看 k8s 指标

对于指标数据流,我们可以切换到指标页面,选择数据流 k8s_metrics,就可以看到我们采集的 K8s 集群指标数据了:
notion image
左侧我们可以选择一个指标,然后就可以看到这个指标的标签列表,然后我们就可以在右侧填写 PromQL 语句来查询数据了,比如我们这里查询每个命名空间的内存使用情况,则可以使用下面的 PromQL 语句:sum(k8s_pod_memory_usage) by (k8s_namespace_name)
notion image
如果我们需要经常查询这个指标,这可以将其添加到仪表盘中,点击页面中的添加到仪表盘按钮即可,然后在仪表盘页面就可以看到我们的仪表盘了
notion image
和 Grafana 类似,我们也可以编辑面板,在面板右上角点击Edit Panel,就可以进入面板编辑页面了,点击最右侧的配置按钮,就可以编辑面板了,比如我们这里可以选择图例的单位、图例的显示名称等,编辑后可以点击应用按钮预览,如果满意可以点击保存按钮保存
notion image
同样我们也可以和 Grafana 一样配置一个变量,然后在面板上展示这个变量,比如我们这合理可以添加一个 namespace 变量,其值可以从 k8s_namespace_phase 这个数据流中获取,如下图所示:
notion image
notion image
当然现在我们需要去修改下面板的 PromQL 查询语句,需要将变量 namespace 传入,更改成:sum(k8s_pod_memory_usage{k8s_namespace_name =~ "$namespace"}) by (k8s_namespace_name) 即可:
notion image
现在我们就可以在面板上通过筛选 namespace 变量来查看不同命名空间的内存使用情况了:
notion image

自动埋点

接下来还有链路追踪的数据,因为上面我们安装的 OpenTelemetry 的 Collector 已经自动为我们创建了自动埋点的 Instrumentation 对象,如下所示:
notion image
针对上面的这些语言编写的应用,我们就可以进行自动埋点,只需要在应用的 Pod 中添加对应的 Annotation 即可: Java: instrumentation.opentelemetry.io/inject-java: "openobserve-collector/openobserve-java" DotNet: instrumentation.opentelemetry.io/inject-dotnet: "openobserve-collector/openobserve-dotnet" NodeJS: instrumentation.opentelemetry.io/inject-nodejs: "openobserve-collector/openobserve-nodejs" Python: instrumentation.opentelemetry.io/inject-python: "openobserve-collector/openobserve-python" Go (Uses eBPF): instrumentation.opentelemetry.io/inject-go: "openobserve-collector/openobserve-go" instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/path/to/container/executable"
这里我们可以部署一个微服务 HOT Commerce 来演示在 Kubernetes 环境中如何使用 OpenTelemetry Operator 进行自动埋点,并将数据发送到 OpenObserve 中。这个应用包含 5 个简单的微服务,每个微服务都是用不同的编程语言编写的:
该应用对应的 Kubernetes 资源清单文件如下,注意下面的每个 Deployment 应用中,我们都添加了对应的 instrumentation.opentelemetry.io/inject-xxx 的 Annotation,这样就可以实现自动埋点了。
注意上面的每个 Deployment 应用中,我们都添加了对应的 instrumentation.opentelemetry.io/inject-xxx 的 Annotation,这样就可以实现自动埋点了。直接使用下面命令部署 HOT Commerce 应用即可
部署完成后,我们先查看所有的服务是否正常运行
notion image
我们可以通过 http://:30100访问 frontend 服务了,当我们访问 frontend 服务时,OpenTelemetry 会自动为我们的应用程序生成链路追踪数据,并将其发送到 OpenTelemetry Collector,然后 Collector 会将数据发送到 OpenObserve 中
然后我们就可以在 Openobserve 中查看到有 traces 类型的数据流了。切换到追踪页面,就可以看到我们采集到的链路追踪数据了:
notion image
点击一个 Trace ID,就可以查看这个链路追踪的详细信息了:
notion image
这里我们可以看到这个链路追踪的详细信息,包括每个服务的调用时间、调用耗时、调用结果等信息
notion image
到这里我们就实现了在 OpenObserve 中查看我们的 K8s 集群的观测数据,当然同样的对于非 K8s 集群的应用也可以直接将数据采集到 OpenObserve 中,比如 Fluentd、Vector、Prometheus、OpenTelemetry Collector 等。
上一篇
EFK
下一篇
git/github/gitlab