使用 Vector 和 ClickHouse 采集 OpenResty Edge 日志

本文介绍如何使用 Vector 采集 OpenResty Edge Node 的日志, 并将日志集中写入 ClickHouse。ClickHouse 通过 Docker Compose 部署在独立的 数据库服务器上,Vector 以 systemd 服务的形式部署在每台 Edge Node 上。

Edge Node 日志文件 -> 本机 Vector -> HTTPS -> ClickHouse

采集范围

部署完成后,Vector 将日志写入 app 数据库中的三个表:

日志类型Edge Node 默认日志文件ClickHouse 表
HTTP 访问日志access.lognginx_http_access_logs
TCP/UDP Stream 访问日志stream_access.lognginx_stream_access_logs
NGINX 错误日志(可选)*error*.lognginx_error_logs

HTTP 和 Stream 访问日志必须使用部署包提供的 JSON 格式。Vector 会解析默认格式的 NGINX 错误日志。解析失败的日志不会被丢弃,其 parsed_ok 字段为 0,原始内容保存在 raw_message 字段中。

错误日志采集是可选的。如果不需要将错误日志写入 ClickHouse,请在部署 Vector 前从 edge-vector-deployment/vector.yaml 中删除以下三个完整配置块:

  • sources.nginx_error
  • transforms.normalize_error
  • sinks.clickhouse_error

删除 Vector 中的采集配置即可,不要删除 Edge Node 上的原始错误日志文件。 ClickHouse 中未使用的 nginx_error_logs 空表可以保留,不会写入错误日志数据。

部署准备

准备一台 ClickHouse 服务器以及至少一台已加入 Edge Admin 的 Edge Node。

主机要求
ClickHouse 服务器Docker 或 Podman、对应的 Compose 插件、OpenSSL、持久化磁盘以及 TLS 证书
Edge Nodesystemd、可用的 openresty-vector 软件仓库以及读取 Edge 日志的权限

本文使用以下示例值,请按实际环境替换:

配置示例值
ClickHouse 部署目录/opt/edge-clickhouse-deployment
Vector 部署目录/opt/edge-vector-deployment
ClickHouse 域名clickhouse.example.com
ClickHouse 对外 HTTPS 端口443
ClickHouse 监听地址0.0.0.0
日志保留时间365

交付文件包含两个版本配套的压缩包。以下以 1.0.0 版本为例:

文件部署位置用途
edge-clickhouse-deployment-1.0.0.tar.gzClickHouse 服务器部署 ClickHouse、初始化日志表和账号
edge-vector-deployment-1.0.0.tar.gz每台 Edge Node配置 Edge 日志格式并部署 Vector

在 ClickHouse 服务器上解压

edge-clickhouse-deployment-1.0.0.tar.gz 下载到 ClickHouse 服务器的 /opt 目录并 解压:

cd /opt
sudo curl -O https://openresty.com/client/oredge/edge-clickhouse-deployment-1.0.0.tar.gz
sudo tar -xzf edge-clickhouse-deployment-1.0.0.tar.gz

解压后的目录结构如下:

/opt/
└── edge-clickhouse-deployment/
    ├── .env.example
    ├── auto-deploy.sh
    ├── certs/
    ├── config.d/
    ├── docker-compose.yml
    ├── initdb/
    └── users.d/

在 Edge Node 上解压

edge-vector-deployment-1.0.0.tar.gz 下载到每台 Edge Node 的 /opt 目录并解压:

cd /opt
sudo curl -O https://openresty.com/client/oredge/edge-vector-deployment-1.0.0.tar.gz
sudo tar -xzf edge-vector-deployment-1.0.0.tar.gz

解压后的目录结构如下:

/opt/
└── edge-vector-deployment/
    ├── auto-deploy.sh
    ├── systemd/
    ├── vector.env.example
    └── vector.yaml

解压后的部署目录不带版本号,始终使用 /opt/edge-clickhouse-deployment/opt/edge-vector-deployment。两个压缩包的版本必须一致;固定目录名可以避免版本 变化影响部署和升级脚本中的路径。

