跳转到内容

Prometheus 面试题

30 道题
分类
可观测性
子分类
metrics
题目数
30 道
已阅读 0 / 30 题
1 Prometheus 的核心架构和设计理念是什么?

答案:

Prometheus 是一款基于拉取(Pull)模型的指标监控和时间序列数据库,遵循开箱即用和自治原则。

核心架构:

graph TD
    A["Targets<br/>(Exporters)"] -->|"/metrics (Pull)"| B["Prometheus Server<br/>(TSDB + 采集)"]
    B --> C["Alertmanager"]
    B --> D["Grafana"]
    B --> E["Remote Storage"]

设计理念:

原则说明
Pull 模型Server 主动拉取目标指标,无需 Agent 主动推送
自治单个 Server 独立运行,不依赖分布式存储
标签模型指标通过 Label 标识维度,支持灵活聚合
PromQL专有时序查询语言,支持多维分析和聚合
高效压缩自研 TSDB,块压缩,单节点支持百万活跃序列
2 Prometheus 的 Pull 模型和 Push 模型各自的优缺点是什么?

答案:

Prometheus 默认采用 Pull 模型,通过 Pushgateway 和 Remote Write 补充 Push 场景。

对比分析:

维度Pull 模型Push 模型
采集控制Server 端控制采集频率Client 端控制推送频率
健康检测Pull 超时即判定目标不可用Push 中断需额外心跳检测
防火墙穿越需目标可达Client 主动连接,可穿越 NAT
自动发现天然支持(通过 SD)需服务注册中心
扩展性需 LB 层做分片天然分布
批处理任务任务结束后无法 PullPushgateway 支持
配置变更修改 scrape_config 即可需修改 Client 端配置

适用场景:

Pull 模型:
  - 长期运行的 Service/Worker
  - K8s 环境(Pod 生命周期匹配)
  - 需要健康检测的场景

Push 模型(Pushgateway/Remote Write):
  - 批处理任务(CronJob、CI 任务)
  - 短生命周期任务
  - NAT 网络环境
  - 边缘设备采集
3 Prometheus 的四种指标类型(Metric Types)是什么?

答案:

Prometheus Client 库定义四种核心指标类型,各有不同的语义和使用场景。

指标类型数据结构典型场景示例
Counter只增不减的累计值请求计数、错误计数http_requests_total
Gauge可增可减的瞬时值CPU 使用率、内存使用量node_memory_usage_bytes
Histogram分桶计数 + 总和 + 总数请求延迟分布、响应大小http_request_duration_seconds
Summary分位数计算 + 总和 + 总数延迟分位数(预计算)http_request_duration_seconds

Counter 特点:

  • 重启后归零,rate() / irate() 函数计算速率
  • 不可用于减法运算(需 reset() 处理重置)

Gauge 特点:

  • 可直接进行加减运算
  • delta() 函数计算时间范围内的变化量

Histogram 与 Summary 区别:

维度HistogramSummary
分位数计算查询端 (PromQL)客户端预计算
聚合能力支持 sum 聚合不支持聚合
配置灵活性自定义 Bucket自定义分位数 + 衰减窗口
资源消耗Client 端轻量Client 端较重
推荐场景需要跨实例聚合无法接受降精度
4 PromQL 的核心函数 rate() 和 irate() 的区别是什么?

答案:

rate() 和 irate() 均为 Counter 类型指标计算每秒增长率,但计算方式不同。

核心区别:

维度rate()irate()
计算方式区间内平均增长率区间内最后两个样本的瞬时增长率
对峰值敏感度平滑(平均)敏感(捕捉最新变化)
抗噪能力强(区间平均)弱(两样本易受毛刺影响)
返回结果始终 >= 0始终 >= 0
推荐场景告警规则、慢速变化的指标快速变化的指标、短时间窗口

示例:

# rate() - 5m 内平均每秒请求数
rate(http_requests_total[5m])

# irate() - 最后两个点的瞬时速率
irate(http_requests_total[5m])

选择建议:

rate():
  - 告警规则(避免峰值误告警)
  - 容量规划(关注趋势而非毛刺)
  - 长时间窗口(1h/1d)的聚合

irate():
  - Grafana 图表(显示更精细的曲线)
  - 短时间窗口的快速指标
  - 故障排查(观察最新变化)
5 Prometheus TSDB 的存储结构是什么样的?

答案:

Prometheus TSDB 采用块存储(Block)结构,按时间窗口组织数据,支持高效压缩和查询。

存储目录结构:

/data/
  ├── 01EM6Q6A1Z1Z1Z1Z1Z1Z1Z1Z1Z1/   # Block 目录(ULID 命名)
  │   ├── chunks/
  │   │   └── 000001                   # 压缩后的样本数据块
  │   ├── index                        # 倒排索引(Label → Series)
  │   ├── meta.json                    # Block 元数据(时间范围、样本数)
  │   ├── tombstones                   # 删除标记
  │   └── wal/                         # WAL(预写日志)
  │       ├── 000001.wal
  │       └── 000002.wal
  ├── 01EM6Q6A1Z1Z1Z1Z1Z1Z1Z1Z1Z2/
  ├── chunks_head/                     # 当前正在写入的 chunk
  │   └── 000001
  ├── wal/                             # 当前 WAL
  │   ├── 000003.wal
  │   └── 000004.wal
  └── lock                             # 文件锁

写入流程:

