跳到主要内容

时序数据库与日志存储

问题

什么是时序数据库?适合存储什么类型的数据?

答案

时序数据特点

时序数据是按时间顺序记录的数据点序列,具有以下特点:

  • 写多读少(持续写入大量数据)
  • 很少更新或删除
  • 查询通常按时间范围和聚合
  • 数据有时效性(旧数据可归档/删除)

适用场景

场景数据类型
监控指标CPU、内存、请求延迟
IoT 传感器温度、湿度、位置
前端埋点PV/UV、性能指标
金融行情股价、交易量
日志分析应用日志、访问日志

常见方案对比

方案类型特点适用
InfluxDB时序数据库简单易用、SQL-like监控指标
ClickHouse列式分析库超快聚合查询日志分析、BI
TimescaleDBPG 扩展兼容 SQL已有 PG 生态
Prometheus监控系统Pull 模型 + AlertManager基础设施监控
Elasticsearch搜索引擎全文搜索 + 聚合日志检索

前端监控数据存储

metrics-storage.ts
// 前端性能指标入库(ClickHouse)
interface PerformanceMetric {
timestamp: Date;
page_url: string;
fcp: number; // First Contentful Paint
lcp: number; // Largest Contentful Paint
cls: number; // Cumulative Layout Shift
ttfb: number; // Time to First Byte
user_agent: string;
country: string;
}

// ClickHouse 建表(列式存储 + 按日期分区)
const createTableSQL = `
CREATE TABLE web_vitals (
timestamp DateTime,
page_url String,
fcp Float32,
lcp Float32,
cls Float32,
ttfb Float32,
user_agent String,
country LowCardinality(String)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (page_url, timestamp)
TTL timestamp + INTERVAL 90 DAY -- 90 天自动清理
`;

// 聚合查询:每小时平均 LCP
const query = `
SELECT
toStartOfHour(timestamp) AS hour,
page_url,
avg(lcp) AS avg_lcp,
quantile(0.75)(lcp) AS p75_lcp,
quantile(0.95)(lcp) AS p95_lcp,
count() AS sample_count
FROM web_vitals
WHERE timestamp >= now() - INTERVAL 24 HOUR
GROUP BY hour, page_url
ORDER BY hour DESC
`;

常见面试问题

Q1: 为什么不用 MySQL 存时序数据?

答案

  1. MySQL 按行存储,聚合查询需要扫描大量无关列
  2. 数据量大时写入性能下降(索引维护)
  3. 缺少自动数据过期(TTL)
  4. 缺少时序专用聚合函数

Q2: ClickHouse 为什么查询这么快?

答案

  1. 列式存储:只读需要的列,减少 IO
  2. 向量化执行:批量处理数据
  3. 数据压缩:同列数据压缩率极高
  4. 稀疏索引:分区 + 排序键快速定位

Q3: ELK Stack 是什么?

答案

  • Elasticsearch:分布式搜索和分析引擎
  • Logstash:数据收集和处理管道
  • Kibana:可视化仪表板

常用于日志收集和分析。现代替代方案:Loki(Grafana 生态)。

相关链接