【发布时间】:2017-06-17 15:57:38
【问题描述】:
一位朋友问我如何在 HBase 中逐帧存储原始视频。典型的访问模式是在一段时间内检索帧。每帧大约是。 7MB,素材以每秒约 30 帧的速度拍摄。例如,一个 20 分钟的视频大约需要 250GB 的存储空间。
我看到了 HBase: the definitive guide 的作者 Lars George 的精彩视频,标题为 HBase Schema Design: things you need to know,他在其中谈到了存储视频“块”(他谈到视频的 sn-p 开始于 1:07:12 和结束于 1:08:52),所以看起来 HBase 可能适合这个用例。
我创建了几个行键选项:
场景0:rowkey=视频ID+时间戳;单列中的框架(又高又瘦的桌子),例如
key col
video1|1497567476.123 image=[image BLOB]
video1|1497567476.156 image=[image BLOB]
...
video1|1497567536.014 image=[image BLOB]
优点:
- 简单
缺点:
- 由于键是连续的,我们阅读时的热点
场景一:rowkey = hash(video ID + round(timestamp, 1 minute)) + timestamp;单列中的框架,例如
key col
18ba6892ce0933ece7282b1f2971b3fd|1497567536.014 image=[image BLOB]
...
2ea8ce843615408fb19f8d6e44df32c7|1497567476.123 image=[image BLOB]
2ea8ce843615408fb19f8d6e44df32c7|1497567476.156 image=[image BLOB]
rowkey 有一个前缀,可确保一分钟的块分布在整个集群中,并且在一分钟的块中,帧按连续的时间顺序排列。
优点:
- 跨区域分布的块,并且在每个块内,读取将是顺序的。这是一种折衷方案,允许顺序读取和跨 HBase 区域分布数据。
缺点:
- 有点不灵活;不确定最佳的块时间窗口应该是多少,一旦设置,就很难改变
场景二:rowkey = hash(video ID + round(timestamp, 1 minute));列中的帧从“基本”时间偏移(列类似于 OpenTSDB):
key col:base_time + (0 * x millis) col:base_time + (1 * x millis) col:base_time + (2 * x millis)
18ba6892ce0933ece7282b1f2971b3fd image=[image BLOB] ... ...
2ea8ce843615408fb19f8d6e44df32c7 image=[image BLOB] image=[image BLOB] [image BLOB]
优点:
- 模式已被 OpenTSDB 证明适用于时间序列指标(参见 this presentation 中的幻灯片 13)
缺点:
- 非常大的行,这对于 HBase 通常不是一个好主意
对于视频帧的最佳 rowkey 设计,是否有人有任何建议或见解?
注意:我知道几个类似的例子,它们不是使用 HBase 来存储视频片段,而是使用具有单独索引的序列文件或 .har 文件来捕获元数据以允许随机访问。现在,我想专注于 HBase:特别是行键设计。
【问题讨论】: