我们正在尝试使用HBase来存储时间序列数据.我们目前的模型将时间序列存储为单元格中的版本.这意味着单元可能最终存储数百万个版本,并且此时间序列上的查询将使用HBase中 Get类上可用的setTimeRange方法检索一系列版本.
例如
{ "row1" : { "columnFamily1" : { "column1" : { 1 : "1", 2 : "2" }, "column2" : { 1 : "1" } } } }
这是在HBase中存储时间序列数据的合理模型吗?
将数据存储在多列中的备用模型(可以跨列查询)还是更合适的行?
我认为您不应该使用版本控制来存储时间序列.不是因为它不起作用,而是因为它不是针对特定用例而设计的,还有其他方法.
我建议您将时间序列存储为时间步长作为列限定符,值将是数据本身.就像是:
{ "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()
将为每个帧调用.
如果我要在HBase上构建一个时间序列解决方案,我肯定会看看StumbleUpon的一个开源版本http://opentsdb.net,因为它在SU内部使用我会认为它是稳定的并且是连续的支持.