上一篇【第14篇】
下一篇【第16篇】SkyWalking UI使用手册:学会阅读指挥中心的作战地图(明日更新,敬请期待)
上一篇我们把联合指挥部建起来了,但指挥官们需要一个存放作战档案的地方——这就是存储层。
SkyWalking支持的存储方案有好几种,就像档案馆可以用木头、砖头、钢筋混凝土来建。选错了建材,档案馆要么很快倒塌(数据丢失),要么太小装不下(性能瓶颈),要么太贵建不起(资源浪费)。
今天我们就来为档案馆选最合适的建材。
1. 各存储实现的对比
1.1 SkyWalking支持的存储方案
SkyWalking目前支持以下存储实现:
| 存储实现 | selector值 | 定位 | 推荐场景 |
|---|---|---|---|
| H2 | h2 | 内存嵌入式数据库 | 本地开发/快速体验 |
| MySQL | mysql | 关系型数据库 | 小规模团队/QPS<100 |
| PostgreSQL | postgresql | 关系型数据库 | 小规模团队/QPS<100 |
| Elasticsearch | elasticsearch | 搜索引擎 | 中大规模生产环境 |
| BanyanDB | banyandb | SkyWalking自研存储 | 实验性/未来方向 |
1.2 横向对比
┌──────────────────────────────────────────────────────────────────┐ │ SkyWalking存储方案横向对比 │ │ │ │ ┌──────┬──────┬──────┬──────┬──────┬──────┐ │ │ │ 维度 │ H2 │MySQL │ PG │ ES │Banyan│ │ │ │ │ │ │ │ │DB │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │写入 │ ★ │ ★★ │ ★★ │★★★★ │★★★ │ │ │ │性能 │(内存 │(单表 │(单表 │(批量 │(列存 │ │ │ │ │快但 │瓶颈) │瓶颈) │写入) │储) │ │ │ │ │易丢)│ │ │ │ │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │查询 │ ★ │ ★★ │ ★★ │★★★★ │★★★ │ │ │ │性能 │(无 │(索引 │(索引 │(倒排 │(专用 │ │ │ │ │优化)│OK) │OK) │索引) │索引) │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │可扩展│ × │ ★★ │ ★★ │★★★★ │★★★ │ │ │ │性 │(单机│(分库 │(分库 │(分片 │(集群 │ │ │ │ │) │分表) │分表) │集群) │设计) │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │运维 │★★★★│ ★★ │ ★★ │ ★ │ ★★ │ │ │ │成本 │(零 │(中 │(中 │(高 │(中 │ │ │ │ │运维)│运维) │运维) │运维) │运维) │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │数据 │ × │ ★★ │ ★★ │★★★★ │★★★ │ │ │ │保留 │(无 │(可 │(可 │(自然 │(专设 │ │ │ │ │TTL) │配置) │配置) │TTL) │TTL) │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ 结论:H2→玩玩, MySQL/PG→小规模, ES→生产标配 │ └──────────────────────────────────────────────────────────────────┘1.3 各存储的特点详解
H2——临时帐篷
H2是嵌入式内存数据库,SkyWalking启动时自带,不需要额外部署。就像一个临时帐篷——搭建快速,但经不起风雨:
# H2配置storage:selector:${SW_STORAGE:h2}h2:driver:org.h2.Driverurl:jdbc:h2:tcp://localhost/skywalking-oap-dbuser:sapassword:优点:零配置零运维,启动秒开
缺点:重启数据丢失(除非用文件模式)、性能极差、不支持TTL
适用:本地开发体验,绝不用于生产
MySQL/PostgreSQL——砖房
MySQL和PG是传统关系型数据库,就像用砖头建档案馆——结实、耐用、运维成熟,但扩展性有限:
# MySQL配置storage:selector:${SW_STORAGE:mysql}mysql:driver:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://mysql-host:3306/skywalking?useSSL=falseuser:rootpassword:rootmaxSize:${SW_STORAGE_MYSQL_MAX_SIZE:250}优点:运维成熟,DBA熟悉
缺点:写入瓶颈(单表插入慢)、查询瓶颈(复杂聚合慢)、扩展性差
适用:5-10个微服务、QPS<100的小规模团队
Elasticsearch——钢筋混凝土大厦
ES是SkyWalking生产环境的标准选择,就像用钢筋混凝土建档案馆——能抗地震、能扩楼层、能容纳海量档案:
# Elasticsearch配置(详见下节)storage:selector:${SW_STORAGE:elasticsearch}elasticsearch:...优点:批量写入高效、倒排索引查询快、分片集群可扩展、自然TTL
缺点:运维复杂、资源消耗大、JVM调优门槛高
适用:10+微服务、QPS>100的中大规模团队
BanyanDB——未来建筑
BanyanDB是SkyWalking社区自研的专用存储引擎,还在快速发展中。就像一种新型建筑材料——理论上更适配,但施工经验还不够丰富。目前不建议生产使用,但值得持续关注。
2. 生产环境推荐方案
2.1 推荐方案一览
┌──────────────────────────────────────────────────────────────────┐ │ 不同规模的生产环境推荐存储方案 │ │ │ │ ┌─ 小规模(5-10个服务,QPS<100)─────────────────────┐ │ │ │ 推荐:MySQL │ │ │ │ 原因:运维成本低,团队有DBA经验 │ │ │ │ 注意:必须配置TTL,定期清理历史数据 │ │ │ │ 升级路径:流量增长后切换到ES │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌─ 中规模(10-30个服务,QPS 100-500)──────────────────┐ │ │ │ 推荐:Elasticsearch 3节点集群 │ │ │ │ 原因:批量写入和聚合查询的性能优势 │ │ │ │ 配置:3分片1副本,JVM 4GB │ │ │ │ 升级路径:扩展到5节点 │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌─ 大规模(30+个服务,QPS>500)───────────────────────┐ │ │ │ 推荐:Elasticsearch 5-7节点集群 │ │ │ │ 原因:需要高写入吞吐和快速聚合查询 │ │ │ │ 配置:5分片2副本,JVM 8-16GB │ │ │ │ 优化:冷热数据分离、ILM策略 │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌─ 超大规模(100+服务,QPS>2000)───────────────────┐ │ │ │ 推荐:Elasticsearch 7+节点 + 冷热分离 │ │ │ │ 原因:超大数据量需要专门的架构设计 │ │ │ │ 配置:7分片2副本,专用热节点+冷节点 │ │ │ │ 优化:ILM + Frozen Tier + 数据降采样 │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘3. Elasticsearch存储配置详解
3.1 完整ES配置参数
# application.yaml - Elasticsearch存储配置storage:selector:${SW_STORAGE:elasticsearch}elasticsearch:nameSpace:${SW_NAMESPACE:""}# 命名空间(多OAP集群共用ES时区分)clusterNodes:${SW_CLUSTER_NODES:localhost:9200}# ES节点列表protocol:${SW_STORAGE_ES_PROTOCOL:http}# http 或 httpstrustStorePath:${SW_STORAGE_ES_SSL_TRUSTSTORE_PATH:""}# TLS证书路径trustStorePass:${SW_STORAGE_ES_SSL_TRUSTSTORE_PASS:""}# TLS证书密码dayStep:${SW_STORAGE_DAY_STEP:1}# TTL步长(见下节)# 索引配置indexShardsNumber:${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:1}# 普通索引分片数indexReplicasNumber:${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}# 普通索引副本数superDatasetIndexShardsFactor:${SW_STORAGE_ES_SUPER_DATASET_INDEX_SHARDS_FACTOR:5}# Trace分片倍数superDatasetDayStep:${SW_STORAGE_ES_SUPER_DATASET_DAY_STEP:1}# Trace数据TTL步长# 批量写入配置bulkActions:${SW_STORAGE_ES_BULK_ACTIONS:5000}# 每批最大文档数bulkSize:${SW_STORAGE_ES_BULK_SIZE:50}# 每批最大MB数flushInterval:${SW_STORAGE_ES_FLUSH_INTERVAL:30}# 批量刷新间隔(秒)concurrentRequests:${SW_STORAGE_ES_CONCURRENT_REQUESTS:2}# 并发写入数# 查询配置resultWindowMaxSize:${SW_STORAGE_ES_RESULT_WINDOW_MAX_SIZE:10000}# 查询最大窗口metadataQueryMaxSize:${SW_STORAGE_ES_METADATA_QUERY_MAX_SIZE:5000}# 元数据查询最大数segmentQueryMaxSize:${SW_STORAGE_ES_SEGMENT_QUERY_MAX_SIZE:200}# Trace查询最大数profileTaskQueryMaxSize:${SW_STORAGE_ES_PROFILE_TASK_QUERY_MAX_SIZE:200}3.2 批量写入参数调优
ES的批量写入(Bulk API)是SkyWalking高效写入的关键。四个参数控制着批量写入的行为:
┌──────────────────────────────────────────────────────────────────┐ │ ES批量写入参数的协作关系 │ │ │ │ 数据到达OAP ──→ 缓存在内存队列 │ │ │ │ │ │ 等待触发条件 │ │ │ │ │ ┌──────────────┼──────────────────────┐ │ │ │ │ │ │ │ │ bulkActions │ bulkSize │ flushInterval │ │ │ (文档数) │ (数据量) │ (时间间隔) │ │ │ 5000条 │ 50MB │ 30秒 │ │ │ │ │ │ │ │ 任一条件满足 → 触发批量写入 │ │ │ └──────────────┴──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─── concurrentRequests ──┐ │ │ │ 控制同时写入的批次数 │ │ │ │ 2 = 最多2批并发写入 │ │ │ │ (值越大吞吐越高但 │ │ │ │ ES压力越大) │ │ │ └──────────────────────────┘ │ │ │ │ 调优建议: │ │ 小规模 → bulkActions=2000, bulkSize=20, flushInterval=15 │ │ 中规模 → bulkActions=5000, bulkSize=50, flushInterval=30 │ │ 大规模 → bulkActions=10000, bulkSize=100, flushInterval=10 │ └──────────────────────────────────────────────────────────────────┘3.3 nameSpace的使用
nameSpace参数允许多个OAP集群共用同一个ES集群——就像在一个大档案馆里划分不同区域的档案室:
# 生产环境OAP集群nameSpace:${SW_NAMESPACE:prod}# 测试环境OAP集群(共用ES,但数据隔离)nameSpace:${SW_NAMESPACE:test}设置nameSpace后,ES中的索引名会带上前缀:
# 无nameSpace: skywalking_segment-20260702 # nameSpace=prod: prod_skywalking_segment-20260702 # nameSpace=test: test_skywalking_segment-202607024. 数据保留时间TTL配置
4.1 TTL的工作原理
SkyWalking的TTL(Time To Live)机制控制数据保留多久。就像档案馆的规定——作战档案保留7天,月度报告保留6个月,年度总结保留3年:
┌──────────────────────────────────────────────────────────────────┐ │ SkyWalking TTL 机制 │ │ │ │ 不同类型数据有不同的保留时间 │ │ │ │ ┌─── 分钟级数据 ───→ 保留短(7天)───→ 数据量最大 ──→ 自动删除 │ │ │ │ │ ├─── 小时级数据 ───→ 保留中等(14天)──→ 数据量中等 ──→ 自动删除 │ │ │ │ │ ├─── 天级数据 ───→ 保留长(30天)───→ 数据量小 ──→ 自动删除 │ │ │ │ │ └─── 月级数据 ───→ 保留最长(6个月)──→ 数据量极小──→ 自动删除 │ │ │ │ 删除方式:ES按时间滚动索引,超期索引整体删除 │ │ (比逐条删除效率高100倍) │ └──────────────────────────────────────────────────────────────────┘4.2 TTL配置参数
# core模块中的TTL配置core:default:# 分钟级指标数据保留天数recordDataTTL:${SW_CORE_RECORD_DATA_TTL:3}# 分钟级指标的其他维度数据保留天数otherMetricsDataTTL:${SW_CORE_OTHER_METRICS_DATA_TTL:7}# 小时/天/月级指标数据保留天数monthMetricsDataTTL:${SW_CORE_MONTH_METRICS_DATA_TTL:6}# Trace数据保留天数# Trace是超大数据集,有独立的TTL配置# 由storage.elasticsearch.superDatasetDayStep配合计算4.3 不同场景的TTL配置
# 开发环境(数据量小,保留短) SW_CORE_RECORD_DATA_TTL=1 SW_CORE_OTHER_METRICS_DATA_TTL=3 SW_CORE_MONTH_METRICS_DATA_TTL=3 # 小规模生产(保留适中) SW_CORE_RECORD_DATA_TTL=3 SW_CORE_OTHER_METRICS_DATA_TTL=7 SW_CORE_MONTH_METRICS_DATA_TTL=6 # 大规模生产(Trace保留短,聚合保留长) SW_CORE_RECORD_DATA_TTL=3 SW_CORE_OTHER_METRICS_DATA_TTL=15 SW_CORE_MONTH_METRICS_DATA_TTL=184.4 dayStep的作用
dayStep参数与TTL配合,控制索引的滚动粒度:
# ES配置elasticsearch:dayStep:${SW_STORAGE_DAY_STEP:1}# 普通数据1天一个索引superDatasetDayStep:${SW_STORAGE_ES_SUPER_DATASET_DAY_STEP:1}# Trace数据1天一个索引dayStep=1:每天创建一个新索引(默认,精确TTL)dayStep=2:每2天创建一个新索引(减少索引数量,降低ES开销)
大规模场景下,可以将Trace的dayStep设为2或3:
# 大规模场景优化superDatasetDayStep:2# Trace索引每2天创建一个# 原本30天=30个索引 → 变为15个索引,减少ES的分片开销5. 不同规模团队的选型建议
5.1 选型决策流程
┌──────────────────────────────────────────────────────────────────┐ │ 存储选型决策流程 │ │ │ │ 你的微服务规模? │ │ │ │ │ ├──→ <5个服务,快速体验? │ │ │ └──→ H2(开发测试,绝不生产) │ │ │ │ │ ├──→ 5-10个服务,团队小? │ │ │ ├──→ 团队有DBA? ──→ MySQL │ │ │ └──→ 团队没有DBA? ──→ 考虑ES(运维工具成熟) │ │ │ │ │ ├──→ 10-30个服务? │ │ │ └──→ ES 3节点(标准选择) │ │ │ │ │ ├──→ 30-100个服务? │ │ │ └──→ ES 5-7节点(+冷热分离) │ │ │ │ │ └──→ 100+服务? │ │ └──→ ES 7+节点(+ILM +Frozen Tier) │ │ │ │ 核心原则:宁可一开始选ES,也不要从小存储升级 │ │ 因为MySQL→ES的数据迁移非常痛苦 │ └──────────────────────────────────────────────────────────────────┘5.2 ES资源预估
| 微服务数 | QPS | 日Trace量 | ES节点数 | JVM内存 | 磁盘空间 |
|---|---|---|---|---|---|
| 10 | 100 | ~100万 | 3 | 4GB×3 | 50GB |
| 30 | 300 | ~300万 | 3 | 4GB×3 | 150GB |
| 50 | 500 | ~500万 | 5 | 8GB×5 | 300GB |
| 100 | 1000 | ~1000万 | 7 | 16GB×3+8GB×4 | 1TB |
| 200+ | 2000+ | ~2000万+ | 7+ | 16GB×7+ | 2TB+ |
5.3 MySQL选型的注意事项
如果选择了MySQL,需要注意以下限制:
# MySQL配置(完整版)storage:selector:${SW_STORAGE:mysql}mysql:driver:${SW_STORAGE_MYSQL_DRIVER:com.mysql.cj.jdbc.Driver}url:jdbc:mysql://${SW_STORAGE_MYSQL_URL:mysql-host:3306}/skywalking?useSSL=false&rewriteBatchedStatements=trueuser:${SW_STORAGE_MYSQL_USER:root}password:${SW_STORAGE_MYSQL_PASSWORD:root}maxSize:${SW_STORAGE_MYSQL_MAX_SIZE:250}# 最大连接数minSize:${SW_STORAGE_MYSQL_MIN_SIZE:5}# 最小连接数# 重要:MySQL的TTL依赖定时清理任务# 需要确保以下参数正确配置recordDataTTL:${SW_CORE_RECORD_DATA_TTL:3}otherMetricsDataTTL:${SW_CORE_OTHER_METRICS_DATA_TTL:7}关键注意事项:
rewriteBatchedStatements=true——MySQL的批量写入优化参数,不加的话写入性能极差- 连接池大小需要根据并发量调整——
maxSize默认250可能太大 - MySQL不支持自然TTL,需要OAP定期执行DELETE语句清理——数据量大时清理很慢
- 不建议使用单表超过百万行——聚合查询会很慢
6. 从MySQL迁移到ES
如果一开始用了MySQL,流量增长后需要迁移到ES。迁移流程:
# 步骤一:部署ES集群# (参考上一篇文章的ES集群配置)# 步骤二:修改OAP的storage.selectorexportSW_STORAGE=elasticsearchexportSW_CLUSTER_NODES=es-node1:9200,es-node2:9200# 步骤三:重启OAP(旧数据不迁移,只保留新数据)# 注意:MySQL中的历史数据无法自动迁移到ES# 历史数据会在MySQL中自然过期后消失# 步骤四:验证新数据正常写入EScurl"es-node1:9200/_cat/indices?v"|grepskywalking迁移的关键问题:旧数据无法自动迁移。这是为什么我们建议一开始就选ES——避免痛苦的迁移过程。
7. 小结
存储选型的核心原则是"因地制宜、预留空间":
- H2:只用于开发体验,绝不用于生产
- MySQL:小规模团队有DBA时的选择,但升级路径痛苦
- Elasticsearch:生产环境标准选择,批量写入高效、聚合查询快速、自然TTL
- TTL:不同粒度数据保留不同时间,Trace保留短,聚合保留长
- 选型建议:宁可一开始选ES,也不要从小存储升级——迁移太痛苦
下一篇文章,我们将进入SkyWalking UI的世界——看看那些漂亮图表背后的故事。
上一篇【第14篇】
下一篇【第16篇】SkyWalking UI使用手册:学会阅读指挥中心的作战地图(明日更新,敬请期待)