Redis Essentials 读书笔记 - 第三章:Time Series (A Collection of Observations)

来源:互联网 发布:android开发特效源码 编辑:程序博客网 时间:2024/05/24 03:07

Chapter 3. Time Series (A Collection of Observations)

时间序列(Time Series)是在一段时间范围内排序的时间点的值,可用于统计,社交网络,电信工程等一切需要时间度量的场景。它可以来进行预测,如股市走向,环境条件变化等。stock market changes, real estate trends, environmental conditions, and more.

时间序列的例子包括:
* 随时间变化,报纸中特定词语的使用
* 年度最低工资变化
* 每日股价波动
* 按月产品购买趋势
* 气候变化

时间序列面临存储的挑战,例如如果每秒存一个时间,每天则需86,400个时间点,长时间存储压力更大,对于内存数据库如Redis更是如此。

另一个问题是,随时间推移,之前细粒度的时间点失去价值,例如在后期的统计中,秒级的时间点已没有意义,通常用小时就够了。

New York Times提供了一个有趣的工具,可统计自1851年起,在报纸中使用的特定词语的统计图。可参见http://chronicle.nytlabs.com
下面是对于china关键词的年度统计图,不能按月或按天:

Building the foundation

本节演示用Strings, Hash, Sorted Sets 和 HyperLogLogs实现时间序列。

时间粒度支持日,小时,分钟,秒,每一个粒度一个key,当事件发生时,每一个key都需要更新

时间按时间粒度分组,例如某一秒发生的时间会同时归类到相应的分钟,小时和天。

此解决方案非常适合于实时计数,如页面浏览,视频观看,点击数,购买商品数等。

此程序的运行方式如下,在命令行中可指定数据类型从而对应相应的实现,但结果是一样的。

[redis@tt12c examples]$ cd chapter\ 3[redis@tt12c chapter 3]$ lstimeseries-hash.js         timeseries-sorted-set.js  using-timeseries.jstimeseries-hyperloglog.js  timeseries-string.js      using-timeseries-unique.js[redis@tt12c chapter 3]$ node using-timeseries.js stringResults from 1sec:Timestamp   | Value--------------- | ------  0 | 1  1 | 2  2 | 0  3 | 1  4 | 0Results from 1min:Timestamp   | Value--------------- | ------  0 | 4  60  | 1  120 | 0[redis@tt12c chapter 3]$ node using-timeseries.js hashResults from 1sec:Timestamp   | Value--------------- | ------  0 | 1  1 | 2  2 | 0  3 | 1  4 | 0Results from 1min:Timestamp   | Value--------------- | ------  0 | 4  60  | 1  120 | 0

为了避免存太多的数据,每一个key都设置了过期时间,如秒级只保留2小时,分钟级保留7天等,小时级保留60天,天级永不过期.

当事件发生时,每一个key都会被更新, 如下:

TimeSeries.prototype.insert = function(timestampInSeconds) { // 1  for (var granularityName in this.granularities) { // 2    var granularity = this.granularities[granularityName]; // 3    var key = this._getKeyName(granularity, timestampInSeconds); // 4    this.client.incr(key); // 5    if (granularity.ttl !== null) { // 6      this.client.expire(key, granularity.ttl); // 7    }  }};

执行以下的代码产生时间序列:

item1Purchases.insert(beginTimestamp); // 7item1Purchases.insert(beginTimestamp + 1); // 8item1Purchases.insert(beginTimestamp + 1); // 9item1Purchases.insert(beginTimestamp + 3); // 10item1Purchases.insert(beginTimestamp + 61); // 11

通过redis-cli monitor可以看到实际执行的命令:

1462417516.878865 [0 127.0.0.1:63610] "info"1462417516.884225 [0 127.0.0.1:63610] "flushall"1462417516.917339 [0 127.0.0.1:63610] "incr" "purchases:item1:1sec:0"1462417516.917352 [0 127.0.0.1:63610] "expire" "purchases:item1:1sec:0" "7200"1462417516.917359 [0 127.0.0.1:63610] "incr" "purchases:item1:1min:0"1462417516.917363 [0 127.0.0.1:63610] "expire" "purchases:item1:1min:0" "604800"1462417516.917369 [0 127.0.0.1:63610] "incr" "purchases:item1:1hour:0"1462417516.917373 [0 127.0.0.1:63610] "expire" "purchases:item1:1hour:0" "5184000"1462417516.917378 [0 127.0.0.1:63610] "incr" "purchases:item1:1day:0"1462417516.917382 [0 127.0.0.1:63610] "incr" "purchases:item1:1sec:1"1462417516.917386 [0 127.0.0.1:63610] "expire" "purchases:item1:1sec:1" "7200"1462417516.917417 [0 127.0.0.1:63610] "incr" "purchases:item1:1min:0"1462417516.917425 [0 127.0.0.1:63610] "expire" "purchases:item1:1min:0" "604800"1462417516.917430 [0 127.0.0.1:63610] "incr" "purchases:item1:1hour:0"1462417516.917435 [0 127.0.0.1:63610] "expire" "purchases:item1:1hour:0" "5184000"1462417516.917440 [0 127.0.0.1:63610] "incr" "purchases:item1:1day:0"1462417516.917444 [0 127.0.0.1:63610] "incr" "purchases:item1:1sec:1"1462417516.917448 [0 127.0.0.1:63610] "expire" "purchases:item1:1sec:1" "7200"1462417516.917467 [0 127.0.0.1:63610] "incr" "purchases:item1:1min:0"1462417516.917471 [0 127.0.0.1:63610] "expire" "purchases:item1:1min:0" "604800"1462417516.917476 [0 127.0.0.1:63610] "incr" "purchases:item1:1hour:0"1462417516.917481 [0 127.0.0.1:63610] "expire" "purchases:item1:1hour:0" "5184000"1462417516.917486 [0 127.0.0.1:63610] "incr" "purchases:item1:1day:0"1462417516.917490 [0 127.0.0.1:63610] "incr" "purchases:item1:1sec:3"1462417516.917494 [0 127.0.0.1:63610] "expire" "purchases:item1:1sec:3" "7200"1462417516.917499 [0 127.0.0.1:63610] "incr" "purchases:item1:1min:0"1462417516.917503 [0 127.0.0.1:63610] "expire" "purchases:item1:1min:0" "604800"1462417516.917508 [0 127.0.0.1:63610] "incr" "purchases:item1:1hour:0"1462417516.917513 [0 127.0.0.1:63610] "expire" "purchases:item1:1hour:0" "5184000"1462417516.917518 [0 127.0.0.1:63610] "incr" "purchases:item1:1day:0"1462417516.917522 [0 127.0.0.1:63610] "incr" "purchases:item1:1sec:61"1462417516.917526 [0 127.0.0.1:63610] "expire" "purchases:item1:1sec:61" "7200"1462417516.917530 [0 127.0.0.1:63610] "incr" "purchases:item1:1min:60"1462417516.917534 [0 127.0.0.1:63610] "expire" "purchases:item1:1min:60" "604800"1462417516.917539 [0 127.0.0.1:63610] "incr" "purchases:item1:1hour:0"1462417516.917550 [0 127.0.0.1:63610] "expire" "purchases:item1:1hour:0" "5184000"1462417516.917556 [0 127.0.0.1:63610] "incr" "purchases:item1:1day:0"1462417516.917562 [0 127.0.0.1:63610] "mget" "purchases:item1:1sec:0" "purchases:item1:1sec:1" "purchases:item1:1sec:2" "purchases:item1:1sec:3" "purchases:item1:1sec:4"1462417516.917576 [0 127.0.0.1:63610] "mget" "purchases:item1:1min:0" "purchases:item1:1min:60" "purchases:item1:1min:120"

这个例子可以很方便的改成记录股价变动,只需把INCRBY改为SET,把计数改为设置股价。

Optimizing with Hashes

前面String的实现每天会产生87,865个key (60 * 60 * 24 + 60 * 24 + 24 + 1),太多的key调试不方便,也消耗内存(每日11MB),因此我们用Hash的ziplist来优化(每日800KB)。
具体的benchmark可参见:https://gist.github.com/hltbra/2fbf5310aabbecee68c5

Hash要使用ziplist需要同时满足以下条件, 否则就会用hash table:

It must have fewer fields than the threshold Set in the configuration hash-max-ziplist-entries. The default value for hash-max-ziplist-entries is 512.
No field value can be bigger than hash-max-ziplist-value. The default value for hash-max-ziplist-value is 64 bytes.

Note

The benchmark used can be found at https://gist.github.com/hltbra/2fbf5310aabbecee68c5.

前述String的实现每秒至少产生一个key,为了使用Hash介绍内存空间,我们需要把多个key置于一个组中, 每组中key的数量小于512。分组的依据如下:

1sec granularity: Stores a maximum of 300 timestamps of 1 second each (5 minutes of data points)
1min granularity: Stores a maximum of 480 timestamps of 1 minute each (8 hours of data points)
1hour granularity: Stores a maximum of 240 timestamps of 1 hour each (10 days of data points)
1day granularity: Stores a maximum of 30 timestamps of 1 day each (30 days of data points)

大部分代码是相同的,关键是利用hash进行了分区,相当于建立多个bucket。
通过redis-cli monitor可以看到实际执行的命令:

[redis@tt12c ~]$ redis-cli monitorOK1462418086.839729 [0 127.0.0.1:63620] "info"1462418086.843865 [0 127.0.0.1:63620] "flushall"1462418086.894362 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1sec:0" "0" "1"1462418086.894425 [0 127.0.0.1:63620] "expire" "purchases:item1:1sec:0" "7200"1462418086.894437 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1min:0" "0" "1"1462418086.894446 [0 127.0.0.1:63620] "expire" "purchases:item1:1min:0" "604800"1462418086.894455 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1hour:0" "0" "1"1462418086.894464 [0 127.0.0.1:63620] "expire" "purchases:item1:1hour:0" "5184000"1462418086.894473 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1day:0" "0" "1"1462418086.894483 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1sec:0" "1" "1"1462418086.894492 [0 127.0.0.1:63620] "expire" "purchases:item1:1sec:0" "7200"1462418086.894500 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1min:0" "0" "1"1462418086.894511 [0 127.0.0.1:63620] "expire" "purchases:item1:1min:0" "604800"1462418086.894520 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1hour:0" "0" "1"1462418086.894529 [0 127.0.0.1:63620] "expire" "purchases:item1:1hour:0" "5184000"1462418086.894537 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1day:0" "0" "1"1462418086.894546 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1sec:0" "1" "1"1462418086.894556 [0 127.0.0.1:63620] "expire" "purchases:item1:1sec:0" "7200"1462418086.894564 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1min:0" "0" "1"1462418086.894573 [0 127.0.0.1:63620] "expire" "purchases:item1:1min:0" "604800"1462418086.894581 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1hour:0" "0" "1"1462418086.894590 [0 127.0.0.1:63620] "expire" "purchases:item1:1hour:0" "5184000"1462418086.894598 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1day:0" "0" "1"1462418086.894606 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1sec:0" "3" "1"1462418086.894615 [0 127.0.0.1:63620] "expire" "purchases:item1:1sec:0" "7200"1462418086.894623 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1min:0" "0" "1"1462418086.894631 [0 127.0.0.1:63620] "expire" "purchases:item1:1min:0" "604800"1462418086.894639 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1hour:0" "0" "1"1462418086.894648 [0 127.0.0.1:63620] "expire" "purchases:item1:1hour:0" "5184000"1462418086.894656 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1day:0" "0" "1"1462418086.894665 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1sec:0" "61" "1"1462418086.894673 [0 127.0.0.1:63620] "expire" "purchases:item1:1sec:0" "7200"1462418086.894681 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1min:0" "60" "1"1462418086.894690 [0 127.0.0.1:63620] "expire" "purchases:item1:1min:0" "604800"1462418086.894699 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1hour:0" "0" "1"1462418086.894709 [0 127.0.0.1:63620] "expire" "purchases:item1:1hour:0" "5184000"1462418086.894718 [0 127.0.0.1:63620] "hincrby" "purchases:item1:1day:0" "0" "1"1462418086.894726 [0 127.0.0.1:63620] "multi"1462418086.894759 [0 127.0.0.1:63620] "hget" "purchases:item1:1sec:0" "0"1462418086.894768 [0 127.0.0.1:63620] "hget" "purchases:item1:1sec:0" "1"1462418086.894774 [0 127.0.0.1:63620] "hget" "purchases:item1:1sec:0" "2"1462418086.894780 [0 127.0.0.1:63620] "hget" "purchases:item1:1sec:0" "3"1462418086.894786 [0 127.0.0.1:63620] "hget" "purchases:item1:1sec:0" "4"1462418086.894793 [0 127.0.0.1:63620] "exec"1462418086.894795 [0 127.0.0.1:63620] "multi"1462418086.894800 [0 127.0.0.1:63620] "hget" "purchases:item1:1min:0" "0"1462418086.894806 [0 127.0.0.1:63620] "hget" "purchases:item1:1min:0" "60"1462418086.894812 [0 127.0.0.1:63620] "hget" "purchases:item1:1min:0" "120"1462418086.894826 [0 127.0.0.1:63620] "exec"

可以看到,本例所有的秒级都存入了key: purchases:item1:1sec:0中,可以存300个时间点,然后具体的秒在field中表示。

Adding uniqueness with Sorted Sets and HyperLogLog

本节使用Sorted Sets 和 HyperLogLog实现统计唯一(distinct)访问, 利用了这两个数据类型没有重复值的特性。Sorted Set 100%准确,而HyperLogLog使用较少内存,但准确率只有99.19%。具体使用哪个就看你的需要了。

这两个例子和前两个例子的区别是,前面的是计访问总数,而这两个只计唯一的访问(同一用户的重复访问不会计入)

要让Sorted Sets(zset)有效率的使用内存,需要一个zset中的field数量小于128,类似于前面Hash的例子,这里也做了key grouping,相当于做了分区。

通过redis-cli monitor可以看到实际执行的命令:

[redis@tt12c chapter 3]$ node using-timeseries-unique.js sorted-set[redis@tt12c ~]$ redis-cli monitorOK1462419249.646618 [0 127.0.0.1:63625] "info"1462419249.650224 [0 127.0.0.1:63625] "flushall"1462419249.689717 [0 127.0.0.1:63625] "zadd" "concurrentplays:1sec:0" "0" "0:user:max"1462419249.690007 [0 127.0.0.1:63625] "expire" "concurrentplays:1sec:0" "7200"1462419249.690033 [0 127.0.0.1:63625] "zadd" "concurrentplays:1min:0" "0" "0:user:max"1462419249.690053 [0 127.0.0.1:63625] "expire" "concurrentplays:1min:0" "604800"1462419249.690067 [0 127.0.0.1:63625] "zadd" "concurrentplays:1hour:0" "0" "0:user:max"1462419249.690083 [0 127.0.0.1:63625] "expire" "concurrentplays:1hour:0" "5184000"1462419249.690098 [0 127.0.0.1:63625] "zadd" "concurrentplays:1day:0" "0" "0:user:max"1462419249.690114 [0 127.0.0.1:63625] "zadd" "concurrentplays:1sec:0" "0" "0:user:max"1462419249.690130 [0 127.0.0.1:63625] "expire" "concurrentplays:1sec:0" "7200"1462419249.690144 [0 127.0.0.1:63625] "zadd" "concurrentplays:1min:0" "0" "0:user:max"1462419249.690159 [0 127.0.0.1:63625] "expire" "concurrentplays:1min:0" "604800"1462419249.690173 [0 127.0.0.1:63625] "zadd" "concurrentplays:1hour:0" "0" "0:user:max"1462419249.690187 [0 127.0.0.1:63625] "expire" "concurrentplays:1hour:0" "5184000"1462419249.690201 [0 127.0.0.1:63625] "zadd" "concurrentplays:1day:0" "0" "0:user:max"1462419249.690215 [0 127.0.0.1:63625] "zadd" "concurrentplays:1sec:0" "1" "1:user:hugo"1462419249.690235 [0 127.0.0.1:63625] "expire" "concurrentplays:1sec:0" "7200"1462419249.690248 [0 127.0.0.1:63625] "zadd" "concurrentplays:1min:0" "0" "0:user:hugo"1462419249.690265 [0 127.0.0.1:63625] "expire" "concurrentplays:1min:0" "604800"1462419249.690279 [0 127.0.0.1:63625] "zadd" "concurrentplays:1hour:0" "0" "0:user:hugo"1462419249.690296 [0 127.0.0.1:63625] "expire" "concurrentplays:1hour:0" "5184000"1462419249.690309 [0 127.0.0.1:63625] "zadd" "concurrentplays:1day:0" "0" "0:user:hugo"1462419249.690325 [0 127.0.0.1:63625] "zadd" "concurrentplays:1sec:0" "1" "1:user:renata"1462419249.690342 [0 127.0.0.1:63625] "expire" "concurrentplays:1sec:0" "7200"1462419249.690382 [0 127.0.0.1:63625] "zadd" "concurrentplays:1min:0" "0" "0:user:renata"1462419249.690401 [0 127.0.0.1:63625] "expire" "concurrentplays:1min:0" "604800"1462419249.690415 [0 127.0.0.1:63625] "zadd" "concurrentplays:1hour:0" "0" "0:user:renata"1462419249.690431 [0 127.0.0.1:63625] "expire" "concurrentplays:1hour:0" "5184000"1462419249.690445 [0 127.0.0.1:63625] "zadd" "concurrentplays:1day:0" "0" "0:user:renata"1462419249.690461 [0 127.0.0.1:63625] "zadd" "concurrentplays:1sec:0" "3" "3:user:hugo"1462419249.690477 [0 127.0.0.1:63625] "expire" "concurrentplays:1sec:0" "7200"1462419249.690490 [0 127.0.0.1:63625] "zadd" "concurrentplays:1min:0" "0" "0:user:hugo"1462419249.690504 [0 127.0.0.1:63625] "expire" "concurrentplays:1min:0" "604800"1462419249.690518 [0 127.0.0.1:63625] "zadd" "concurrentplays:1hour:0" "0" "0:user:hugo"1462419249.690532 [0 127.0.0.1:63625] "expire" "concurrentplays:1hour:0" "5184000"1462419249.690545 [0 127.0.0.1:63625] "zadd" "concurrentplays:1day:0" "0" "0:user:hugo"1462419249.690559 [0 127.0.0.1:63625] "zadd" "concurrentplays:1sec:0" "61" "61:user:kc"1462419249.690576 [0 127.0.0.1:63625] "expire" "concurrentplays:1sec:0" "7200"1462419249.690589 [0 127.0.0.1:63625] "zadd" "concurrentplays:1min:0" "60" "60:user:kc"1462419249.690605 [0 127.0.0.1:63625] "expire" "concurrentplays:1min:0" "604800"1462419249.690618 [0 127.0.0.1:63625] "zadd" "concurrentplays:1hour:0" "0" "0:user:kc"1462419249.690634 [0 127.0.0.1:63625] "expire" "concurrentplays:1hour:0" "5184000"1462419249.690648 [0 127.0.0.1:63625] "zadd" "concurrentplays:1day:0" "0" "0:user:kc"1462419249.690669 [0 127.0.0.1:63625] "multi"1462419249.690695 [0 127.0.0.1:63625] "zcount" "concurrentplays:1sec:0" "0" "0"1462419249.690842 [0 127.0.0.1:63625] "zcount" "concurrentplays:1sec:0" "1" "1"1462419249.690860 [0 127.0.0.1:63625] "zcount" "concurrentplays:1sec:0" "2" "2"1462419249.690872 [0 127.0.0.1:63625] "zcount" "concurrentplays:1sec:0" "3" "3"1462419249.690883 [0 127.0.0.1:63625] "zcount" "concurrentplays:1sec:0" "4" "4"1462419249.690897 [0 127.0.0.1:63625] "exec"1462419249.690902 [0 127.0.0.1:63625] "multi"1462419249.690911 [0 127.0.0.1:63625] "zcount" "concurrentplays:1min:0" "0" "0"1462419249.690923 [0 127.0.0.1:63625] "zcount" "concurrentplays:1min:0" "60" "60"1462419249.690936 [0 127.0.0.1:63625] "zcount" "concurrentplays:1min:0" "120" "120"1462419249.690949 [0 127.0.0.1:63625] "exec"

可以看到,key的设计和前面的例子是一样的,score中存的是时间,而不是累计的访问次数,field中存的用户名,但不明白为何要加一个时间前缀。
几个命令解释一下,zcount用来计数,multi和exec用于交易

127.0.0.1:6379> help zcount  ZCOUNT key min max  summary: Count the members in a sorted set with scores within the given values  since: 2.0.0  group: sorted_set127.0.0.1:6379> help multi  MULTI -  summary: Mark the start of a transaction block  since: 1.2.0  group: transactions127.0.0.1:6379> help exec  EXEC -  summary: Execute all commands issued after MULTI  since: 1.2.0  group: transactions

HyperLogLog 的实现无需key grouping, 类似于String, 实现非常简洁!每一个timestamp一个key。并用PFADD代替了INCRBY, 以及PFCOUNT 替代了 MGET.

通过redis-cli monitor可以看到实际执行的命令:

[redis@tt12c chapter 3]$ node using-timeseries-unique.js hyperloglog[redis@tt12c ~]$ redis-cli monitorOK1462421278.494144 [0 127.0.0.1:63631] "info"1462421278.498276 [0 127.0.0.1:63631] "flushall"1462421278.556209 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1sec:0" "user:max"1462421278.556277 [0 127.0.0.1:63631] "expire" "concurrentplays:1sec:0" "7200"1462421278.556300 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1min:0" "user:max"1462421278.556315 [0 127.0.0.1:63631] "expire" "concurrentplays:1min:0" "604800"1462421278.556330 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1hour:0" "user:max"1462421278.556344 [0 127.0.0.1:63631] "expire" "concurrentplays:1hour:0" "5184000"1462421278.556358 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1day:0" "user:max"1462421278.556371 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1sec:0" "user:max"1462421278.556386 [0 127.0.0.1:63631] "expire" "concurrentplays:1sec:0" "7200"1462421278.556399 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1min:0" "user:max"1462421278.556412 [0 127.0.0.1:63631] "expire" "concurrentplays:1min:0" "604800"1462421278.556427 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1hour:0" "user:max"1462421278.556440 [0 127.0.0.1:63631] "expire" "concurrentplays:1hour:0" "5184000"1462421278.556454 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1day:0" "user:max"1462421278.556466 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1sec:1" "user:hugo"1462421278.556481 [0 127.0.0.1:63631] "expire" "concurrentplays:1sec:1" "7200"1462421278.556495 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1min:0" "user:hugo"1462421278.556509 [0 127.0.0.1:63631] "expire" "concurrentplays:1min:0" "604800"1462421278.556523 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1hour:0" "user:hugo"1462421278.556537 [0 127.0.0.1:63631] "expire" "concurrentplays:1hour:0" "5184000"1462421278.556550 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1day:0" "user:hugo"1462421278.556563 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1sec:1" "user:renata"1462421278.556578 [0 127.0.0.1:63631] "expire" "concurrentplays:1sec:1" "7200"1462421278.556590 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1min:0" "user:renata"1462421278.556604 [0 127.0.0.1:63631] "expire" "concurrentplays:1min:0" "604800"1462421278.556617 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1hour:0" "user:renata"1462421278.557908 [0 127.0.0.1:63631] "expire" "concurrentplays:1hour:0" "5184000"1462421278.557944 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1day:0" "user:renata"1462421278.557960 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1sec:3" "user:hugo"1462421278.557988 [0 127.0.0.1:63631] "expire" "concurrentplays:1sec:3" "7200"1462421278.558004 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1min:0" "user:hugo"1462421278.558018 [0 127.0.0.1:63631] "expire" "concurrentplays:1min:0" "604800"1462421278.558033 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1hour:0" "user:hugo"1462421278.558047 [0 127.0.0.1:63631] "expire" "concurrentplays:1hour:0" "5184000"1462421278.558060 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1day:0" "user:hugo"1462421278.558073 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1sec:61" "user:kc"1462421278.558087 [0 127.0.0.1:63631] "expire" "concurrentplays:1sec:61" "7200"1462421278.558100 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1min:60" "user:kc"1462421278.558114 [0 127.0.0.1:63631] "expire" "concurrentplays:1min:60" "604800"1462421278.558127 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1hour:0" "user:kc"1462421278.558141 [0 127.0.0.1:63631] "expire" "concurrentplays:1hour:0" "5184000"1462421278.558155 [0 127.0.0.1:63631] "pfadd" "concurrentplays:1day:0" "user:kc"1462421278.558186 [0 127.0.0.1:63631] "multi"1462421278.558205 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1sec:0"1462421278.558316 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1sec:1"1462421278.558331 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1sec:2"1462421278.558341 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1sec:3"1462421278.558351 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1sec:4"1462421278.558362 [0 127.0.0.1:63631] "exec"1462421278.558367 [0 127.0.0.1:63631] "multi"1462421278.558376 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1min:0"1462421278.558387 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1min:60"1462421278.558397 [0 127.0.0.1:63631] "pfcount" "concurrentplays:1min:120"1462421278.558407 [0 127.0.0.1:63631] "exec"

Summary

本章用String, Hash, Sorted Set, HyperLoglog实现了时间序列的场景,更多的设计到数据结构。
如果不想看代码,可以直接用redis-cli monitor来监控实际的命令。

0 0
原创粉丝点击