```mermaid
graph TD
    A["样本到达"] --> B["内存中 Head Chunk"]
    B -->|"写入 WAL(故障恢复)"| WAL["WAL"]
    B --> C["Head Chunk 满 2h"]
    C --> D["冻结"]
    D --> E["写入磁盘 Block"]
    E --> F["Block 压缩"]
    F --> G["合并"]
    G --> H["删除过期 Block"]

**压缩合并:**

原始 Block(2h 块): Block-A (14:00-16:00) Block-B (16:00-18:00) Block-C (18:00-20:00) Block-D (20:00-22:00)

合并后(10h 块): Block-ABCD (14:00-22:00) → 更小的总体积,更快的查询

6 Prometheus 的服务发现(Service Discovery)机制有哪些?

答案:

Prometheus 支持多种服务发现机制,动态管理采集目标。

支持的服务发现:

服务发现类型适用场景刷新机制
kubernetes_sd_configsK8s Pod/Service/EndpointWatch API 实时更新
consul_sd_configsConsul 注册中心Watch/轮询
file_sd_configs文件方式定义 Target文件修改自动刷新
dns_sd_configsDNS SRV 记录DNS 轮询
ec2_sd_configsAWS EC2 实例API 轮询
azure_sd_configsAzure VMAPI 轮询
gce_sd_configsGCP GCE 实例API 轮询
openstack_sd_configsOpenStack 实例API 轮询
nerve_sd_configsAirbnb NerveZK 监听
serverset_sd_configsGoogle ServersetZK 监听
triton_sd_configsJoyent TritonAPI 轮询
eureka_sd_configsNetflix EurekaAPI 轮询
docker_sd_configsDocker 容器Docker API
digitalocean_sd_configsDigitalOcean DropletsAPI 轮询
http_sd_configsHTTP 接口HTTP 轮询

K8s SD 示例:

scrape_configs:
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app]
        action: keep
        regex: myapp
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: "true"

file_sd 示例:

scrape_configs:
  - job_name: 'file-based-targets'
    file_sd_configs:
      - files:
          - /etc/prometheus/targets/*.json
        refresh_interval: 5m
7 Prometheus relabeling 机制的作用和常见用法是什么?

答案:

Relabeling 是 Prometheus 在采集前对 Target 标签进行动态修改、过滤和重命名的机制。

Relabeling 动作:

动作作用示例
replace替换标签值(默认)修改标签名或值
keep保留匹配的 Target过滤掉不符合条件的 Target
drop丢弃匹配的 Target排除特定 Target
hashmod对源标签值做 Hash 取模用于分片
labelmap匹配并映射标签将 _meta* 标签改为最终标签
labeldrop删除匹配的标签删除高基数标签
labelkeep保留匹配的标签仅保留需要的标签
keepequal保留值相等的 Target条件保留
dropequal丢弃值相等的 Target条件丢弃

常见用法:

relabel_configs:
  # 1. 只采集带有 annotation 的 Pod
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    action: keep
    regex: "true"

  # 2. 设置采集路径
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)

  # 3. 映射 K8s 标签到最终标签
  - source_labels: [__meta_kubernetes_pod_label_app]
    action: replace
    target_label: app

  # 4. 删除高基数标签
  - regex: "__meta_kubernetes_pod_uid|__meta_kubernetes_pod_controller_uid"
    action: labeldrop

  # 5. 保留特定标签
  - regex: "app|component|tier|namespace"
    action: labelkeep

执行顺序:

1. 从 SD 获取 __meta_* 标签
2. 应用 relabel_configs(顺序执行)
3. 应用 metric_relabel_configs
4. 写入 TSDB
8 Prometheus 告警规则的生命周期和管理方式是什么?

答案:

Prometheus 告警从规则评估到通知经过多个状态转换。

告警状态机:

graph TD
    START["评估规则"] --> PENDING["Pending<br/>首次触发(未到 for 持续时间)"]
    PENDING -->|"for 持续期间"| FIRING["Firing<br/>持续触发(发送通知)"]
    FIRING -->|"规则恢复(不再触发)"| RESOLVED["Resolved<br/>已解决(可选发送)"]
    RESOLVED --> DONE["(恢复正常)"]

告警规则示例:

groups:
  - name: node-alerts
    interval: 10s
    rules:
      - alert: NodeCPUUsageHigh
        expr: (100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)) > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Node XQOPEN $labels.instance XQCLOSE CPU usage > 80%"
          description: "Node XQOPEN $labels.instance XQCLOSE CPU usage is XQOPEN $value | humanizePercentage XQCLOSE"

      - alert: NodeDiskSpaceFull
        expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.1
        for: 10m
        labels:
          severity: critical
        annotations:
          summary: "Node XQOPEN $labels.instance XQCLOSE disk space < 10%"

Alertmanager 配置:

route:
  receiver: 'default'
  routes:
    - match:
        severity: critical
      receiver: 'pagerduty'
    - match:
        severity: warning
      receiver: 'slack'

receivers:
  - name: 'pagerduty'
    pagerduty_configs:
      - routing_key: <key>
  - name: 'slack'
    slack_configs:
      - api_url: <webhook>
        channel: '#alerts'
9 Prometheus 的记录规则(Recording Rules)有什么作用?

答案:

Recording Rules 预计算复杂或高频查询的 PromQL 表达式,将结果存储为新的时间序列,降低查询延迟和 Server 负载。

使用场景:

场景说明示例
复杂计算耗时长或复杂的 PromQL百分比计算、多层聚合
Dashboard 加速Grafana 面板频繁查询预计算后直接查询
聚合降精度高精度 → 低精度原始 15s → 5m 聚合
跨实例聚合多实例汇总集群级别指标

配置示例:

groups:
  - name: node-recording
    interval: 1m
    rules:
      - record: node:node_cpu_utilization:ratio
        expr: (1 - avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))

      - record: node:node_memory_utilization:ratio
        expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)

      - record: node:node_disk_utilization:ratio
        expr: (1 - avg by(instance, device) (rate(node_disk_io_time_seconds_total[5m])))

最佳实践:

命名规范: level:metric:aggregation
  例如: node:node_cpu_utilization:ratio
  - level: 数据来源层(node/container/service)
  - metric: 指标名称
  - aggregation: 聚合方式(ratio/avg/p99/rate)

注意事项:
  - 避免递归引用
  - 设置合适的评估间隔
  - 监控记录规则的性能和资源消耗
  - 及时清理不再使用的记录规则
10 Prometheus 的 Remote Write 和 Remote Read 机制是什么?

答案:

Remote Write/Read 是 Prometheus 与外部存储系统交互的标准协议,分别实现数据导出和查询。

Remote Write:

```mermaid
graph TD
    A["Prometheus Server"] -->|"Remote Write<br/>Snappy 压缩 + Protobuf 编码"| B["接收端<br/>Cortex / Thanos Receiver / VictoriaMetrics"]
    B --> C["长期存储 / 全局视图"]