确认各主机的时间和时区配置正确。ClickHouse 表以 UTC 保存时间;查询客户端可以按需 转换显示时区。为 clickhouse.example.com 准备由客户端信任的 CA 签发的服务器 证书,证书的 Subject Alternative Name 必须包含该域名。公网服务建议使用受公共信任 的 CA;使用组织内部 CA 时,需要将 CA 证书部署到每台 Edge Node。

配置 Edge 访问日志

配置 HTTP 访问日志格式

  1. 登录 Edge Admin,进入 全局配置 > 通用 > 日志

  2. 使用以下任一方式配置 HTTP 访问日志格式:

    • 修改默认的 main 格式。
    • 新增一个名为 vector-json 的格式,并将其设置为默认访问日志格式。
  3. 将所选格式的内容替换为:

    {
    "app_id": $app_id,
    "timestamp":"$time_iso8601",
    "remote_addr":"$remote_addr",
    "remote_user":"$remote_user",
    "http_host":"$http_host",
    "request":"$request",
    "status":$status,
    "body_bytes_sent":$body_bytes_sent,
    "request_time":$request_time,
    "http_referer":"$http_referer",
    "http_user_agent":"$http_user_agent",
    "upstream_addr":"$upstream_addr",
    "upstream_status":"$upstream_status",
    "upstream_connect_time":"$upstream_connect_time",
    "upstream_header_time":"$upstream_header_time",
    "upstream_response_time":"$upstream_response_time",
    "upstream_cache_status":"$upstream_cache_status",
    "pid":$pid,
    "req_id":"$req_id",
    "request_length":$request_length,
    "invalid_referer":"$invalid_referer",
    "internal_request":"$internal_request"
    }
    
  4. Escape(转义) 设置为 json

  5. 检查需要采集日志的 HTTP 应用。使用默认格式的应用会自动采用上述配置;如果应用 显式选择了其他格式,请改为 mainvector-json

  6. 保存并发布配置。

该格式包含应用 ID、请求、状态码、请求耗时和上游耗时等字段。有关可用变量的说明, 请参见OpenResty Edge 的访问日志变量

Edge Admin 发布配置时会自动删除日志格式中的换行符。虽然上述 JSON 为方便阅读采用 多行展示,Edge Node 实际写入时每条日志只占一行,文件格式为 JSON Lines(JSONL)。

配置 Stream 访问日志格式

  1. 全局配置 > 通用 > 日志 中找到 Stream 访问日志格式。

  2. 将原有的空格分隔格式替换为:

    {
    "timestamp":"$time_iso8601",
    "remote_addr":"$remote_addr",
    "protocol":"$protocol",
    "status":$status,
    "bytes_sent":$bytes_sent,
    "bytes_received":$bytes_received,
    "session_time":$session_time,
    "upstream_addr":"$upstream_addr",
    "upstream_bytes_sent":"$upstream_bytes_sent",
    "upstream_bytes_received":"$upstream_bytes_received",
    "upstream_connect_time":"$upstream_connect_time",
    "server_addr":"$server_addr",
    "server_port":$server_port
    }
    
  3. Escape(转义) 设置为 json,保存并发布配置。

JSON 格式使用 $time_iso8601 生成 timestamp,Vector 会将其写入 ClickHouse 的 event_time 字段。其他字段与原有 Stream 访问日志中的连接状态、流量和上游信息 一一对应。Edge Admin 同样会删除该格式中的换行符,因此 Stream 访问日志也是每条 记录占一行的 JSONL。

如果不需要采集 Stream 日志,可以跳过本步骤,并保留 Vector 中相应的采集配置。 在没有匹配文件时,Vector 不会产生 Stream 日志数据。

保持日志格式一致

访问日志格式必须与同一版本 ClickHouse 部署包中的表结构保持一致。两个交付包中的 以下配置是配套的:

  • 本文给出的 HTTP 和 Stream JSON 格式定义 Edge 输出的字段。
  • edge-vector-deployment/vector.yaml 中的 normalize_http_accessnormalize_stream_access 定义字段解析与转换规则。
  • edge-clickhouse-deployment/initdb/001-nginx-logs.sql 定义 ClickHouse 表的列名和 类型。

