优化算法以减少时间复杂度(使用的redis数据类型)

时间:2016-12-20 12:55:16

标签: algorithm redis

背景

在我的网站中,用户正在创建自己的社交网络。这会导致通知飞到网络中的相关节点。例如。朋友请求,喜欢,评论,都为网络中的相关节点生成通知。

为了保持一切透明,用户可以在单独的网址中将其相关通知视为列表。此列表由名为ss:<user_id>的redis支持的有序集提供支持。有序集包含hash ids,以及自纪元以来的时间(作为score)。例如:

hash_id              |     updated_at
np:1:0:544           |     1482234321.48124
np:1:2:454           |     1482235629.73111
np:1:1:701           |     1482237000.59143

此外,每个通知都是看到看不见。此seen状态存储在密钥s的相关哈希中。例如。哈希s中的np:1:0:544键为False;告诉我们这是一个看不见的通知。很简单。

挑战:

挑战在于计算超出预定义纪元时间的所有看不见的通知。此时间存储在名为cut-off的单独计数器中。

我现在在做什么:

1)获取ss:<user_id>的所有hash_ids,得分高于cut-off。例如。 ZRANGEBYSCORE ss:<user_id> (cut-off +inf(用redis的说法)。

2)遍历每个hash_id,检查它的s密钥(即seen密钥)。如果sFalse,请递增计数器。例如。为每个哈希对象执行HGET hash_name s。如果返回值为False,则incr为单独的redis计数器。

步骤1的时间复杂度为O(log(N)+M)。第2步的结果是O(M)。它最多可以是O(N)

我需要改进的地方:

我能以更短的时间复杂度(例如O(log(N))做到这一点吗?例如。通过使用复合索引和词典排序?

表现至关重要;这个计算每天在我的网站上发生约200万次(并且扩大规模),所以我正在寻找提高可扩展性的方法。

注意:我当然可以采取其他措施来减轻这种算法的负担(例如降低其发生率,改善基础设施等),但这些是不同的考虑因素。

1 个答案:

答案 0 :(得分:0)

我改变了方法。

排序集的score(即updated_at)现在为time.time()+SEEN[status] SEEN={True:2000000000,False:4000000000}。这会自动按看到看不见对键进行排序,同时保留时间信息(由score-SEEN[status]获得)。

总的来说,这种方法使我能够从计算中删除第2步。时间复杂度降至O(log(N))。最重要的是,指数的智能制定可以真正推动绩效。对于任何有兴趣的人,here's an informative read关于复杂索引如何能够完成各种事情。