**配置:**

```yaml
remote_write:
  - url: "http://thanos-receiver:19291/api/v1/receive"
    name: "thanos-receive"
    write_relabel_configs:
      - source_labels: [__name__]
        regex: "node_.*"
        action: keep
    queue_config:
      capacity: 2500
      max_samples_per_send: 500
      batch_send_deadline: 5s
      min_backoff: 30ms
      max_backoff: 100ms

Remote Read:

remote_read:
  - url: "http://thanos-query:9090/api/v1/read"
    read_recent: true
    required_matchers:
      job: "node"

对比分析:

维度Remote WriteRemote Read
数据流向Prometheus → 外部存储外部存储 → Prometheus
协议Snappy + ProtobufSnappy + Protobuf
可靠性队列 + 重试机制直接查询
典型用途长期存储、全局聚合历史数据回查
性能影响异步写入,低影响取决于远程存储延迟

注意事项:

Remote Write:
  - 失败数据本地保留(队列持久化)
  - 配置 write_relabel_configs 控制写入范围
  - 监控 remote_storage_queue_highest_sent_timestamp_seconds

Remote Read:
  - 默认不查询远程(仅本地)
  - 设置 read_recent=true 包含近期数据
  - 查询性能取决于远程存储
11 Prometheus 的 High Cardinality(高基数)问题是什么?如何解决?

答案:

高基数指时间序列的标签组合数量过大,导致 TSDB 性能和资源消耗急剧增加。

高基数的影响:

指标正常(< 10 万序列)高基数(> 100 万序列)极高基数(> 1000 万序列)
内存< 2GB8-16GB32GB+
查询延迟< 100ms1-5s30s+
TSDB 压缩正常缓慢失败
磁盘 IO极高

常见高基数场景:

1. URL 路径作为标签(/api/users/123 → 每个用户一个序列)
2. Request ID/UUID 作为标签
3. 用户 ID / Session ID 作为标签
4. 精确时间戳作为标签
5. IP 地址 + Port 组合

解决方案:

# 1. Relabel 丢弃高基数标签
metric_relabel_configs:
  - source_labels: [__name__]
    regex: "http_request_duration_seconds"
    action: keep
  - source_labels: [url]
    regex: "/api/users/[0-9]+"
    replacement: "/api/users/{id}"
    action: replace

# 2. 聚合降精度(Recording Rules)
record: service:http_requests_total:rate5m
expr: sum by(service, method, status) (rate(http_requests_total[5m]))

# 3. 限制采集标签数
scrape_configs:
  - job_name: 'myapp'
    params:
      collect[]: ['default']
    relabel_configs:
      - regex: "request_id|session_id|user_id"
        action: labeldrop

监控高基数:

# 时间序列数量
count by (__name__) ({__name__=~".+"})

# 标签基数
count(count by (url) (http_requests_total))

# 内存中序列数
prometheus_tsdb_head_series
12 Prometheus 联邦(Federation)机制的工作原理是什么?

答案:

Prometheus 联邦允许一个 Prometheus Server 从另一个 Prometheus Server 拉取聚合后的指标,实现层级式的监控架构。

联邦层级:

全局 Prometheus(Global View)
    ├── 区域 Prometheus-A(Region-A)
    │   ├── 节点采集器(Node Exporters)
    │   └── 应用采集器(App Exporters)
    ├── 区域 Prometheus-B(Region-B)
    │   ├── 节点采集器
    │   └── 应用采集器
    └── Service Mesh Prometheus
        └── 服务指标

配置:

# 全局 Prometheus 配置(从区域 Prometheus 拉取聚合指标)
scrape_configs:
  # 联邦采集(拉取预聚合指标)
  - job_name: 'federate-region-a'
    scrape_interval: 30s
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{__name__=~"node:.*"}'
        - '{__name__=~"service:.*"}'
    static_configs:
      - targets:
          - 'prometheus-region-a:9090'
  - job_name: 'federate-region-b'
    scrape_interval: 30s
    metrics_path: '/federate'
    params:
      'match[]':
        - '{__name__=~"node:.*"}'
    static_configs:
      - targets:
          - 'prometheus-region-b:9090'

联邦模式对比:

模式描述适用场景
层级联邦上层 Pull 下层聚合指标多数据中心、多团队
跨服务联邦一个服务 Pull 另一个服务的指标Service Mesh 场景
对等联邦互为联邦实现高可用小规模 HA

注意事项:

1. honor_labels: true 保持原始标签
2. 只采集聚合指标,避免原始指标重复
3. 全局 Prometheus 资源消耗较低(仅存储聚合数据)
4. 区域性 Prometheus 故障不影响全局视图
5. 联邦非实时,存在数据延迟(取决于 scrape_interval)
13 Prometheus 的 Operator 模式(Prometheus Operator)是什么?

答案:

Prometheus Operator 是基于 Kubernetes Operator 模式的 Prometheus 管理方案,通过 CRD 简化 Prometheus 集群的部署和管理。

核心 CRD:

CRD作用说明
PrometheusPrometheus Server 实例定义副本数、资源、存储、配置
AlertmanagerAlertmanager 实例定义集群配置、模板
ServiceMonitorService 的指标采集配置基于 Service label 选择目标
PodMonitorPod 的指标采集配置直接采集 Pod 指标
PrometheusRule告警和记录规则Prometheus 规则管理
ProbeBlackbox Exporter 探针网络探测配置
AlertmanagerConfigAlertmanager 接收者配置路由、接收者、抑制规则

ServiceMonitor 示例:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-app
spec:
  selector:
    matchLabels:
      app: example-app
  endpoints:
    - port: http
      interval: 15s
      path: /metrics
  namespaceSelector:
    matchNames:
      - default

Prometheus CRD 示例:

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: k8s
spec:
  replicas: 2
  resources:
    requests:
      memory: 4Gi
  storage:
    volumeClaimTemplate:
      spec:
        storageClassName: ssd
        resources:
          requests:
            storage: 100Gi
  serviceMonitorSelector:
    matchLabels:
      app: monitored
  ruleSelector:
    matchLabels:
      role: alert-rules
14 Prometheus 的数据保留和数据压缩机制是什么?

答案:

Prometheus 通过块合并、压缩和保留策略管理 TSDB 的数据生命周期。

保留策略配置:

# 启动参数
--storage.tsdb.retention.time=15d    # 数据保留时间(默认 15d)
--storage.tsdb.retention.size=100GB  # 数据保留大小限制
--storage.tsdb.retention.size=0      # 0=不限大小

压缩合并流程:

graph TD
    subgraph "2h 块"
        A["Block-A<br/>14:00-16:00"]
        B["Block-B<br/>16:00-18:00"]
        C["Block-C<br/>18:00-20:00"]
        D["Block-D<br/>20:00-22:00"]
    end
    A --> AB["Block-A+B<br/>10h 块"]
    B --> AB
    C --> CD["Block-C+D"]
    D --> CD
    AB --> ABCD["Block-A+B+C+D<br/>合并最终块"]
    CD --> ABCD

压缩级别:

级别块大小压缩比例说明
L12h原始数据最新数据,不压缩
L210h~2:1第一次合并
L350h~4:1第二次合并
L4250h~8:1最终压缩

磁盘空间计算:

8 个样本/序列 × 16 bytes = 128 bytes/原始样本
压缩后平均 ~1.3 bytes/样本

估算公式:
  序列数 × 样本数 × 1.3 bytes = 存储大小

示例:
  100 万序列 × 15s 间隔 × 15d
  = 100万 × (86400/15 × 15) × 1.3
  ≈ 100万 × 86400 × 1.3
  ≈ 112GB
15 Prometheus 的内存使用和性能优化策略是什么?

答案:

Prometheus 的内存消耗主要来自 TSDB Head 中活跃的时间序列数据。

内存消耗模型:

内存 ≈ 活跃序列数 × 每个序列占用(~2KB)

分解:
  - 倒排索引: ~序列数 × 标签数 × 100 bytes
  - Head Chunk: ~序列数 × (chunk 大小) = ~序列数 × 1KB
  - WAL 缓存: ~序列数 × 0.5KB
  - 查询缓存: 额外开销

优化策略:

# 1. 启动参数优化
--storage.tsdb.min-block-duration=2h    # 默认 2h
--storage.tsdb.max-block-duration=48h   # 最大块大小
--storage.tsdb.retention.time=15d
--storage.tsdb.retention.size=100GB

# 2. 资源限制
--memory.series=500000                  # 最大序列数限制
--memory.chunks=500000                  # 最大 chunk 数限制

# 3. 采集优化
scrape_configs:
  - job_name: 'myapp'
    scrape_interval: 30s                 # 降低采集频率
    scrape_timeout: 10s
    relabel_configs:
      - action: labeldrop                # 丢弃高基数标签
        regex: "tmp|temp|request_id"

监控内存:

# TSDB Head 序列数
prometheus_tsdb_head_series

# 内存中的 Chunk 数
prometheus_tsdb_head_chunks

# 内存使用率
process_resident_memory_bytes / process_virtual_memory_bytes

# 每个序列的内存估算
process_resident_memory_bytes / prometheus_tsdb_head_series
16 Prometheus 在 K8s 中的采集方式有哪几种?

答案:

Prometheus 在 K8s 中支持多种角色的服务发现和数据采集。

采集角色:

角色采集范围说明
pod单个 Pod采集 Pod 中容器的 metrics 端点
serviceService 后端采集 Service 背后的 Pod
endpointsEndpoint 对象采集 Endpoint 关联的 Pod
ingressIngress 对象采集 Ingress 的指标
node节点采集 Node Exporter 等节点指标

完整配置示例:

scrape_configs:
  # 1. Pod 采集(基于 annotation)
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: "true"
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__

  # 2. Service 采集(基于 label)
  - job_name: 'kubernetes-services'
    kubernetes_sd_configs:
      - role: service
    relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: "true"

  # 3. Node 采集
  - job_name: 'kubernetes-nodes'
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

  # 4. Kubelet 采集
  - job_name: 'kubernetes-kubelet'
    kubernetes_sd_configs:
      - role: node
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    relabel_configs:
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/$1/proxy/metrics
17 Prometheus 的 Alertmanager 集群模式是如何工作的?

答案:

Alertmanager 通过 Gossip 协议实现集群节点间的告警去重、分组和静默同步。

集群架构:

graph TD
    PROM["Prometheus"] -->|"Alert"| AM["Alertmanager"]
    AM --> GOSSIP["Gossip (Mesh)"]
    GOSSIP --> A["A"]
    GOSSIP --> B["B"]
    GOSSIP --> C["C"]
    AM --> SLACK["Slack"]
    AM --> EMAIL["Email"]

集群配置:

# Alertmanager 启动参数(三个节点)
alertmanager --cluster.listen-address=0.0.0.0:9094 \
             --cluster.peer=alertmanager-0:9094 \
             --cluster.peer=alertmanager-1:9094 \
             --cluster.peer=alertmanager-2:9094 \
             --config.file=/etc/alertmanager/alertmanager.yml

Prometheus 端配置:

# 配置多个 Alertmanager
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager-0:9093
            - alertmanager-1:9093
            - alertmanager-2:9093
    scheme: http
    timeout: 10s
    api_version: v2

工作机制:

1. Prometheus 将告警发送到所有 Alertmanager 节点
2. Alertmanager 通过 Gossip 同步告警通知状态
3. 已发送的通知不会被重复发送(去重)
4. 一个节点故障,其他节点继续处理
5. 分组和抑制规则在所有节点一致

Gossip 同步内容:

- 告警通知的已发送状态
- 静默规则
- 节点成员变更
18 Prometheus 的 HTTP API 支持哪些操作?

答案:

Prometheus 提供完整的 HTTP API,覆盖数据查询、元数据管理和管理操作。

API 端点:

端点方法用途
/api/v1/queryGET/POST瞬时查询
/api/v1/query_rangeGET/POST范围查询
/api/v1/seriesGET/POST序列匹配查询
/api/v1/labelsGET标签名列表
/api/v1/label/{name}/valuesGET标签值列表
/api/v1/metadataGET指标元数据
/api/v1/alertsGET活跃告警
/api/v1/rulesGET规则列表
/api/v1/targetsGET采集目标状态
/api/v1/targets/metadataGET目标元数据
/api/v1/query_exemplarsGET/POSTExemplar 查询
/api/v1/status/configGET运行时配置
/api/v1/status/tsdbGETTSDB 状态
/api/v1/status/buildinfoGET构建信息
/api/v1/status/runtimeinfoGET运行时信息
/api/v1/admin/tsdb/snapshotPOST创建快照
/api/v1/admin/tsdb/delete_seriesPOST删除序列
/api/v1/admin/tsdb/clean_tombstonesPOST清理墓碑

查询示例:

# 瞬时查询
curl 'http://localhost:9090/api/v1/query?query=up{job="node"}&time=1717000000'

# 范围查询
curl 'http://localhost:9090/api/v1/query_range?query=rate(http_requests_total[5m])&start=1717000000&end=1717003600&step=15'

# 标签值查询
curl 'http://localhost:9090/api/v1/label/__name__/values'

# 创建快照
curl -XPOST 'http://localhost:9090/api/v1/admin/tsdb/snapshot'
19 Prometheus 的 WAL(Write-Ahead Log)机制是什么?

答案:

WAL 是 Prometheus TSDB 的预写日志,用于确保数据持久性和故障恢复。

WAL 结构:

/data/wal/
  ├── 000001.wal          # WAL 文件(按序号递增)
  ├── 000002.wal
  ├── 000003.wal
  └── checkpoint.000002/  # WAL 检查点
      ├── 000000.wal
      └── 000001.wal

写入流程:

```mermaid
graph TD
    A["样本到达"] --> B["写入 WAL(先写日志)"]
    B --> C["写入内存 Head Chunk(后写数据)"]
    C --> D["批量提交(2h 后冻结)"]
    D --> E["冻结 Chunk"]
    E --> F["删除对应 WAL 段"]
    F --> G["写入 Block"]