不要只在 Edge Admin 中增加、删除字段或修改字段类型。如果需要自定义日志格式,必须 同步修改 Vector 转换规则和 ClickHouse 表结构,并在发布前验证三处配置一致。

对齐 Edge 日志文件名

OpenResty Edge 默认使用 stream_access.log,并将轮转文件命名为 access.log_YYYYMMDD.HHMMSS 这类下划线后缀。部署 Vector 前,编辑 edge-vector-deployment/vector.yaml,确认三个 file source 的 include 覆盖当前 日志和未压缩的轮转日志:

sources:
  nginx_http_access:
    include:
      - ${NGINX_LOG_DIR}/access.log
      - ${NGINX_LOG_DIR}/access.log_*

  nginx_stream_access:
    include:
      - ${NGINX_LOG_DIR}/stream_access.log
      - ${NGINX_LOG_DIR}/stream_access.log_*

  nginx_error:
    include:
      - ${NGINX_LOG_DIR}/*error*.log
      - ${NGINX_LOG_DIR}/*error*.log_*
      - ${NGINX_LOG_DIR}/**/*error*.log
      - ${NGINX_LOG_DIR}/**/*error*.log_*

生产环境建议保留轮转日志的匹配规则。Vector 持续运行时会继续读取已经打开的轮转 文件;如果 Vector 停机或重启跨过了轮转时间,access.log_* 等规则可以让它根据 检查点补采未压缩的旧文件。只匹配当前 access.log 适用于允许少量日志丢失的实时 采集场景,不建议用于完整日志留存。

保留各 source 中排除 *.gz 文件的配置,并确保被采集的日志没有启用 Gzip 压缩, 以便 Vector 在故障恢复后补采轮转文件。有关默认路径和轮转方式,请参见 日志文件的路径日志轮转

在 Edge Node 上产生测试流量后,确认 HTTP 访问日志是单行 JSON:

sudo tail -n 1 /usr/local/oredge-node/logs/access.log

部署 ClickHouse

准备服务器证书

在 ClickHouse 服务器的部署目录中创建 certs,并放入证书链和私钥:

edge-clickhouse-deployment/
└── certs/
    ├── server.crt
    └── server.key

server.crt 应包含完整证书链,server.key 不得加密,以便 ClickHouse 无人值守启动。 限制私钥的读取权限,同时确保容器内的 ClickHouse 进程能够读取它。不要将证书私钥 提交到版本控制系统。

启用 ClickHouse HTTPS

部署包中的 edge-clickhouse-deployment/config.d/custom.xml 已默认配置为:

<clickhouse>
    <timezone>UTC</timezone>
    <max_connections>4096</max_connections>
    <listen_host>0.0.0.0</listen_host>
    <http_port>8123</http_port>
    <https_port>443</https_port>
    <tcp_port>9000</tcp_port>
    <openSSL>
        <server>
            <certificateFile>/etc/clickhouse-server/certs/server.crt</certificateFile>
            <privateKeyFile>/etc/clickhouse-server/certs/server.key</privateKeyFile>
            <loadDefaultCAFile>true</loadDefaultCAFile>
            <cacheSessions>true</cacheSessions>
            <disableProtocols>sslv2,sslv3,tlsv1,tlsv1_1</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
        </server>
    </openSSL>
</clickhouse>

部署包中的 edge-clickhouse-deployment/docker-compose.yml 默认挂载证书,但不向 宿主机发布端口。auto-deploy.sh 会根据用户指定的端口生成 docker-compose.ports.yml。例如,使用 --https-port 443 时,生成的端口配置等效于:

services:
  clickhouse:
    ports:
      - "${CLICKHOUSE_BIND_ADDRESS:-0.0.0.0}:443:443"

端口映射左侧是用户指定的宿主机端口,右侧是固定的容器端口。ClickHouse 在容器内 始终监听 HTTPS 443;使用上述参数时,宿主机和容器的端口映射为 443:443

