用于存储视频帧的HBase架构设计:行与列,行作为列

时间:2017-06-17 15:57:38

标签: hbase video-processing

一位朋友问我如何在HBase中逐帧存储原始视频。典型的访问模式是检索一段时间的帧。每帧约。 7MB,并以每秒约30帧的速度拍摄素材。例如,一段20分钟的视频将占用大约250GB的存储空间。

我看到了HBase: the definitive guide的作者Lars George的精彩视频,名为HBase Schema Design: things you need to know,他谈到存储视频“块”(他在谈论视频的片段从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]

的优点:

  • 简单

缺点:

  • 我们读的热点,因为键是连续的

场景1:rowkey = hash(视频ID + round(时间戳,1分钟))+时间戳;单列中的帧,例如

key                                             col
18ba6892ce0933ece7282b1f2971b3fd|1497567536.014 image=[image BLOB]
...
2ea8ce843615408fb19f8d6e44df32c7|1497567476.123 image=[image BLOB]
2ea8ce843615408fb19f8d6e44df32c7|1497567476.156 image=[image BLOB]

rowkey有一个前缀,可确保在群集中分布一分钟的块,并且在一分钟的块内,帧按连续的时间顺序排列。

的优点:

  • 分布在各个区域的块,并且在每个块内,读取将是顺序的。这是一种折衷方案,允许顺序读取跨HBase区域分发数据。

缺点:

  • 有点不灵活;不确定最佳块时间窗口应该是什么,一旦设置,就很难改变

场景2:rowkey = hash(视频ID + round(时间戳,1分钟));列中的帧偏离“基准”时间(列类似于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设计有任何建议或见解?

注意:我知道几个类似的例子,使用序列文件或带有单独索引的.har文件,而不是使用HBase来存储视频素材,以捕获元数据以允许随机访问。现在,我想专注于HBase:特别是rowkey设计。

2 个答案:

答案 0 :(得分:1)

我喜欢你,但我建议使用( videoID%number_of_regions)+ videoID + timestamp 。这样您就不会受限于1分钟的限制,但读取是连续的,整个视频存储在同一区域。

答案 1 :(得分:1)

每秒视频有200MB的数据(每帧7MB * 30 fps)。

当单元格很小并且从单个机器读取所有内容然后等待所有机器返回结果时,数据局部性是一件好事。加载甚至5秒的视频(1GB)已经是单个机器磁盘IO的巨大负载,因此数据位置无济于事。

我认为按键/加密键是这里最好的解决方案

key = hash(video_id, timestamp) + video_id + timestamp

您将在群集中获得均匀的数据分布并分散负载。您可以将帧存储在单独的列中的单行中,或者将frame_id添加到键中,这无关紧要。

为了获得更好的性能,您还需要设置正确的CF大小设置以适合您的数据。