**故障恢复:**

正常启动: WAL → 回放到 Head Chunk → 恢复内存状态

非正常关闭: 扫描 WAL → 找到未冻结的样本 → 重建 Head Chunk 丢弃不完整的 WAL 段 → 确保数据一致性

WAL 损坏: 自动截断损坏的 WAL 段 记录错误日志: “WAL segment corrupted” 丢失损坏段的数据


**WAL 配置:**

```bash
--storage.tsdb.wal-compression          # WAL 压缩(默认开启)
--storage.tsdb.wal-segment-size=128MB   # WAL 段大小(默认 128MB)
20 Prometheus 的 staleness(数据过期机制)是如何判断的?

答案:

Prometheus 通过样本的最后更新时间判断时间序列是否过期(staleness)。

过期判定规则:

默认过期时间: 5 分钟(从最新样本开始)

判定逻辑:
  当前时间 - 最新样本的时间戳 > 5m → 标记为 stale
  标记为 stale 后 → 查询中不返回该序列

Stale Marker:
  目标离线时,Prometheus 写入一个 Stale NaN
  Stale Marker 后的序列在下次采集前不可见

Stale 影响:

# 查询结果受 stale 影响
up{job="node"}  # 如果 node 离线 >5m → 不返回结果

# rate() 函数对 stale 的处理
rate(http_requests_total[5m])  # 5m 窗口内无新数据 → 返回 0

# 使用 offset 可以查询即使被 staleness 的数据
up offset 10m  # 查 10 分钟前的数据

避免 Stale 影响:

# 对于 pushgateway 这类非持续采集的目标
scrape_configs:
  - job_name: 'pushgateway'
    honor_labels: true
    static_configs:
      - targets: ['pushgateway:9091']

# 使用 keep_dropped_targets 配置保留周期
21 Prometheus 的 Label 模型和设计要求是什么?

答案:

Prometheus 的标签模型是其多维数据模型的基础,设计上遵循特定的约束和最佳实践。

标签模型约束:

约束项规则
标签名字母、数字、下划线,长度 <= 256
标签值任意 UTF-8 字符串
__ 前缀系统保留标签(namemetrics_path 等)
标签数量无硬限制(实际受性能和基数约束)
唯一标识指标名 + 所有标签的组合唯一标识一个时间序列

内置标签:

标签含义
name指标名
address采集地址(host:port)
metrics_pathMetrics 路径
scheme协议(http/https)
scrape_interval采集间隔
scrape_timeout采集超时
job作业名
instance实例(默认 address

标签设计原则:

最佳实践:
  - 标签基数控制在 < 100 个唯一值
  - 区分维度(service、method、status)而非实体(user_id、request_id)
  - 统一命名风格(蛇形命名)
  - 标签值有界(method ∈ [GET,POST,PUT,DELETE])
  - 避免在标签中嵌入可变信息(IP、时间戳)

反例:
  http_requests_total{user_id="12345", request_id="abc-def", timestamp="1717000000"}
  → 每个请求产生新序列,基数爆炸

正例:
  http_requests_total{service="api-gateway", method="GET", status="200"}
  → 序列数有限,可聚合
22 Prometheus 的 scrape_interval 和 evaluation_interval 的关系是什么?

答案:

scrape_interval 控制数据采集频率,evaluation_interval 控制规则评估频率,两者既有协作也有约束。

定义:

参数作用默认值影响
scrape_interval每秒采集一次目标1m数据精度和存储量
evaluation_interval每间隔评估一次规则1m告警响应延迟

约束关系:

规则评估不能快于数据采集:
  evaluation_interval >= scrape_interval
  否则规则评估时取到的是重复的旧数据

PromQL 窗口大小建议 >= 4 × scrape_interval:
  rate(metric[5m]) 对 15s 采集间隔是合理的(20 个样本点)
  rate(metric[1m]) 对 15s 采集间隔偏小(4 个样本点)

规则配置:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - 'alerts.yml'
  - 'recording.yml'

groups:
  - name: example
    interval: 30s         # 覆盖全局 evaluation_interval
    rules:
      - alert: ...
23 Prometheus 的 textfile collector 有什么用?

答案:

Textfile Collector 是 Node Exporter 等组件的辅助功能,允许将非标准格式的指标通过文件方式暴露给 Prometheus。

工作机制:

```mermaid
graph TD
    A["批处理/CronJob"] --> B["生成 .prom 文件<br/>(自定义指标格式)"]
    B --> C["Node Exporter 定期读取<br/>(--collector.textfile.directory)"]
    C --> D["与 Node Exporter 指标合并"]
    D --> E["Prometheus 采集 /metrics"]

