15

我们正在尝试使用HBase来存储时间序列数据。我们当前拥有的模型将时间序列作为版本存储在一个单元格中。这意味着单元格最终可能存储数百万个版本,并且此时间序列上的查询将使用HBase中 Get 类上可用的 setTimeRange 方法检索一系列版本。

例如

{
    "row1" : {
        "columnFamily1" : {
            "column1" : {
                1 : "1",
                2 : "2"
            },
            "column2" : {
                1 : "1"
            }
        }
    }
}

这是在 HBase 中存储时间序列数据的合理模型吗?

将数据存储在多列(是否可以跨列查询)或行中的替代模型是否更合适?

4

2 回答 2

19

我认为您不应该在此处使用版本控制来存储时间序列。不是因为它不起作用,而是因为它不是为特定用例设计的,还有其他方法。


我建议您将时间序列存储为时间步长作为列限定符,值将是数据本身。就像是:

{
    "row1" : {
        "columnFamily1" : {
            "col1-000001" : "1"
            "col1-000002" : "2"
            "col1-000003" : "91"
            "col2-000001" : "31"
            }
        }
    }
}

这里的一件好事是 HBase 按排序顺序存储列限定符,因此在读取时间序列时,您应该按顺序看到项目。


另一个现实的选择是将记录的标识符作为行键的第一部分,然后在行键中也有时间步长。就像是:

{
    "fooseries-00001" : {
        "columnFamily1" : {
            "val" : "1"
            }
        }
    }
    "fooseries-00002" : {
        "columnFamily1" : {
            "val" : "2"
            }
        }
    }

}

这有一个很好的功能,它可以很容易地在特定系列中进行范围扫描。例如,拉出 fooseries 的步骤 104 到 199 将非常容易实现并且效率很高。

这个的缺点是删除整个系列将需要更多的管理和同步。另一个缺点是 MapReduce 分析将很难对这些数据进行任何类型的分析。使用上述方法,整个时间序列将传递给一个map()调用,而在这里,map()将为每一帧调用。

于 2012-04-26T03:19:40.803 回答
0

+1 for openTSDB 它做了很多技巧来简化基于时间的汇总查询。

至于原始问题,您可以拥有任意数量的单元格版本(没有限制)。没有性能损失,“Get”在 HBase 中被实现为 Scan,setTimeRange 是非常有效的过滤器。

于 2013-06-16T22:59:05.743 回答