不要删除 Compose 文件中的 healthcheck;它通过容器内部的 HTTP 8123 接口检查 服务。clickhouse-init 同样通过 Compose 内部的 Native TCP 9000 接口完成初始化。 只有显式指定对应的部署参数时,这些端口才会发布到宿主机。

配置环境变量

在 ClickHouse 服务器上执行:

cd /opt/edge-clickhouse-deployment
sudo cp .env.example .env
sudo chmod 600 .env

使用 sudoedit .env 编辑文件,至少修改以下配置:

CLICKHOUSE_TAG=26.3.17.56
CLICKHOUSE_DB=app
CLICKHOUSE_USER=app
CLICKHOUSE_PASSWORD=请替换为强管理密码
CLICKHOUSE_VECTOR_PASSWORD=请替换为强写入密码
CLICKHOUSE_OREDGE_READER_PASSWORD=请替换为强只读密码
CLICKHOUSE_RETENTION_DAYS=365
CLICKHOUSE_BIND_ADDRESS=0.0.0.0

三个账号应使用不同的强密码,可以使用 openssl rand -hex 32 分别生成。.env 包含明文凭据,只允许管理员读取,不要将其提交到版本控制系统。对外端口不再通过 .env 设置,而是在首次运行 auto-deploy.sh 时通过命令行参数指定。

运行自动部署脚本

查看脚本支持的部署参数:

cd /opt/edge-clickhouse-deployment
sudo ./auto-deploy.sh --help

可用的端口参数如下:

参数映射目标用途
--https-port PORT容器 HTTPS 443Vector 和远程 HTTPS 客户端,生产环境推荐使用
--http-port PORT容器 HTTP 8123可选的明文 HTTP 接口,不应向公网开放
--tcp-port PORT容器 Native TCP 9000可选的原生客户端接口,不应向公网开放

如果不指定任何端口参数,脚本不会向宿主机发布端口。本文只需要 HTTPS 接口,建议将 宿主机标准 HTTPS 443 端口映射到容器的 443 端口。

使用 Docker 部署:

cd /opt/edge-clickhouse-deployment
sudo ./auto-deploy.sh --https-port 443

使用 Podman 部署:

cd /opt/edge-clickhouse-deployment
sudo ./auto-deploy.sh --runtime podman --https-port 443

下文以 Docker 命令为例。使用 Podman 时,请将 docker 替换为 podman

端口参数必须在首次部署时指定。如果 ClickHouse 容器已经存在,脚本会直接退出,不会 修改现有容器或 docker-compose.ports.yml

脚本会创建 clickhouse_dataclickhouse_logs 两个外部卷,启动 ClickHouse, 并通过一次性的 clickhouse-init 容器完成以下初始化:

  • 创建三个日志表并配置数据保留时间。
  • 创建仅能写入日志表的 vector 账号。
  • 创建仅能查询日志表的 oredge-reader 账号。

检查容器状态:

sudo docker compose \
    --project-name clickhouse-deployment \
    --file docker-compose.yml \
    --file docker-compose.ports.yml \
    ps --all

clickhouse-init 显示 Exited (0) 是正常现象。ClickHouse 服务应处于运行且健康的 状态。如果初始化失败,请检查其日志:

sudo docker compose \
    --project-name clickhouse-deployment \
    --file docker-compose.yml \
    --file docker-compose.ports.yml \
    logs clickhouse-init

配置网络访问

在防火墙或安全组中开放 --https-port 指定的 TCP 端口。本文使用 443。不要向公网 开放 ClickHouse 的明文 HTTP 和 Native TCP 端口。如果 Edge Node 有固定出口地址, 仍建议限制允许访问 HTTPS 端口的来源范围;不能限制来源时,应使用随机强密码,并在 服务器入口配置连接限速和异常访问监控。

确认 clickhouse.example.com 已解析到 ClickHouse 服务器,然后在每台 Edge Node 上测试 HTTPS 连通性。命令会交互式提示输入 vector 账号的密码:

curl --user vector --data-binary 'SELECT 1' \
    https://clickhouse.example.com/