**使用场景:**
  1. CronJob 执行结果指标

    • 备份成功/失败计数
    • 日志轮转状态
    • 系统维护任务状态
  2. 自定义系统指标

    • RAID 阵列状态
    • 硬件健康检测
    • 许可证到期日
  3. 遗留系统指标

    • Shell 脚本采集的指标
    • 不支持 Prometheus Client 的应用

**配置示例:**

```bash
# Node Exporter 启动
./node_exporter --collector.textfile.directory=/var/lib/node_exporter/textfile

# CronJob 生成指标
#!/bin/bash
echo "# HELP backup_last_success Backups last success timestamp" > /var/lib/node_exporter/textfile/backup.prom
echo "# TYPE backup_last_success gauge" >> /var/lib/node_exporter/textfile/backup.prom
echo "backup_last_success $(date +%s)" >> /var/lib/node_exporter/textfile/backup.prom

文本文件格式:

# HELP my_metric Description
# TYPE my_metric gauge
my_metric{label="value"} 42 1717000000
24 Prometheus 的 Pushgateway 的正确使用方式是什么?

答案:

Pushgateway 是 Prometheus Push 模型的关键组件,允许批处理任务和短生命周期任务推送指标。

架构:

```mermaid
graph TD
    A["批处理任务"] -->|"Push<br/>HTTP PUT/POST"| B["Pushgateway (:9091)"]
    B -->|"Pull<br/>/metrics"| C["Prometheus Server"]

