用于存储视频帧的 HBase 架构设计:行与列,行作为列
Posted
技术标签:
【中文标题】用于存储视频帧的 HBase 架构设计:行与列,行作为列【英文标题】:HBase schema design to store video frames: rows vs columns, rows as columns 【发布时间】: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:特别是行键设计。
【问题讨论】:
【参考方案1】:视频每秒有 200MB 的数据(每帧 7MB * 30 fps)。
当单元格较小时,数据局部性是一件好事,从单台机器读取所有内容然后等待所有机器返回结果会更快。加载 5 秒的视频 (1GB) 对于单机磁盘 IO 来说已经是一个巨大的负载,因此数据本地化无济于事。
我相信加盐/加前缀是这里最好的解决方案
key = hash(video_id, timestamp) + video_id + timestamp
您将在整个集群中获得均匀的数据分布并分散负载。您可以将帧存储在单独的列中的单行中,也可以将 frame_id 添加到键中,没关系。
为了获得更好的性能,您还需要设置正确的 CF 大小设置以适合您的数据。
【讨论】:
【参考方案2】:我喜欢你的方法,但我建议使用 (videoID % number_of_regions) + videoID + timestamp。这样您就不会被限制在 1 分钟的限制内,但读取是连续的,并且整个视频都存储在同一区域中。
【讨论】:
以上是关于用于存储视频帧的 HBase 架构设计:行与列,行作为列的主要内容,如果未能解决你的问题,请参考以下文章