业务目标
我正在创建一个仪表盘,该仪表盘将取决于某些时间序列,我将使用Redis来实现它。我是使用Redis的新手,并且正在尝试使用Redis-Streams计算流中的元素。
XADD conversation:9:chat_messages * id 2583 user_type Bot
XADD conversation:9:chat_messages * id 732016 user_type User
XADD conversation:9:chat_messages * id 732017 user_type Staff
XRANGE conversation:9:chat_messages - +
我知道我可以使用XLEN命令获得元素的总数:
XLEN conversation:9:chat_messages
但是我也想知道期间中的元素:
XLEN conversation:9:chat_messages 1579551316273 1579551321872
[我知道我可以使用LUA来计数那些元素,但是我想要一些真正快速的方法来实现这一点,并且我知道使用Redis标记将是最快的方法。
使用直接的Redis命令可以实现这一目标吗?还是我必须写一个Lua脚本来做到这一点?
其他信息
我受AWS的ElastiCache的限制,只能使用Redis 5.0.6,我无法安装其他模块,例如RedisTimeSeries模块。我想使用该模块,但目前无法使用。
抱歉,没有命令可以实现这一目标。
您对Redis Streams的最佳选择是使用Lua脚本。您将获得O(N),其中N是要计数的元素数,如果存在命令,则将获得O(log N)。
local T = redis.call('XRANGE', KEYS[1], ARGV[1], ARGV[2])
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
请注意,对于大的N,O(N)和O(log(N))之间的差异非常大,但对于聊天应用程序,如果通过对话进行跟踪,则如果聊天有数百个,则不会有太大的区别甚至数千个条目,一旦您考虑了总命令时间(包括往返时间),这将花费大部分时间。上面的Lua脚本消除了网络有效负载和客户端处理时间。
如果您确实需要O(log N),并且不需要使用方组和其他流功能,则可以切换到排序集。如果要自动使用Redis服务器时间戳,请参见How to store in Redis sorted set with server-side timestamp as score?。
然后您可以使用ZCOUNT,它是O(log(N))。
如果确实需要Stream功能,则需要将排序后的集合保留为辅助索引。
虽然Redis Stream数据结构不支持此结构,但是您可以在其旁边使用排序集来跟踪消息范围。
[基本上,对于您从XADD
获得的每个消息ID,例如“ 1579551316273-0”-您需要执行ZADD conversation:9:ids 0 1579551316273-0
。然后,您可以使用ZLEXCOUNT
获得范围的“长度”。