**正确场景 vs 错误场景:**

| 场景 | 是否推荐 | 原因 |
|------|---------|------|
| **CronJob 执行结果** | 推荐 | 任务执行完即消失 |
| **CI/CD 流水线** | 推荐 | Pipeline 执行状态 |
| **批处理脚本** | 推荐 | 无法长期运行 |
| **Service 指标** | 不推荐 | 应使用 Pull 模型 |
| **高频率指标** | 不推荐 | Pushgateway 成为瓶颈 |
| **实例级指标** | 不推荐 | 无法区分实例 |

**操作示例:**

```bash
# 推送单个指标
echo "job_duration_seconds 42.5" | curl --data-binary @- http://pushgateway:9091/metrics/job/myjob

# 推送带标签的指标
cat <<EOF | curl --data-binary @- http://pushgateway:9091/metrics/job/myjob/instance/myinstance
# TYPE job_success gauge
job_success{status="completed"} 1
# TYPE job_duration_seconds gauge
job_duration_seconds 42.5
EOF

# 删除 job 的所有指标
curl -X DELETE http://pushgateway:9091/metrics/job/myjob

注意事项:

1. Pushgateway 是"指标缓存",不持久化
2. 务必在任务结束时 DELETE 清理指标
3. Pushgateway 不是 Prometheus 的替代品
4. 使用 honor_labels: true 保留 job/instance 标签
5. 监控 Pushgateway 自身指标(pushgateway_metrics_total)
25 Prometheus 的 blackbox exporter 支持的探测方式有哪些?

答案:

Blackbox Exporter 是 Prometheus 生态中用于网络探测的组件,支持多种协议的目标可达性和质量检测。

探测模块:

模块协议探测方式典型场景
http_2xxHTTP/HTTPSGET/HEAD 请求Web 服务可用性
http_post_2xxHTTP/HTTPSPOST 请求API 端点检测
tcp_connectTCPTCP 端口连接端口可用性
icmpICMPPing 探测主机连通性
dnsDNSDNS 查询DNS 解析质量
grpcgRPCgRPC 健康检查gRPC 服务检测
sshSSHSSH 握手SSH 服务检测
tlsTLSTLS 握手证书过期检测

配置示例:

# blackbox-exporter 配置
modules:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      valid_http_versions: ["HTTP/1.1", "HTTP/2"]
      valid_status_codes: [200, 301, 302]
      preferred_ip_protocol: "ip4"

  tcp_connect:
    prober: tcp
    timeout: 5s

  icmp:
    prober: icmp
    timeout: 5s
    icmp:
      preferred_ip_protocol: "ip4"

  dns:
    prober: dns
    dns:
      query_name: "example.com"
      query_type: "A"
      valid_rcodes: [NOERROR]

Prometheus 采集配置:

scrape_configs:
  - job_name: 'blackbox-http'
    metrics_path: /probe
    params:
      module: [http_2xx]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox-exporter:9115
    static_configs:
      - targets:
          - 'https://example.com'
          - 'https://api.example.com/health'

  - job_name: 'blackbox-icmp'
    metrics_path: /probe
    params:
      module: [icmp]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox-exporter:9115
    static_configs:
      - targets:
          - '192.168.1.1'
          - '10.0.0.1'
26 Prometheus 的高可用方案有哪几种?

答案:

Prometheus 的高可用方案从简单的主备到全局聚合,不同方案在一致性、资源消耗和复杂度上各有取舍。

方案对比:

方案架构数据一致性复杂度适用规模
双跑(Dual Run)两个 Prometheus 采集相同 Target最终一致小型
HA Pair + 联邦主备 + 上层联邦聚合最终一致中型
ThanosSidecar + 对象存储强一致中大型
VictoriaMetricsVMCluster 架构强一致大/超大型
Cortex微服务架构强一致大型

双跑方案:

graph TD
    TA["Target-A"] --> P1["Prom-1"]
    TB["Target-B"] --> P2["Prom-2"]
    P1 --> GRAFANA["Grafana<br/>(PromQL 聚合)"]
    P2 --> GRAFANA

Thanos 方案:

graph TD
    TA["Target-A"] --> P1["Prom-1<br/>+Sidecar"]
    TB["Target-B"] --> P2["Prom-2<br/>+Sidecar"]
    P1 --> TQ["Thanos<br/>Query"]
    P2 --> TQ
    TQ --> G["Grafana"]

关键指标:

双跑:
  - RTO: 分钟级(切换查询源)
  - RPO: 近零(双写)
  - 资源: 2× 存储和计算

Thanos:
  - RTO: 秒级(Query 无状态)
  - RPO: 近零(对象存储)
  - 资源: Prometheus + Sidecar + 对象存储

VictoriaMetrics:
  - RTO: 秒级(无状态组件)
  - RPO: 近零(副本机制)
  - 资源: VictoriaMetrics 集群
27 Prometheus 的 TSDB 索引结构是怎么样的?

答案:

Prometheus TSDB 的索引采用倒排索引结构,支持高效的标签条件查询。

索引层次:

graph TD
    subgraph "1. 符号表 Symbol Table"
        A["'up' → ID=1<br/>'job' → ID=2<br/>'instance' → ID=3<br/>'api-server' → ID=4<br/>'localhost:9090' → ID=5<br/>..."]
    end
    subgraph "2. 倒排索引 Posting"
        B["job='api-server' → [1,5,10,15,...]<br/>instance='local' → [1,2,3,4,...]<br/>__name__='up' → [1,2,5,8,...]"]
    end
    subgraph "3. 序列文件 Series"
        C["Series ID: 1<br/>Labels: job='api-server'<br/>instance='localhost:9090'<br/>Chunks: [chunk1, chunk2]"]
    end
    A --> B --> C

查询执行路径:

up{job="api-server", instance="localhost:9090"}
1. 查找 __name__="up" → Posting List A [1, 2, 5, 8]
2. 查找 job="api-server" → Posting List B [1, 5, 10, 15]
3. 查找 instance="localhost:9090" → Posting List C [1, 2, 3]
4. Intersect(A, B, C) → [1]
5. 通过 Series ID=1 获取 Chunk 和样本数据
28 Prometheus 的 Exemplar 机制是什么?

答案:

Exemplar 是 OpenMetrics 标准的一部分,允许在时序数据中嵌入对应用层 Trace 的引用,实现 Metrics 到 Trace 的关联。

Exemplar 结构:

格式:
  metric_name{labels} value timestamp # {trace_id="abc123", span_id="def456"} 42

示例:
  http_request_duration_seconds_bucket{method="GET",le="0.1"} 15 1717000000 # {trace_id="abc123", span_id="def456"} 0.095

配置:

# Prometheus Server 开启 Exemplar 存储
--enable-feature=exemplar-storage

# 存储配置(默认 100000 个 Exemplar)
--storage.tsdb.exemplar-exemplars-per-series=100

查询 Exemplar:

# 查询 Exemplar 数据
http_request_duration_seconds_bucket{trace_id="abc123"}

# API 查询
GET /api/v1/query_exemplars?query=http_request_duration_seconds_bucket

应用场景:

1. 高延迟请求 → 查看具体 Trace
   发现 P99 延迟 > 1s,通过 Exemplar 找到对应的 Trace ID

2. 错误请求 → 关联详细日志
   Metrics 显示错误率升高,查 Exemplar 获取 Trace ID

3. 慢查询追踪
   Database 延迟异常,关联到具体的查询 Trace
29 Prometheus 的查询性能优化策略有哪些?

答案:

Prometheus 查询性能受数据量、时间范围和查询复杂度影响,优化策略覆盖查询语句和架构层面。

查询优化:

策略方法效果
减少时间范围缩小查询窗口减少扫描的数据量
使用记录规则预计算复杂查询秒级响应
精确匹配标签使用 = 而非 =~利用索引
避免 heavy 函数少用 quantile_over_time减少计算开销
优化 step 参数增大 step减少返回的样本数

PromQL 优化示例:

# 慢查询(全序列扫描)
avg without(cpu, mode)(
  rate(node_cpu_seconds_total[5m])
)

# 优化(先缩小范围)
avg by(instance, mode)(
  rate(node_cpu_seconds_total{mode!="idle"}[5m])
)

架构优化:

# 使用记录规则预计算
groups:
  - name: prometheus_recording
    interval: 1m
    rules:
      - record: service:http_requests:rate1m
        expr: sum by(service, method, status) (rate(http_requests_total[1m]))

# 增加本地缓存
--storage.tsdb.retention.time=30d
--storage.tsdb.min-block-duration=2h
--query.max-concurrency=20
--query.timeout=2m
--query.max-samples=50000000
30 Prometheus 的安全机制和认证方式是什么?

答案:

Prometheus 原生安全功能较为基础,需结合反向代理或专用组件实现完整的认证授权。

支持的安全机制:

机制原生支持说明
Basic Auth采集端(scrape)目标端支持 Basic Auth 认证
Bearer Token采集端支持静态 Token 和文件读取
TLS/mTLS两端支持配置证书
OAuth2采集端支持 OAuth2 客户端凭证
RBAC不支持(需反向代理)Nginx/Envoy 前置
审计日志不支持需外部方案

认证配置:

# Prometheus 采集带认证的目标
scrape_configs:
  - job_name: 'authenticated-target'
    scheme: https
    tls_config:
      ca_file: /etc/prometheus/ca.crt
      cert_file: /etc/prometheus/client.crt
      key_file: /etc/prometheus/client.key
      insecure_skip_verify: false
    basic_auth:
      username: 'prometheus'
      password_file: /etc/prometheus/.password
    # 或 Bearer Token
    authorization:
      type: Bearer
      credentials_file: /etc/prometheus/token
    # 或 OAuth2
    oauth2:
      client_id: 'prometheus'
      client_secret_file: /etc/prometheus/client_secret
      token_url: 'https://auth.example.com/token'
      scopes: ['metrics:read']

# Alertmanager Basic Auth
alerting:
  alertmanagers:
    - scheme: https
      tls_config:
        ca_file: /etc/prometheus/ca.crt
      basic_auth:
        username: 'alertmanager'
        password: '<password>'
      static_configs:
        - targets: ['alertmanager.example.com:9093']

反向代理方案:

# Nginx 反向代理 Prometheus API
server {
    listen 443 ssl;
    server_name prometheus.example.com;

    location / {
        auth_basic "Prometheus";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://localhost:9090;
    }

    location /api/v1/ {
        # 只允许特定角色访问写 API
        if ($request_method = POST) {
            satisfy any;
            allow 10.0.0.0/8;
            deny all;
        }
        proxy_pass http://localhost:9090;
    }
}