redis性能 - 最多删除100条记录?

时间:2014-06-03 12:35:40

标签: redis

我是Redis的新手,读过这本书< Redis in Action>和2.1节("登录和cookie缓存")有一个clean_sessions函数:

QUIT = False
LIMIT = 10000000

def clean_session:
  while not QUIT:
    size = conn.zcard('recent:')
    if size <= LIMIT:
      time.sleep(1)
      continue

    # find out the range in `recent:` ZSET
    end_index = min(size-LIMIT, 100)
    tokens = conn.zrange('recent:', 0, end_index-1)

    # delete corresponding data
    session_keys = []
    for token in tokens:
      session_keys.append('viewed:' + token)

    conn.delete(*session_keys)
    conn.hdel('login:', *tokens)
    conn.zrem('recent:', *tokens)

如果记录超过1000万,它会删除登录令牌和相应的数据,问题是:

  • 为什么每次最多删除100条记录?

  • 为什么不一次删除size - LIMIT条记录?

  • 有一些性能考虑因素吗?

谢谢,所有回复都表示赞赏:)

1 个答案:

答案 0 :(得分:3)

我想这个选择有多种原因。

Redis是一个单线程事件循环。这意味着大型命令(例如大型zrange或大型del,hdel或zrem)将比几个小命令处理得更快,但会影响其他会话的延迟。如果一个大命令需要一秒钟才能执行,那么访问Redis的所有客户端也将被阻止一秒钟。

因此,第一个原因是尽量减少这些清理操作对其他客户端进程的影响。通过在几个小命令中对活动进行分段,它也为其他客户端提供了执行命令的机会。

第二个原因是Redis服务器中通信缓冲区的大小。大命令(或大回复)可能会占用大量内存。如果要清理数百万个项目,则lrange命令的回复或del,hdel,zrem命令的输入可以表示数兆字节的数据。超过一定限度,Redis将关闭连接以保护自己。因此,最好避免处理非常大的命令或非常大的回复。

第三个原因是Python客户端的内存。如果必须清除数百万个项目,Python将不得不维护非常大的列表对象(标记和session_keys)。它们可能适合也可能不适合记忆。

建议的解决方案是增量的:无论要删除的项目数量多少,都将避免在客户端和Redis端消耗大量内存。它还将避免达到通信缓冲区限制(导致连接关闭),并将限制对访问Redis的其他进程的性能的影响。

请注意,100值是任意的。较小的值将允许以较低的会话清洁吞吐量为代价的更好的延迟。较大的值将以较高的延迟价格增加清理算法的吞吐量。

实际上,这是清洁算法的吞吐量和其他操作的延迟之间的经典权衡。