存储是可观测性平台成本最高的组件,占整体支出的 40-60%。选择合适的存储后端、优化存储策略、控制数据增长,直接决定了可观测性平台的可持续性。
本章将深入四大存储后端的架构与选型:VictoriaMetrics/Mimir 用于指标存储、Tempo 用于追踪存储、Loki 用于日志存储。讨论每种后端的设计哲学、性能特征、成本模型,以及如何根据你的规模和需求做出选择。
一、指标存储后端#
1.1 Prometheus 的局限#
Prometheus 是最流行的指标采集和查询系统,但它有两个根本局限:
| 局限 | 说明 | 影响 |
|---|
| 单机架构 | 不支持水平扩展 | 无法处理超过单机容量的指标 |
| 本地存储 | 数据存储在本地磁盘 | 无持久化保证、无长期存储 |
1.2 VictoriaMetrics 架构深入#
VictoriaMetrics 是一个高性能、成本优化的时序数据库,兼容 Prometheus 协议。它的核心设计理念是”简单架构 + 极致压缩 + 低成本”。
graph TB
subgraph VM["VictoriaMetrics 集群架构"]
VMINSERT["vminsert<br/>写入节点<br/>水平扩展<br/>无状态"]
VMSTORAGE["vmstorage<br/>存储节点<br/>水平扩展<br/>有状态"]
VMSELECT["vmselect<br/>查询节点<br/>水平扩展<br/>无状态"]
end
subgraph 客户端
PROM["Prometheus<br/>remote_write"]
OTEL["OTel Collector"]
GRAFANA["Grafana"]
end
PROM -->|"remote_write"| VMINSERT
OTEL -->|"OTLP"| VMINSERT
VMINSERT -->|"一致性哈希"| VMSTORAGE
VMSELECT -->|"广播查询"| VMSTORAGE
GRAFANA -->|"PromQL"| VMSELECT
style VM fill:#e8f5e9,stroke:#2e7d32
VictoriaMetrics 的关键设计决策:
| 设计决策 | 选择 | 原因 |
|---|
| 存储格式 | 自定义列存 | 比 Gorilla 编码更好的压缩比 |
| 写入路径 | WAL + 内存缓冲 + 刷盘 | 兼顾写入性能和数据持久性 |
| 查询路径 | 广播到所有 vmstorage | 简单、无需查询路由 |
| 数据分片 | 一致性哈希 by tenant + metric name | 均匀分布、减少热点 |
| 压缩 | zstd + 自定义编码 | 10-20x 压缩比 |
写入路径:
sequenceDiagram
participant App as 应用/Collector
participant Insert as vminsert
participant Storage as vmstorage
participant Disk as 磁盘
App->>Insert: remote_write (SNAPPY 压缩)
Insert->>Insert: 解压 + 解析
Insert->>Insert: 一致性哈希选择 vmstorage
Insert->>Storage: 写入请求
Storage->>Storage: 写入 WAL(预写日志)
Storage->>Storage: 写入内存索引
Storage->>Disk: 异步刷盘(每 1s)
Note over Storage: WAL 保证数据不丢<br/>内存索引加速查询
查询路径:
sequenceDiagram
participant Grafana as Grafana
participant Select as vmselect
participant Storage1 as vmstorage-1
participant Storage2 as vmstorage-2
Grafana->>Select: PromQL 查询
Select->>Storage1: 广播查询
Select->>Storage2: 广播查询
Storage1-->>Select: 返回部分结果
Storage2-->>Select: 返回部分结果
Select->>Select: 合并结果
Select-->>Grafana: 返回完整结果
| 特性 | VictoriaMetrics | Prometheus |
|---|
| 架构 | 分布式 | 单机 |
| 写入性能 | 5M+ samples/s | 500K samples/s |
| 压缩比 | 10-20x | 3-5x |
| 长期存储 | 原生支持 | 需要 Thanos |
| 多租户 | 集群版 | |
| 降采样 | | |
| 兼容性 | Prometheus 兼容 | 原生 |
1.3 Mimir 架构深入#
Mimir 是 Grafana Labs 开发的大规模指标存储后端,设计目标是”无限扩展”。与 VictoriaMetrics 的简化分布式架构不同,Mimir 采用了微服务架构:
graph TB
subgraph 写入路径
DIST["Distributor<br/>写入入口<br/>一致性哈希"]
ING["Ingester<br/>写入 WAL + 刷块<br/>TSDB 格式"]
end
subgraph 读取路径
QRY["Querier<br/>查询引擎"]
QF["Query Frontend<br/>查询调度 + 分割"]
RULER["Ruler<br/>告警规则评估"]
end
subgraph 存储["对象存储"]
S3["S3 / GCS / ABS"]
end
subgraph 元数据
RING["Ring<br/>一致性哈希环"]
CONSUL["Consul / etcd<br/>成员管理"]
end
DIST --> ING --> S3
QRY --> S3
QRY --> ING
QF --> QRY
RULER --> QRY
DIST -.-> RING
ING -.-> RING
RING -.-> CONSUL
style 写入路径 fill:#e3f2fd,stroke:#1565c0
style 读取路径 fill:#e8f5e9,stroke:#2e7d32
style 存储 fill:#fff3e0,stroke:#e65100
style 元数据 fill:#f3e5f5,stroke:#6a1b9a
Mimir 的关键组件:
| 组件 | 职责 | 扩展方式 |
|---|
| Distributor | 写入入口、验证、一致性哈希 | 水平扩展 |
| Ingester | 写入 WAL、维护内存 TSDB、刷块到对象存储 | 水平扩展(带数据迁移) |
| Querier | 查询引擎、合并 Ingester + 对象存储数据 | 水平扩展 |
| Query Frontend | 查询调度、分割大查询、缓存 | 水平扩展 |
| Compactor | 合并小块、降采样、清理过期数据 | 单实例或有限扩展 |
| Store Gateway | 查询对象存储中的历史数据 | 水平扩展 |
| Ruler | 告警规则评估 | 水平扩展 |
| 特性 | Mimir | VictoriaMetrics |
|---|
| 架构 | 微服务 | 简化分布式 |
| 最大规模 | 10 亿+ 活跃序列 | 1 亿+ 活跃序列 |
| 对象存储 | S3/GCS/ABS | |
| 多租户 | 原生 | 集群版 |
| 运维复杂度 | 高 | 中 |
| 适用场景 | 超大规模 | 中大规模 |
| 查询缓存 | Query Frontend 缓存 | vmselect 缓存 |
| 降采样 | Compactor | vmrollup |
1.4 选型建议#
| 规模 | 活跃序列数 | 推荐 | 原因 |
|---|
| 小型 | < 100 万 | Prometheus | 简单、够用 |
| 中型 | 100 万-1000 万 | VictoriaMetrics 单机 | 性能好、运维简单 |
| 大型 | 1000 万-1 亿 | VictoriaMetrics 集群 | 水平扩展 |
| 超大型 | > 1 亿 | Mimir | 无限扩展 |
二、追踪存储后端#
2.1 Tempo 架构深入#
Tempo 是 Grafana 生态的追踪存储后端,设计哲学是”仅索引 TraceID,其他全扫描”。这个设计选择使得 Tempo 的存储成本远低于全索引方案(如 Jaeger + Elasticsearch)。
graph TB
subgraph Tempo["Tempo 架构"]
DIST["Distributor<br/>接收 OTLP<br/>验证 + 路由"]
ING["Ingester<br/>写入 WAL + 刷块<br/>Parquet 格式"]
QRY["Querier<br/>查询引擎<br/>TraceQL"]
QF["Query Frontend<br/>查询调度"]
COMP["Compactor<br/>合并块<br/>降采样"]
end
subgraph 存储["对象存储"]
S3["S3 / GCS / Local"]
end
subgraph 指标["衍生指标"]
MG["Metrics Generator<br/>Span → 指标<br/>RED 指标"]
end
DIST --> ING --> S3
QRY --> S3
QRY --> ING
QF --> QRY
COMP --> S3
ING --> MG
style Tempo fill:#e0f2f1,stroke:#00695c
style 存储 fill:#fff3e0,stroke:#e65100
style 指标 fill:#e8f5e9,stroke:#2e7d32
Tempo 的存储格式:
Tempo 将追踪数据以 Parquet 列存格式存储在对象存储中。Parquet 格式提供了优秀的压缩比和列式查询性能:
| 存储层 | 格式 | 用途 |
|---|
| WAL | 本地文件 | 写入缓冲,保证数据不丢 |
| 块(Block) | Parquet 列存 | 长期存储,高压缩比 |
| 索引 | TraceID → Block 映射 | 快速查找 TraceID 所在块 |
Tempo 的查询路径:
- TraceID 查询:通过索引找到 TraceID 所在的 Block,从对象存储读取
- TraceQL 查询:扫描 Block 中的 Parquet 数据,利用列存裁剪加速
- 搜索查询:全扫描,但利用 Parquet 的列式存储和统计信息加速
2.2 Tempo vs Jaeger#
| 维度 | Tempo | Jaeger |
|---|
| 索引方式 | 仅 TraceID | 全索引(服务、操作、标签) |
| 存储成本 | 低(无索引开销) | 高(索引开销大) |
| 搜索方式 | TraceID + TraceQL | 结构化搜索 |
| 对象存储 | S3/GCS | 仅 ES/Cassandra |
| 与 Grafana 集成 | 深度 | 一般 |
| 适用场景 | 大规模 + Grafana 生态 | 需要灵活搜索 |
| 查询语言 | TraceQL | Jaeger Query |
| 衍生指标 | Metrics Generator | |
2.3 Tempo 配置#
endpoint: s3.amazonaws.com
block_retention: 720h # 30 天保留
path: /var/tempo/generator/wal
- url: http://mimir:9009/api/v1/push
2.4 TraceQL 查询实战#
{resource.service.name = "order-service"}
{resource.service.name = "order-service" && duration > 500ms}
{span.http.method = "POST" && span.http.status_code >= 500}
{resource.service.name = "frontend"} -> {resource.service.name = "order-service" && duration > 1s}
三、日志存储后端#
3.1 Loki 架构深入#
Loki 采用”仅索引元数据”的设计,成本远低于 Elasticsearch。它的核心思想是:不索引日志内容,只索引标签(Labels)。查询时先通过标签缩小范围,再对日志内容进行扫描和过滤。
graph TB
subgraph 写入路径[" 写入路径"]
DIST["Distributor<br/>验证 + 路由"]
ING["Ingester<br/>写入 WAL + 刷块<br/>压缩日志 + 索引标签"]
end
subgraph 读取路径[" 读取路径"]
QF["Query Frontend<br/>查询调度 + 分割"]
QRY["Querier<br/>查询引擎<br/>LogQL"]
end
subgraph 存储[" 对象存储"]
S3["S3 / GCS<br/>日志块(压缩)<br/>索引块(标签)"]
end
subgraph 缓存[" 缓存"]
MEM["Memcached / Redis<br/>查询结果缓存<br/>索引缓存"]
end
DIST --> ING --> S3
QF --> QRY
QRY --> S3
QRY --> ING
QRY -.-> MEM
style 写入路径 fill:#e3f2fd,stroke:#1565c0
style 读取路径 fill:#e8f5e9,stroke:#2e7d32
style 存储 fill:#fff3e0,stroke:#e65100
style 缓存 fill:#f3e5f5,stroke:#6a1b9a
Loki 的存储格式:
| 存储内容 | 格式 | 说明 |
|---|
| 日志数据 | 压缩块(gzstd) | 原始日志文本,按时间分块 |
| 标签索引 | 倒排索引 | 标签 → 日志块 ID 映射 |
| WAL | 本地文件 | 写入缓冲,保证数据不丢 |
3.2 Loki vs Elasticsearch#
| 维度 | Loki | Elasticsearch |
|---|
| 索引方式 | 仅索引标签 | 全文倒排索引 |
| 存储成本 | 低(1/5 ~ 1/10) | 高 |
| 全文搜索 | 慢(扫描) | 快(倒排索引) |
| 结构化搜索 | 快(标签索引) | 快 |
| 查询语言 | LogQL | Lucene/KQL |
| 适用场景 | 结构化日志 + Grafana | 全文搜索 + 日志分析 |
| 对象存储 | S3/GCS | 需要本地存储 |
| 水平扩展 | | |
不要把所有日志都发到 Elasticsearch。对于结构化日志,Loki 的成本通常是 Elasticsearch 的 1/5 到 1/10。只有在需要全文搜索的场景时才使用 Elasticsearch。
3.3 LogQL 查询实战#
{service="order-service"} |= "ERROR"
{service="order-service"} | json | level="ERROR" | error_code="DB_TIMEOUT"
sum(count_over_time({service="order-service"} | json | level="ERROR" [5m])) by (error_code)
quantile_over_time(0.99, {service="order-service"} | json | unwrap duration_ms [5m])
{service="order-service"} | json | trace_id="abc123"
topk(10, sum(rate({service="order-service"} | json | unwrap duration_ms [5m])) by (http_route))
sum(rate({service="order-service"} | json | level="ERROR" [5m])) / sum(rate({service="order-service"} | json [5m])) * 100
四、存储格式与压缩策略#
4.1 指标存储格式#
| 后端 | 存储格式 | 压缩算法 | 压缩比 | 说明 |
|---|
| VictoriaMetrics | 自定义列存 | zstd + Delta + XOR | 10-20x | 类似 Gorilla 编码但更激进 |
| Mimir | TSDB 块 | Snappy + Delta + XOR | 8-15x | 与 Prometheus 相同格式 |
| Prometheus | TSDB 块 | Snappy + Delta + XOR | 3-5x | 原生格式 |
时序数据压缩的核心技术:
| 压缩技术 | 适用数据 | 压缩比 | 说明 |
|---|
| Delta 编码 | 时间戳 | 5-10x | 相邻时间戳差值很小 |
| XOR 编码 | 浮点值 | 5-10x | 相邻值异或后前导零多 |
| 字典编码 | 标签名/值 | 3-5x | 重复字符串用 ID 替代 |
| zstd/Snappy | 整体压缩 | 2-3x | 通用压缩算法 |
4.2 追踪存储格式#
| 后端 | 存储格式 | 压缩算法 | 压缩比 | 说明 |
|---|
| Tempo | Parquet 列存 | zstd | 5-10x | 列存天然适合压缩 |
| Jaeger (ES) | JSON 文档 | LZ4 | 2-3x | 行存,压缩比低 |
| Jaeger (Cassandra) | 自定义 | Snappy | 3-5x | 宽行存储 |
4.3 日志存储格式#
| 后端 | 存储格式 | 压缩算法 | 压缩比 | 说明 |
|---|
| Loki | 压缩块 | gzstd | 8-15x | 结构化日志压缩比更高 |
| Elasticsearch | 倒排索引 | LZ4/DEFLATE | 2-5x | 索引开销大 |
4.4 压缩比优化实践#
| 优化方式 | 适用后端 | 效果 | 说明 |
|---|
| 结构化日志 | Loki | 压缩比 8x → 15x | JSON 格式比纯文本更易压缩 |
| 高基数标签分离 | VictoriaMetrics | 压缩比 10x → 20x | 将高基数标签移到日志 |
| 块大小优化 | Mimir | 压缩比 8x → 15x | 更大的块 → 更好的压缩 |
| 块合并 | Tempo | 压缩比 5x → 10x | 合并小块减少元数据开销 |
| 标签优化 | Loki | 存储量减少 50% | 减少标签数量、避免高基数标签 |
五、查询性能优化#
5.1 指标查询优化#
rate(http_request_duration_seconds_sum[5m])
rate(http_request_duration_seconds_sum{service="order-service"}[5m])
rate(http_request_duration_seconds_sum{service="order-service",method="POST"}[5m])
sum(rate(http_request_duration_seconds_sum[5m])) by (user_id)
sum(rate(http_request_duration_seconds_sum[5m])) by (service, method)
| 优化策略 | 效果 | 说明 |
|---|
| 缩小时间范围 | 查询速度 2-10x | 查询 1h vs 7d 差异巨大 |
| 减少标签过滤 | 查询速度 1.5-3x | 精确匹配比正则快 |
| 避免高基数 Group By | 查询速度 5-100x | 高基数导致大量时间序列 |
| 使用 Recording Rules | 查询速度 10-100x | 预计算常用查询 |
| 启用查询缓存 | 重复查询 100x | Mimir/VictoriaMetrics 支持 |
5.2 追踪查询优化#
{resource.service.name = "order-service" && duration > 100ms}
| 优化策略 | 效果 | 说明 |
|---|
| 使用 TraceID 查询 | 最快 | 直接定位到 Block |
| 缩小时间范围 | 2-10x | 减少扫描的 Block 数量 |
| 添加服务名过滤 | 2-5x | 利用 Parquet 列存裁剪 |
| 使用 Metrics Generator | 10-100x | 先查指标再查追踪 |
5.3 日志查询优化#
{service="order-service"} |~ "error|timeout"
{service="order-service"} | json | level="ERROR"
{service="order-service", level="ERROR"}
| 优化策略 | 效果 | 说明 |
|---|
| 使用标签过滤 | 10-100x | 标签有索引,扫描快 |
| 使用结构化查询 | 2-5x | JSON 解析比正则快 |
| 缩小时间范围 | 2-10x | 减少扫描的 Block 数量 |
| 限制返回条数 | 1.5-3x | 使用 limit 参数 |
| 启用查询缓存 | 重复查询 100x | Loki + Memcached |
六、保留策略#
6.1 保留策略设计#
不同信号的数据价值随时间递减,保留策略应该反映这一特征:
| 信号 | 热数据(0-7 天) | 温数据(7-30 天) | 冷数据(30+ 天) |
|---|
| 指标 | 原始分辨率 | 5 分钟降采样 | 1 小时降采样 |
| 追踪 | 全量(采样后) | 仅错误 + 慢请求 | 仅错误 |
| 日志 | 全量 | 仅 ERROR + WARN | 仅 ERROR |
6.2 VictoriaMetrics 保留配置#
-retentionPeriod=90d # 全局保留 90 天
-downsampling.period=5m:30d # 5 分钟降采样保留 30 天
-downsampling.period=1h:90d # 1 小时降采样保留 90 天
6.3 Tempo 保留配置#
block_retention: 720h # 30 天保留
compaction_window: 1h # 1 小时合并窗口
compacted_block_retention: 1h # 合并后旧块保留 1 小时
6.4 Loki 保留配置#
- max_query_length: 721h # 最大查询范围 30 天
retention_period: 744h # 保留 31 天
working_directory: /var/loki/compactor
retention_delete_delay: 2h
delete_request_cancel_period: 24h
七、存储成本优化#
7.1 成本模型#
| 信号 | 存储成本 | 计算公式 |
|---|
| 指标 | 低 | 序列数 × 采样间隔 × 保留期 × 每样本字节数 |
| 追踪 | 中 | Span 数 × 每 Span 字节数 × 采样率 × 保留期 |
| 日志 | 高 | 日志量 × 压缩比 × 保留期 |
7.2 降采样#
降采样(Downsampling)是降低长期存储成本的核心策略:
| 原始分辨率 | 降采样后 | 存储节省 | 适用场景 |
|---|
| 15s | 5m | 95% | 30 天以上的历史数据 |
| 15s | 1h | 99.6% | 90 天以上的历史数据 |
| 15s | 1d | 99.99% | 365 天以上的历史数据 |
7.3 数据分层#
graph LR
HOT["热数据<br/>0-7 天<br/>SSD/内存<br/>原始分辨率"] --> WARM["温数据<br/>7-30 天<br/>HDD/对象存储<br/>5 分钟降采样"]
WARM --> COLD["冷数据<br/>30+ 天<br/>对象存储<br/>1 小时降采样"]
style HOT fill:#ffcdd2,stroke:#c62828
style WARM fill:#fff3e0,stroke:#e65100
style COLD fill:#e3f2fd,stroke:#1565c0
7.4 成本对比#
| 后端 | 默认压缩比 | 优化后压缩比 | 优化方式 |
|---|
| VictoriaMetrics | 10x | 20x | 高基数标签分离 |
| Mimir | 8x | 15x | 块大小优化 |
| Tempo | 5x | 10x | 块合并 |
| Loki | 8x | 15x | 结构化日志 + 标签优化 |
八、选型决策矩阵#
8.1 综合选型#
| 信号 | 小型(< 100 服务) | 中型(100-500 服务) | 大型(> 500 服务) |
|---|
| 指标 | Prometheus | VictoriaMetrics | Mimir |
| 追踪 | Jaeger | Tempo | Tempo |
| 日志 | Loki | Loki | Loki |
| 性能分析 | Pyroscope | Pyroscope | Parca |
8.2 选型决策流程图#
graph TB
START["选择存储后端"] --> SIGNAL{"什么信号?"}
SIGNAL -->|"指标"| SCALE_M{"规模?"}
SIGNAL -->|"追踪"| TRACE_Q{"查询模式?"}
SIGNAL -->|"日志"| LOG_Q{"全文搜索?"}
SCALE_M -->|"< 100 万序列"| PROM["Prometheus<br/>简单够用"]
SCALE_M -->|"100 万-1 亿"| VM["VictoriaMetrics<br/>性能好运维简单"]
SCALE_M -->|"> 1 亿"| MIMIR["Mimir<br/>无限扩展"]
TRACE_Q -->|"TraceID 查询为主"| TEMPO["Tempo<br/>低成本"]
TRACE_Q -->|"需要灵活搜索"| JAEGER["Jaeger + ES<br/>全索引"]
LOG_Q -->|"否(结构化日志)"| LOKI["Loki<br/>低成本"]
LOG_Q -->|"是(全文搜索)"| ES["Elasticsearch<br/>倒排索引"]
style START fill:#e8eaf6,stroke:#283593
style PROM fill:#c8e6c9,stroke:#2e7d32
style VM fill:#c8e6c9,stroke:#2e7d32
style MIMIR fill:#c8e6c9,stroke:#2e7d32
style TEMPO fill:#c8e6c9,stroke:#2e7d32
style JAEGER fill:#fff3e0,stroke:#e65100
style LOKI fill:#c8e6c9,stroke:#2e7d32
style ES fill:#fff3e0,stroke:#e65100
8.3 成本估算#
| 规模 | 指标存储/月 | 追踪存储/月 | 日志存储/月 | 总计/月 |
|---|
| 小型 | $50 | $30 | $100 | $180 |
| 中型 | $200 | $150 | $500 | $850 |
| 大型 | $1,000 | $800 | $3,000 | $4,800 |
以上成本基于 2026 年 AWS S3 存储价格估算,实际成本取决于数据量、保留期和采样策略。使用对象存储(S3/GCS)比使用块存储(EBS/PV)便宜 5-10 倍。
九、动手实践#
9.1 部署完整存储栈#
docker compose up -d prometheus tempo loki
curl http://localhost:9090/api/v1/query?query=up
curl http://localhost:3200/ready
curl http://localhost:3100/ready
9.2 验证数据流#
curl -X POST http://localhost:4318/v1/traces \
-H "Content-Type: application/json" \
-d '{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"test"}}]},"scopeSpans":[{"spans":[{"traceId":"01234567890123456789012345678901","spanId":"0123456789012345","name":"test","kind":1,"startTimeUnixNano":"1700000000000000000","endTimeUnixNano":"1700000001000000000"}]}]}]}'
open http://localhost:3000/explore
9.3 验证清单#
| 检查项 | 验证方式 | 预期结果 |
|---|
| Prometheus 采集 | 查询 up | targets 全部为 1 |
| Tempo 接收追踪 | Grafana 查询 | 能看到追踪 |
| Loki 接收日志 | Grafana 查询 | 能看到日志 |
| 数据源连通 | Grafana 测试 | 全部连通 |
十、本章小结#
上一章从全景视角介绍了可观测性数据管道。
可观测性四大存储后端的要点基本都在这里了。
| 主题 | 核心要点 | 关键词 |
|---|
| VictoriaMetrics | 简化分布式架构(vminsert/vmstorage/vmselect),10-20x 压缩比,适合中大规模。 | VictoriaMetrics |
| Mimir | 微服务架构,10 亿+ 活跃序列,适合超大规模,运维复杂度高。 | Mimir |
| Tempo | 仅索引 TraceID + Parquet 列存,成本远低于 Jaeger,TraceQL 提供灵活查询。 | Tempo |
| Loki | 仅索引标签,成本远低于 Elasticsearch,LogQL 提供结构化查询。 | Loki |
| 存储格式 | 指标用列存 + Delta/XOR 编码,追踪用 Parquet 列存,日志用压缩块。 | 存储格式 |
| 压缩策略 | 结构化日志、高基数标签分离、块大小优化、块合并。 | 压缩策略 |
| 查询优化 | 缩小时间范围、使用标签过滤、避免高基数 Group By、启用缓存。 | 查询优化 |
| 保留策略 | 不同信号不同保留期,降采样降低长期存储成本。 | 保留策略 |
| 选型原则 | 小规模用简单方案,大规模用分布式方案,始终优先对象存储。 | 选型原则 |