返回 1 表示 DNS、TLS 证书、端口和凭据均可用。使用组织内部 CA 时,通过 --cacert /path/to/organization-ca.crt 指定 CA 证书。不要使用 --insecure-k 跳过证书校验。如果 --https-port 使用的不是 443,URL 中也必须显式指定 相同端口,例如 https://clickhouse.example.com:8443/

在 Edge Node 上部署 Vector

以下步骤需要在每台要采集日志的 Edge Node 上执行。

配置 Vector HTTPS

部署包中的 edge-vector-deployment/vector.yaml 已在三个 ClickHouse sink 中启用 证书和主机名校验:

tls:
  verify_certificate: true
  verify_hostname: true

运行自动部署脚本,并传入服务器证书所覆盖的域名:

cd /opt/edge-vector-deployment
sudo ./auto-deploy.sh --host clickhouse.example.com

脚本默认使用 HTTPS 443 端口,安全地提示输入 vector 账号密码,并自动完成以下 操作:

  • 安装 openresty-vector 软件包(尚未安装时)。
  • 创建非特权的 vector 系统账号。
  • 安装 Vector 配置、环境变量和 vector-edge.service
  • 验证配置并启动服务。

如需非交互式部署,可将密码第一行写入仅允许 root 读取的文件:

sudo ./auto-deploy.sh --host clickhouse.example.com \
    --password-file /root/vector-password

需要覆盖已有的 Vector 托管配置时增加 --force

sudo ./auto-deploy.sh --force --host clickhouse.example.com

如果 ClickHouse 部署时通过 --https-port 指定了非 443 端口,部署 Vector 时必须 通过 --port 指定相同端口。例如,ClickHouse 使用 --https-port 8443 时执行:

sudo ./auto-deploy.sh --host clickhouse.example.com --port 8443

使用本文推荐配置时,Vector 会连接 https://clickhouse.example.com:443。不要将 --host 设置为 IP,除非服务器证书的 Subject Alternative Name 中也包含该 IP。 使用组织内部 CA 时,应先将 CA 证书加入 Edge Node 的系统信任库;不要使用关闭证书 校验的方式绕过 TLS 错误。

主要文件和数据目录如下:

用途路径
Vector 配置/etc/vector-edge/vector-edge.yaml
凭据和环境变量/etc/vector-edge/vector-edge.env
systemd 服务/etc/systemd/system/vector-edge.service
文件读取检查点和磁盘缓冲区/var/lib/vector-edge

授予日志读取权限

部署完成后,优先使用 Edge 日志所属用户组或 ACL 授权,不要让 Vector 以 root 用户 运行。以下 ACL 示例授予现有日志读取权限,并让轮转后新建的文件继承相同权限:

sudo setfacl -m u:vector:x /usr/local/oredge-node
sudo setfacl -R -m u:vector:rX /usr/local/oredge-node/logs
sudo setfacl -d -m u:vector:rX /usr/local/oredge-node/logs

如果系统没有 setfacl,请先安装 ACL 工具,或通过 Edge 日志所属用户组授予等效的 读取和目录遍历权限。

检查 Vector 状态

加载 systemd 配置并启动服务:

sudo systemctl daemon-reload
sudo systemctl enable --now vector-edge.service

Vector 首次启动时从所有匹配且未压缩的文件开头读取,后续从检查点继续。如果节点上 已有大量历史日志,请先评估首次导入量,或临时缩小 include 范围。HTTP 日志 sink 的磁盘缓冲区上限为 4 GiB,Stream 和错误日志 sink 各为 512 MiB。请为 /var/lib/vector-edge 预留足够空间,并在重启或升级时保留该目录。

检查服务状态和实时日志:

sudo systemctl status vector-edge.service
sudo journalctl -u vector-edge.service -f

修改配置后,重新安装配置文件并重启服务。不要删除现有数据目录:

cd /opt/edge-vector-deployment
sudo install -o root -g root -m 0644 vector.yaml \
    /etc/vector-edge/vector-edge.yaml
sudo systemctl restart vector-edge.service

