【SkyWalking从入门到精通】第15篇:SkyWalking存储选型指南:为档案馆挑选最佳建材
上一篇【第14篇】下一篇【第16篇】SkyWalking UI使用手册学会阅读指挥中心的作战地图明日更新敬请期待上一篇我们把联合指挥部建起来了但指挥官们需要一个存放作战档案的地方——这就是存储层。SkyWalking支持的存储方案有好几种就像档案馆可以用木头、砖头、钢筋混凝土来建。选错了建材档案馆要么很快倒塌数据丢失要么太小装不下性能瓶颈要么太贵建不起资源浪费。今天我们就来为档案馆选最合适的建材。1. 各存储实现的对比1.1 SkyWalking支持的存储方案SkyWalking目前支持以下存储实现存储实现selector值定位推荐场景H2h2内存嵌入式数据库本地开发/快速体验MySQLmysql关系型数据库小规模团队/QPS100PostgreSQLpostgresql关系型数据库小规模团队/QPS100Elasticsearchelasticsearch搜索引擎中大规模生产环境BanyanDBbanyandbSkyWalking自研存储实验性/未来方向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?useSSLfalseuser:rootpassword:rootmaxSize:${SW_STORAGE_MYSQL_MAX_SIZE:250}优点运维成熟DBA熟悉缺点写入瓶颈单表插入慢、查询瓶颈复杂聚合慢、扩展性差适用5-10个微服务、QPS100的小规模团队Elasticsearch——钢筋混凝土大厦ES是SkyWalking生产环境的标准选择就像用钢筋混凝土建档案馆——能抗地震、能扩楼层、能容纳海量档案# Elasticsearch配置详见下节storage:selector:${SW_STORAGE:elasticsearch}elasticsearch:...优点批量写入高效、倒排索引查询快、分片集群可扩展、自然TTL缺点运维复杂、资源消耗大、JVM调优门槛高适用10微服务、QPS100的中大规模团队BanyanDB——未来建筑BanyanDB是SkyWalking社区自研的专用存储引擎还在快速发展中。就像一种新型建筑材料——理论上更适配但施工经验还不够丰富。目前不建议生产使用但值得持续关注。2. 生产环境推荐方案2.1 推荐方案一览┌──────────────────────────────────────────────────────────────────┐ │ 不同规模的生产环境推荐存储方案 │ │ │ │ ┌─ 小规模5-10个服务QPS100─────────────────────┐ │ │ │ 推荐MySQL │ │ │ │ 原因运维成本低团队有DBA经验 │ │ │ │ 注意必须配置TTL定期清理历史数据 │ │ │ │ 升级路径流量增长后切换到ES │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌─ 中规模10-30个服务QPS 100-500──────────────────┐ │ │ │ 推荐Elasticsearch 3节点集群 │ │ │ │ 原因批量写入和聚合查询的性能优势 │ │ │ │ 配置3分片1副本JVM 4GB │ │ │ │ 升级路径扩展到5节点 │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌─ 大规模30个服务QPS500───────────────────────┐ │ │ │ 推荐Elasticsearch 5-7节点集群 │ │ │ │ 原因需要高写入吞吐和快速聚合查询 │ │ │ │ 配置5分片2副本JVM 8-16GB │ │ │ │ 优化冷热数据分离、ILM策略 │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌─ 超大规模100服务QPS2000───────────────────┐ │ │ │ 推荐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压力越大) │ │ │ └──────────────────────────┘ │ │ │ │ 调优建议 │ │ 小规模 → bulkActions2000, bulkSize20, flushInterval15 │ │ 中规模 → bulkActions5000, bulkSize50, flushInterval30 │ │ 大规模 → bulkActions10000, bulkSize100, flushInterval10 │ └──────────────────────────────────────────────────────────────────┘3.3 nameSpace的使用nameSpace参数允许多个OAP集群共用同一个ES集群——就像在一个大档案馆里划分不同区域的档案室# 生产环境OAP集群nameSpace:${SW_NAMESPACE:prod}# 测试环境OAP集群共用ES但数据隔离nameSpace:${SW_NAMESPACE:test}设置nameSpace后ES中的索引名会带上前缀# 无nameSpace: skywalking_segment-20260702 # nameSpaceprod: prod_skywalking_segment-20260702 # nameSpacetest: test_skywalking_segment-202607024. 数据保留时间TTL配置4.1 TTL的工作原理SkyWalking的TTLTime 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_TTL1 SW_CORE_OTHER_METRICS_DATA_TTL3 SW_CORE_MONTH_METRICS_DATA_TTL3 # 小规模生产保留适中 SW_CORE_RECORD_DATA_TTL3 SW_CORE_OTHER_METRICS_DATA_TTL7 SW_CORE_MONTH_METRICS_DATA_TTL6 # 大规模生产Trace保留短聚合保留长 SW_CORE_RECORD_DATA_TTL3 SW_CORE_OTHER_METRICS_DATA_TTL15 SW_CORE_MONTH_METRICS_DATA_TTL184.4 dayStep的作用dayStep参数与TTL配合控制索引的滚动粒度# ES配置elasticsearch:dayStep:${SW_STORAGE_DAY_STEP:1}# 普通数据1天一个索引superDatasetDayStep:${SW_STORAGE_ES_SUPER_DATASET_DAY_STEP:1}# Trace数据1天一个索引dayStep1每天创建一个新索引默认精确TTLdayStep2每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内存磁盘空间10100~100万34GB×350GB30300~300万34GB×3150GB50500~500万58GB×5300GB1001000~1000万716GB×38GB×41TB2002000~2000万716GB×72TB5.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?useSSLfalserewriteBatchedStatementstrueuser:${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}关键注意事项rewriteBatchedStatementstrue——MySQL的批量写入优化参数不加的话写入性能极差连接池大小需要根据并发量调整——maxSize默认250可能太大MySQL不支持自然TTL需要OAP定期执行DELETE语句清理——数据量大时清理很慢不建议使用单表超过百万行——聚合查询会很慢6. 从MySQL迁移到ES如果一开始用了MySQL流量增长后需要迁移到ES。迁移流程# 步骤一部署ES集群# 参考上一篇文章的ES集群配置# 步骤二修改OAP的storage.selectorexportSW_STORAGEelasticsearchexportSW_CLUSTER_NODESes-node1:9200,es-node2:9200# 步骤三重启OAP旧数据不迁移只保留新数据# 注意MySQL中的历史数据无法自动迁移到ES# 历史数据会在MySQL中自然过期后消失# 步骤四验证新数据正常写入EScurles-node1:9200/_cat/indices?v|grepskywalking迁移的关键问题旧数据无法自动迁移。这是为什么我们建议一开始就选ES——避免痛苦的迁移过程。7. 小结存储选型的核心原则是因地制宜、预留空间H2只用于开发体验绝不用于生产MySQL小规模团队有DBA时的选择但升级路径痛苦Elasticsearch生产环境标准选择批量写入高效、聚合查询快速、自然TTLTTL不同粒度数据保留不同时间Trace保留短聚合保留长选型建议宁可一开始选ES也不要从小存储升级——迁移太痛苦下一篇文章我们将进入SkyWalking UI的世界——看看那些漂亮图表背后的故事。上一篇【第14篇】下一篇【第16篇】SkyWalking UI使用手册学会阅读指挥中心的作战地图明日更新敬请期待