关于 pyroscope
Grafana Pyroscope Skill 是持续性能分析平台的部署和使用指南,面向需要按代码位置分析应用性能的开发与运维人员。内容涵盖多种语言的剖析数据采集、存储、查询及 Grafana 集成。
主要功能
- 01持续采集代码级性能剖析数据
- 02支持多种语言与剖析类型
- 03单体和微服务部署模式
- 04对象存储后端配置
- 05Grafana 指标、日志和追踪关联
适用场景
- 01定位应用中的 CPU 或内存消耗
- 02在 Kubernetes 上部署剖析服务
- 03将剖析数据存入对象存储
- 04通过追踪关联分析代码性能
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ julianobarbosa/ claude-code-skills --skill pyroscope安装后在 Claude Code 中输入/pyroscope确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/architecture.mdhelm-deployment.mdsdk-instrumentation.mdtroubleshooting.md详细介绍
Grafana Pyroscope 技能
Grafana Pyroscope 综合指南——这是一款开源的持续剖析平台,用于在代码层面分析应用性能。
什么是 Pyroscope?
Pyroscope 是一个可水平扩展、高可用、多租户的持续剖析系统,能够:
- 持续收集剖析数据,开销极低(约 2-5% CPU)
- 提供代码级可见性,精确到源代码行
- 将压缩后的剖析数据存储在对象存储中(S3、GCS、Azure Blob)
- 与 Grafana 集成,以关联剖析数据、指标、日志和追踪数据
- 支持多种语言——Go、Java、Python、.NET、Ruby、Node.js、Rust
架构概览
核心组件
| 组件 | 用途 |
|---|---|
| 分发器 | 验证传入的剖析数据并将其路由到摄取器 |
| 摄取器 | 在内存中缓冲剖析数据、进行压缩并写入存储 |
| 查询器 | 检索并处理剖析数据以供分析 |
| 查询前端 | 处理查询请求、缓存和调度 |
| 查询调度器 | 管理每个租户的查询队列 |
| 存储网关 | 提供对长期剖析数据存储的访问 |
| 压缩器 | 合并数据块、管理保留策略并处理删除 |
数据流
写入路径:
SDK/Alloy → Distributor → Ingester → Object Storage
↓
Blocks + Indexes
读取路径:
Query → Query Frontend → Query Scheduler → Querier
↓
Ingesters + Store Gateway
部署模式
1. 单体模式(-target=all)
- 所有组件在单个进程中运行
- 适用于:开发、小规模部署
- 查询 URL:
http://pyroscope:4040/
2. 微服务模式(生产环境)
- 每个组件独立运行
- 可水平扩展
- 查询 URL:
http://pyroscope-querier:4040/
# Microservices deployment
architecture:
microservices:
enabled: true
querier:
replicas: 3
distributor:
replicas: 2
ingester:
replicas: 3
compactor:
replicas: 3
storeGateway:
replicas: 3
快速入门 - Kubernetes Helm
添加仓库
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
安装单二进制版本
kubectl create namespace pyroscope
helm install pyroscope grafana/pyroscope -n pyroscope
安装微服务模式
curl -Lo values-micro-services.yaml \
https://raw.githubusercontent.com/grafana/pyroscope/main/operations/pyroscope/helm/pyroscope/values-micro-services.yaml
helm install pyroscope grafana/pyroscope \
-n pyroscope \
--values values-micro-services.yaml
剖析类型
| 类型 | 描述 | 语言 |
|---|---|---|
| CPU | 墙钟时间/CPU 时间消耗 | 全部 |
| 内存 | 分配对象/空间、堆 | Go、Java、.NET |
| Goroutine | 并发 Goroutine | Go |
| 互斥锁 | 锁争用(次数/持续时间) | Go、Java、.NET |
| 阻塞 | 线程阻塞/延迟 | Go |
| 异常 | 异常跟踪 | Python |
客户端配置方式
方式 1:SDK 插桩(推送模式)
Go SDK:
import "github.com/grafana/pyroscope-go"
pyroscope.Start(pyroscope.Config{
ApplicationName: "my-app",
ServerAddress: "http://pyroscope:4040",
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileAllocObjects,
pyroscope.ProfileAllocSpace,
pyroscope.ProfileInuseObjects,
pyroscope.ProfileInuseSpace,
pyroscope.ProfileGoroutines,
pyroscope.ProfileMutexCount,
pyroscope.ProfileMutexDuration,
pyroscope.ProfileBlockCount,
pyroscope.ProfileBlockDuration,
},
Tags: map[string]string{
"env": "production",
},
})
Java SDK:
PyroscopeAgent.start(
new Config.Builder()
.setApplicationName("my-app")
.setServerAddress("http://pyroscope:4040")
.setProfilingEvent(EventType.ITIMER)
.setFormat(Format.JFR)
.build()
);
Python SDK:
import pyroscope
pyroscope.configure(
application_name="my-app",
server_address="http://pyroscope:4040",
tags={"env": "production"},
)
方式 2:Grafana Alloy(拉取模式)
通过注解自动插桩:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
metadata:
annotations:
profiles.grafana.com/cpu.scrape: "true"
profiles.grafana.com/cpu.port: "8080"
profiles.grafana.com/memory.scrape: "true"
profiles.grafana.com/memory.port: "8080"
profiles.grafana.com/goroutine.scrape: "true"
profiles.grafana.com/goroutine.port: "8080"
Alloy 配置:
pyroscope.scrape "default" {
targets = discovery.kubernetes.pods.targets
forward_to = [pyroscope.write.default.receiver]
profiling_config {
profile.process_cpu { enabled = true }
profile.memory { enabled = true }
profile.goroutine { enabled = true }
}
}
pyroscope.write "default" {
endpoint {
url = "http://pyroscope:4040"
}
}
方式 3:eBPF 剖析(Linux)
适用于编译型语言(C/C++、Go、Rust):
pyroscope.ebpf "default" {
forward_to = [pyroscope.write.default.receiver]
targets = discovery.kubernetes.pods.targets
}
存储配置
Azure Blob Storage
pyroscope:
config:
storage:
backend: azure
azure:
container_name: pyroscope-data
account_name: mystorageaccount
account_key: ${AZURE_ACCOUNT_KEY}
AWS S3
pyroscope:
config:
storage:
backend: s3
s3:
bucket_name: pyroscope-data
region: us-east-1
endpoint: s3.us-east-1.amazonaws.com
access_key_id: ${AWS_ACCESS_KEY_ID}
secret_access_key: ${AWS_SECRET_ACCESS_KEY}
Google Cloud Storage
pyroscope:
config:
storage:
backend: gcs
gcs:
bucket_name: pyroscope-data
# Uses GOOGLE_APPLICATION_CREDENTIALS
Grafana 集成
数据源配置
apiVersion: 1
datasources:
- name: Pyroscope
type: grafana-pyroscope-datasource
access: proxy
url: http://pyroscope-querier:4040
isDefault: false
editable: true
追踪到剖析数据的关联
启用 Span 剖析,以关联追踪数据与剖析数据:
使用 OpenTelemetry 的 Go:
import (
"github.com/grafana/pyroscope-go"
otelpyroscope "github.com/grafana/otel-profiling-go"
)
tp := trace.NewTracerProvider(
trace.WithSpanProcessor(otelpyroscope.NewSpanProcessor()),
)
要求:
- Span 最短持续时间:20ms
- 支持:Go、Java、.NET、Python、Ruby
资源要求
单二进制版本(开发环境)
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1
memory: 2Gi
微服务(生产环境)
| 组件 | CPU 请求 | 内存请求 | 内存限制 |
|---|---|---|---|
| 分发器 | 500m | 256Mi | 1Gi |
| 摄取器 | 1 | 8Gi | 16Gi |
| 查询器 | 100m | 256Mi | 1Gi |
| 查询前端 | 100m | 256Mi | 1Gi |
| 压缩器 | 1 | 8Gi | 16Gi |
| 存储网关 | 1 | 8Gi | 16Gi |
常用 Helm 值
# Production values
architecture:
microservices:
enabled: true
pyroscope:
persistence:
enabled: true
size: 50Gi
config:
storage:
backend: s3
s3:
bucket_name: pyroscope-prod
region: us-east-1
# High availability
ingester:
replicas: 3
terminationGracePeriodSeconds: 600
querier:
replicas: 3
distributor:
replicas: 2
compactor:
replicas: 3
terminationGracePeriodSeconds: 1200
storeGateway:
replicas: 3
# Pod disruption budget
podDisruptionBudget:
enabled: true
maxUnavailable: 1
# Topology spread
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
# Monitoring
serviceMonitor:
enabled: true
# Alloy for profile collection
alloy:
enabled: true
API 端点
摄取
# Push profiles (Connect API)
POST /push.v1.PusherService/Push
# Legacy HTTP (pprof, JFR formats)
POST /ingest
查询
# Merged profile
POST /querier.v1.QuerierService/SelectMergeProfile
# Flame graph data
POST /querier.v1.QuerierService/SelectMergeStacktraces
# Available labels
POST /querier.v1.QuerierService/LabelNames
# Profile types
POST /querier.v1.QuerierService/ProfileTypes
# Legacy render
GET /pyroscope/render?query={}&from=now-1h&until=now
系统
# Readiness
GET /ready
# Configuration
GET /config
# Metrics
GET /metrics
故障排除
诊断命令
# Check pod status
kubectl get pods -n pyroscope -l app.kubernetes.io/name=pyroscope
# View ingester logs
kubectl logs -n pyroscope -l app.kubernetes.io/component=ingester --tail=100
# Check ring status
kubectl exec -it pyroscope-0 -n pyroscope -- \
curl http://localhost:4040/ingester/ring
# Verify readiness
kubectl exec -it pyroscope-0 -n pyroscope -- \
curl http://localhost:4040/ready
# Check configuration
kubectl exec -it pyroscope-0 -n pyroscope -- \
curl http://localhost:4040/config
常见问题
1. 摄取器内存溢出:
ingester:
resources:
limits:
memory: 16Gi
2. 存储身份验证失败:
# Azure - verify RBAC
az role assignment create \
--role "Storage Blob Data Contributor" \
--assignee-object-id <principal-id> \
--scope <storage-scope>
3. 标签基数过高:
# Limit label cardinality
pyroscope:
config:
validation:
max_label_names_per_series: 25
4. 查询超时:
pyroscope:
config:
querier:
query_timeout: 5m
max_concurrent: 8
参考文档
按主题查看详细配置:
外部资源
注意事项
- 每个应用的性能分析采样率:繁忙的服务采用 100Hz 采样会产生不小的开销——请先在金丝雀环境中进行性能分析。
- 存储压缩会在合并期间阻止新写入——大规模压缩会导致写入停顿;需要调整分块大小和压缩窗口。
- 标签基数激增:每个请求都添加标签会使存储量暴涨;请明确限制标签值,否则存储量每周都会翻倍。
- Trace 集成:要关联 Span 与性能分析数据,需要端到端传递匹配的
traceparent标头;任何一个未插桩的环节都会导致关联静默丢失。 - eBPF 性能分析器与 SDK 性能分析器:两者的归因方式不同,有时会互相冲突。不要在同一服务上同时运行两者。
- gRPC 与 HTTP 推送:数据相同,但 Ingester 的速率限制不同;负载较高时,HTTP 推送受到的限流更严格。
评论
支持 Markdown