
【一句话结论】
采用分层存储架构,结合多维度分片(时间+区域+事件)和多级索引(对象存储时间/区域索引+搜索引擎倒排索引),通过内存+SSD缓存热点数据,支撑PB级视频的高效存储与多维度查询(时间、区域、事件类型检索)。
【原理/概念讲解】
老师口吻,解释各组件与策略:
【对比与适用场景】
| 组件/策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 对象存储(如Ceph) | 分布式文件系统,存储大文件 | 高容量、高扩展性、高可用,适合冷数据 | 原始视频存储(PB级) | 需元数据索引辅助查询,单文件大小限制(如Ceph支持大文件) |
| 时序数据库(如InfluxDB) | 专为时间序列数据设计 | 时间范围查询高效、支持聚合(如求和、计数) | 视频元数据(时间、区域、事件) | 不适合存储大文件,数据量过大时需分片 |
| 搜索引擎(如Elasticsearch) | 分布式全文检索引擎 | 复杂查询(多维度)高效,支持实时索引 | 视频检索(时间、区域、事件) | 需索引维护成本,索引更新延迟 |
| 时间分片 | 按时间维度切分数据 | 时间查询高效,按时间范围过滤 | 按时间检索(如最近24小时) | 时间粒度影响查询粒度(如按天/小时) |
| 区域分片 | 按空间维度切分数据 | 区域查询高效,按城市/区域过滤 | 按区域检索(如某城市) | 区域划分需合理,避免数据倾斜 |
| 事件分片 | 按事件类型切分数据 | 事件类型查询高效,按事件类型过滤 | 按事件类型检索(如交通事故) | 事件类型数量影响分片数,避免分片过多导致管理复杂 |
【示例】
function getShardKey(videoId, timestamp, regionId, eventType) {
return `${timestamp.substring(0,10)}-${regionId}-${eventType}`;
}
// 示例:20230101-beijing-traffic_accident
{
"query": {
"bool": {
"must": [
{"range": {"timestamp": {"gte": "2023-01-01T00:00:00", "lte": "2023-01-31T23:59:59"}}},
{"term": {"region_id": "beijing"}},
{"term": {"event_type": "traffic_accident"}}
]
}
}
}
【面试口播版答案】
面试官您好,针对佳都科技城市大脑的PB级视频存储与查询优化问题,我的核心方案是构建分层存储架构,结合多维度分片和索引设计。首先,原始视频数据采用对象存储(如Ceph)存储,利用其高容量和扩展性;视频元数据(时间、区域、事件)则存入时序数据库(如InfluxDB)和搜索引擎(如Elasticsearch)。查询优化方面,分片策略上采用时间+区域+事件的多维度分片,比如按天分片时间数据,按城市分片区域数据,按事件类型分片事件数据,这样查询时只需访问对应分片,减少数据扫描量。索引设计上,对象存储的元数据建立时间索引和区域索引,搜索引擎建立倒排索引(事件类型、区域、时间范围),支持复杂查询。缓存策略上,使用Redis缓存热点元数据(如最近24小时的视频元数据),SSD缓存热点视频片段(如最近24小时的视频前几秒),提升查询速度。这样整体方案既能支撑PB级数据的存储,又能高效处理时间、区域、事件类型的查询。
【追问清单】
【常见坑/雷区】