检查 Vector 上报是否异常

vector-edge.service 处于 active 状态只表示进程正在运行,不代表日志一定已经成功写入 ClickHouse。首先查看最近 10 分钟的服务日志:

sudo journalctl -u vector-edge.service --since "10 minutes ago" --no-pager

也可以筛选常见的上报异常关键词:

sudo journalctl -u vector-edge.service --since "10 minutes ago" --no-pager \
    | grep -Ei 'error|warn|failed|timeout|refused|tls|certificate|401|403|429|5[0-9]{2}|buffer'

重点关注以下信息:

日志信息常见原因
TLScertificate 或主机名校验失败证书链不完整、证书过期、域名与证书不匹配或 CA 未受信任
connection refused、DNS 或 timeout域名解析、网络、防火墙、端口或 ClickHouse 服务异常
HTTP 401403Vector 用户名、密码或 ClickHouse 写入权限错误
HTTP 4295xxClickHouse 限流、负载过高或服务暂时不可用
bufferfull 或丢弃事件上报持续失败,磁盘缓冲区正在积压或已经达到上限

部署包已在 127.0.0.1:8686 启用仅本机可访问的 Vector API。可以通过 vector top 观察三个 ClickHouse sink 的吞吐量和错误计数:

sudo /usr/local/openresty-vector/bin/vector top \
    --components 'clickhouse_*'

产生测试流量后,如果 ClickHouse sink 的错误数持续增加,或者输入事件持续增加但发送 事件不再增加,说明上报存在异常。短暂的重试不一定会丢失日志;只要磁盘缓冲区未满, Vector 会在 ClickHouse 恢复后继续发送。按 Ctrl+C 退出 vector top

最后应结合下一节的 ClickHouse 查询确认 last_ingested_at 持续更新。只有同时满足 Vector sink 没有持续错误、发送计数持续增加且 ClickHouse 最新写入时间正常,才能确认 上报链路正常。

验证日志采集

先通过已配置的 HTTP 或 Stream 应用产生几条测试流量,然后在 ClickHouse 服务器上 进入只读客户端:

cd /opt/edge-clickhouse-deployment
sudo docker compose \
    --project-name clickhouse-deployment \
    --file docker-compose.yml \
    --file docker-compose.ports.yml \
    exec clickhouse clickhouse-client \
    --user oredge-reader --password --database app

输入 .env 中的 CLICKHOUSE_OREDGE_READER_PASSWORD,再执行以下查询。

查看各类日志数量和最后写入时间:

SELECT 'http' AS type, count() AS rows, max(ingested_at) AS last_ingested_at
FROM nginx_http_access_logs
UNION ALL
SELECT 'stream', count(), max(ingested_at)
FROM nginx_stream_access_logs
UNION ALL
SELECT 'error', count(), max(ingested_at)
FROM nginx_error_logs;

查看最近的 HTTP 请求:

SELECT
    event_time,
    app_id,
    nginx_host,
    remote_addr,
    http_host,
    request,
    status,
    request_time,
    upstream_addr,
    upstream_status
FROM nginx_http_access_logs
ORDER BY event_time DESC
LIMIT 20;

检查日志解析质量:

SELECT
    nginx_host,
    parsed_ok,
    count() AS rows,
    max(ingested_at) AS last_ingested_at
FROM nginx_http_access_logs
GROUP BY nginx_host, parsed_ok
ORDER BY nginx_host, parsed_ok;

如果存在 parsed_ok = 0 的记录,检查无法解析的原始日志:

SELECT ingested_at, source_file, raw_message
FROM nginx_http_access_logs
WHERE parsed_ok = 0
ORDER BY ingested_at DESC
LIMIT 20;

容量规划

日志长度、字段内容和重复度都会影响 ClickHouse 的压缩效果。例如,较长的 URL、 User-Agent、上游地址和错误信息会增加单条日志的空间占用。因此,应以实际业务日志的 压缩后数据为准,不要只根据原始日志文件大小估算。

容量计算公式

分别计算 HTTP、Stream 和可选错误日志,再将结果相加:

