我们正尝试使用 HBase 来存储时间序列数据。我们目前的模型将时间序列存储为单元格中的版本。这意味着单元格可能最终存储数百万个版本,此时间序列上的查询将使用 HBase 中Get类的可用setTimeRange方法检索一系列版本。
e.g。
{
"row1" : {
"columnFamily1" : {
"column1" : {
1 : "1",
2 : "2"
},
"column2" : {
1 : "1"
}
}
}
}
这是在HBase中存储时间序列数据的合理模型吗?
将数据存储在多个列中的替代模型(可以跨列查询)还是更合适的行?
答案 0 :(得分:17)
我认为您不应该使用版本控制来存储时间序列。不是因为它不起作用,而是因为它不是针对特定用例设计的,还有其他方法。
我建议您将时间序列存储为时间步长作为列限定符,值将是数据本身。类似的东西:
{
"row1" : {
"columnFamily1" : {
"col1-000001" : "1"
"col1-000002" : "2"
"col1-000003" : "91"
"col2-000001" : "31"
}
}
}
}
这里的一个好处是HBase按排序顺序存储列限定符,因此在阅读时间序列时,您应该按顺序查看项目。
另一个现实的选择是将记录的标识符作为rowkey的第一部分,但是在rowkey中也有时间步。类似的东西:
{
"fooseries-00001" : {
"columnFamily1" : {
"val" : "1"
}
}
}
"fooseries-00002" : {
"columnFamily1" : {
"val" : "2"
}
}
}
}
这有一个很好的功能,即在特定系列中进行范围扫描非常容易。例如,拉出fooseries的步骤104到199对于实现和高效来说将是非常简单的。
这个的缺点是删除整个系列将需要更多的管理和同步。另一个缺点是MapReduce分析将很难对这些数据进行任何类型的分析。使用上述方法,整个时间序列将传递到一个map()
调用,而在此处,将为每个帧调用map()
。
答案 1 :(得分:6)
如果我要在HBase上构建时间序列解决方案,我肯定会看看StumbleUpon的http://opentsdb.net/开源版本,因为它在SU内部使用我会认为它是稳定的并且是连续的支持。
答案 2 :(得分:3)
看看Zohmg。
答案 3 :(得分:2)
实际上有一篇名为"A three-dimensional data model in HBase for large time-series dataset analysis" (2012)(only Slides)的论文,它显示了利用HBase版本字段的数据模型的改进性能,就像提出的提问者一样。但它并非设计用于保存无限“版本”而是设计一桶细胞(Sensordata一小时或一天)。
答案 4 :(得分:0)
+1 for openTSDB它有许多技巧来简化基于时间的汇总查询。
对于原始问题,您可以拥有任意数量的单元格版本(没有限制)。没有性能损失,'Get'在HBase中实现为扫描,而setTimeRange是非常有效的过滤器。