2014-09-03 111 views
1

我想实现一个时间序列数据库来存储简单的计数器使用redis(和PHP,但语言不应该是相关的,我认为)。所以,我实现了我的Redis键如下(简化):redis时间序列数据和时区

someprefix:YYYY-MM-DD:somecounter

现在,当我想要得到的数据范围为特定的时间间隔,我只是得到所有钥匙对于特定的范围,这一切都工作正常。 (YYYY-MM-DD是UTC的日期)

现在我想实现根据某个时区X获取数据的能力。 我的问题是:有什么方法可以使用此关键模式任何程度的准确性?

我猜测没有,因为根本没有时间信息,所以我也必须添加至少小时和分钟的关键所以时区转换工作正常。我也可能应该在较小的时间间隔内保存信息,否则在转换时区时有时候我会在不同日期获得所有数据,因为时区差异不应该超过13小时,因此给我错误的结果,我是对的?

在redis键上使用unix时间戳而不是格式化日期会更合适吗?例如,如果我稍后决定以更小的精度存储数据,比如说每小时或每10分钟一次,那么什么是更灵活的密钥格式?

希望我能够正确解释我的问题,但请随时要求澄清。

感谢

回答

1

它总是好去与时代(UNIX时间戳),当你要处理的时区。

我会建议屏蔽时间戳来构造密钥。例如事件发生在时间戳1409800502515(星期四,2014年9月4日3时15分02秒格林尼治标准时间),你可以在样

someprefix:1409800500000:somecounter OR 
someprefix:1409800464000:somecounter 
小时级别或级别日这样

Hour bucket = 1409800502515 - (1409800502515 % (60 * 60)) = 1409800500000 
Day bucket = 1409800502515 - (1409800502515 % (24 * 60 * 60)) = 1409800464000 

和框架键斗它

例如计算每小时页面浏览,找到合适的每小时桶和增加计数器

mypage.html:1409800464000:page_views INCR 10 
+0

感谢您的答案John,但作为示例,请考虑以下情形: 位于不同时区(如UTC +1)的客户端请求数据从2014-09-02到2014-09- 06。 我的系统会将客户端提供的日期转换为UTC,因此转换后我有2014-09-01 23:00:00至2014-09-05 23:00:00,我将最终获取所有数据对于第1天,实际上我只需要从那天起1小时。 所以我的问题是:在这种情况下,每天创造一个真正有用的时间段?即使我每小时只有一小桶,也有15和30m偏移的时区。 – dev 2014-09-04 17:48:29

0

首先,我不知道你是如何做的“让所有键的具体响e,这一切都工作正常“,但如果您使用KEYS someprefix:*请注意,这不是建议的生产实践。考虑使用v2.8中提供的SCAN命令。其次,你可以考虑使用一个有序集进行计数。所以,按照你的惯例,你将会得到一个叫做someprefix:somecounter的关键字,你将会以这个纪元的成员作为他们的得分。使用epoch和计数器的读数作为唯一的成员名称(例如'1409800500000:1`,其中1409800500000是时期,1是计数器的值)。

请注意,您可以测量从几年到几微秒的时间分辨率 - 这一切都取决于您在设置分数之前应用了多少div到原始时期。

+0

你好Itamar。现在,我正在不同的键上保存不同的日子,正如我在初始帖子中所说的那样。不,不使用keys命令。我只是在请求的时间间隔内遍历所有密钥,所以如果客户端请求2014-09-01到2014-09-05的数据,我只需要在代码中使用循环来获取这些日期的所有密钥并创建一个数组看起来像“day => counter”,它反过来被用来填充图形。重要的问题是如何将日期存储在redis中,以便我可以快速执行时区转换并在客户端的tz中返回相关范围。 – dev 2014-09-08 16:55:08