基础数据容量 = 每天日志条数 × 保留天数 × 压缩后平均每条字节数
规划数据盘容量 = 基础数据容量 × 2 × (1 + 预计业务增长率)

这里建议使用 2 作为运行安全系数,用于预留后台合并、TTL 删除延迟、数据波动和 至少 30% 的可用空间。该系数不包括备份和副本:

  • 在同一服务器保留一份完整备份时,至少再增加一份基础数据容量;建议将备份存放到 独立磁盘或对象存储。
  • 部署多个 ClickHouse 副本时,集群的总存储量还要乘以副本数。
  • 如果预计一年内流量增长 30%,公式中的预计业务增长率填写 0.3

一百万条日志的容量示例

在没有实测数据时,可以暂时按压缩后平均每条 500 字节估算。100 万条日志的 ClickHouse 活跃数据大约占用 0.5 GB,乘以运行安全系数后,应为这批日志规划约 1 GB 数据盘空间。

不同日志内容下的估算如下。表中使用十进制单位,1 GB = 1,000,000,000 字节:

压缩后平均每条大小100 万条基础容量乘以安全系数后的规划容量
250 字节0.25 GB0.5 GB
500 字节0.5 GB1 GB
1,000 字节1 GB2 GB

这些数值只表示新增日志数据所需的空间,不是 ClickHouse 服务器的最小磁盘配置。 服务器还需要为操作系统、容器镜像、ClickHouse 运行日志和其他运维文件预留空间。

保存一年的容量示例

以下示例假设每天的日志总量已经包含 HTTP、Stream 和可选错误日志,压缩后平均每条 500 字节,保留 365 天,运行安全系数为 2,且暂不计算额外的业务增长、备份和 副本:

每天日志条数平均日志速率一年日志条数基础数据容量建议规划的数据盘容量
100 万条约 12 条/秒3.65 亿条182.5 GB365 GB
1,000 万条约 116 条/秒36.5 亿条1.825 TB3.65 TB
1 亿条约 1,157 条/秒365 亿条18.25 TB36.5 TB

例如,客户每天产生 100 万条日志并保存一年,可以先按 365 GB 数据盘规划。如果预计 一年内日志量增长 30%,则应调整为:

365 GB × 1.3 = 474.5 GB

实际采购时还应向上取整,并选择能够满足持续写入、后台合并和查询负载的 SSD。

测量实际每条日志大小

建议先导入至少 100 万条有代表性的业务日志,等待 ClickHouse 完成主要后台合并, 然后查询 system.partsbytes_on_disk 包含活动数据 part 的压缩列、索引和元数据, 适合用来估算实际磁盘占用:

SELECT
    table,
    sum(rows) AS rows,
    formatReadableSize(sum(bytes_on_disk)) AS size_on_disk,
    round(sum(bytes_on_disk) / nullIf(sum(rows), 0), 2) AS bytes_per_row
FROM system.parts
WHERE database = 'app'
  AND active
  AND table IN (
      'nginx_http_access_logs',
      'nginx_stream_access_logs',
      'nginx_error_logs'
  )
GROUP BY table
ORDER BY table;

使用各表的 bytes_per_row 分别计算会更准确。例如不采集错误日志时,不需要把 nginx_error_logs 计入容量。

统计最近 24 小时各类日志条数:

SELECT 'http' AS type, count() AS rows
FROM nginx_http_access_logs
WHERE ingested_at >= now() - INTERVAL 1 DAY
UNION ALL
SELECT 'stream', count()
FROM nginx_stream_access_logs
WHERE ingested_at >= now() - INTERVAL 1 DAY
UNION ALL
SELECT 'error', count()
FROM nginx_error_logs
WHERE ingested_at >= now() - INTERVAL 1 DAY;

不要只选择流量较低的日期。应统计业务高峰日,并结合促销、攻击流量和未来业务增长 确定每天日志条数。运行一段时间后,定期重新测量并修正容量预测。

检查磁盘空间

使用以下查询查看 ClickHouse 当前磁盘总量和剩余空间:

SELECT
    name,
    path,
    formatReadableSize(total_space) AS total_space,
    formatReadableSize(free_space) AS free_space,
    round(free_space / total_space * 100, 2) AS free_percent
FROM system.disks;

建议在可用空间低于 30% 前告警并扩容,避免后台合并或 TTL 清理因为空间不足而失败。 clickhouse_logs 卷和备份空间需要单独监控,不包含在 system.parts.bytes_on_disk 的 数据表容量中。

每台 Edge Node 还需要为 Vector 磁盘缓冲区预留空间。采集全部三类日志时,当前配置的 缓冲区上限合计为 5 GiB;建议为 /var/lib/vector-edge 至少预留 6 GiB。关闭错误 日志采集后,可以扣除对应的 512 MiB 缓冲区,但仍应考虑 ClickHouse 暂时不可用时的 日志积压时间。

调整日志保留时间

CLICKHOUSE_RETENTION_DAYS 必须是正整数。修改 ClickHouse 服务器上的 .env 后, 重新运行一次初始化服务:

cd /opt/edge-clickhouse-deployment
sudo docker compose \
    --project-name clickhouse-deployment \
    --file docker-compose.yml \
    --file docker-compose.ports.yml \
    run --rm clickhouse-init

该操作会更新新表和现有日志表的 TTL。ClickHouse 通过后台合并删除过期数据,因此 修改后不会立即释放全部空间。

常见问题

Vector 服务无法启动

使用以下命令查看最近的错误:

sudo journalctl -u vector-edge.service -n 100 --no-pager

重点检查 ClickHouse 域名、HTTPS 端口、证书链、vector 密码、系统时间以及 /etc/vector-edge/vector-edge.env 的权限。该环境变量文件应由 root 所有,权限 为 0600

如果日志包含 certificate verify failedunknown issuer,确认服务器发送的是 完整证书链,并检查 Edge Node 是否信任签发证书的 CA。不要关闭 verify_certificateverify_hostname

Vector 报告 Permission denied

确认 vector 用户对 /usr/local/oredge-node 有目录遍历权限,对日志目录和现有日志 有读取权限,并且目录的默认 ACL 会覆盖轮转后新建的文件。

ClickHouse 中没有访问日志

依次确认:

  1. Edge 应用已使用配置后的 main 或默认的 vector-json 格式,并已发布配置。
  2. Edge Node 的当前日志文件有新内容,且每条记录都是单行 JSON。
  3. edge-vector-deployment/vector.yaml 中的文件名与 Edge Node 实际文件名一致。
  4. Vector 日志中没有连接、认证、解析或缓冲区错误。
  5. Edge Node 能够通过 HTTPS 访问 ClickHouse 域名和端口,且证书校验成功。

只有当前日志,没有轮转日志

确认 Vector 的 include 同时包含当前日志和下划线后缀的轮转日志,并且轮转文件没有 经过 Gzip 压缩。Vector 会根据 /var/lib/vector-edge 中的检查点避免在正常重启后 重复读取相同内容。

重新部署后出现重复记录

不要删除 /var/lib/vector-edge,否则 Vector 会丢失读取检查点并可能重新导入历史 日志。ClickHouse 表使用 ReplacingMergeTree,相同排序键的记录只能在后台合并后 去重,不应以此代替 Vector 检查点。

后续使用建议

  • 日常查询使用 oredge-reader 或为每个分析工具创建独立的只读账号,不要使用 vector 写入账号。
  • 日常运维可以使用容器内置的 clickhouse-client 查询;需要图形化浏览时,可使用 DBeaver;需要持续监控和告警时,可接入 Grafana 的 ClickHouse 数据源。
  • 查询历史日志时添加时间范围,避免无意扫描全部分区。
  • 更改 ClickHouse 镜像版本前先备份数据,并保留 clickhouse_data 外部卷。
  • 监控服务器证书的有效期。续期并替换证书文件后,重启 ClickHouse 容器并再次执行 HTTPS 连通性测试。

更多 TLS 配置项请参考 ClickHouse TLS 配置Vector ClickHouse sink 配置