Rails - 活动会话列表

时间:2009-07-11 06:43:02

标签: ruby-on-rails count session memcached

我试图找出使用memcached存储选项计算活动会话数的最直接,最安全的方法。使用基于数据库的会话存储,我只能计算表中的行数,但不能用memcached做同样的事情。

谢谢, 维克拉姆

3 个答案:

答案 0 :(得分:1)

Memcache显式没有提供迭代使用中的键的方法。您可以根据特定密钥进行读取或写入,但您可以获取所有密钥的列表或迭代它们。这是memcache的限制。

不幸的是,before_filter无效,因为会话可以在memcached中过期而不会通知您的应用。

为什么要获取此信息?

答案 1 :(得分:0)

我认为你不能用memcache做到这一点。

必须承认我还没有使用MemCacheStore,但您可以使用应用程序控制器中的过滤器之前使用cron作业和数据库中的表来实现某些功能。

答案 2 :(得分:0)

我知道这篇文章真的很老了,但我想我会在这里添加一个潜在的解决方案,看看社区有什么样的评论。

我们正在考虑将会话移动到memcached,因为我们正在将它用于片段缓存(和其他东西)。这种方法在我的机器上工作,但没有机会清理代码并在更强大的环境中测试它。

解决方案非常简单。它使用基于小时:分钟的键,并在会话延长时递增/递减键。会话所放入的桶(密钥)将被返回并存储在会话中。下次会话到达应用程序时,它放入的前一个存储桶将提供给count方法。这样会话可以在密钥之间移动(从前一个桶移动到新桶)

以下是方法:

def count(previous_bucket)
    # All this does is construct a key like this:
    # _session_counter_10:15
    key = KEY_PREFIX + time_key(Time.now.hour, Time.now.min)

    # do nothing if previous bucket = key
    return key if previous_bucket.present? && key.eql?(previous_bucket)

    # Increment the count in the cache
    Rails.cache.increment(key, 1, expires_in: 30.minutes)

    # If there is a previous bucket, decrement the count there
    if previous_bucket.present?
        Rails.cache.decrement(previous_bucket, 1)
    end

    # Return the key used so it can be stored in the session which was counted.  This will be returned on the next
    # call to bump to keep the numbers accurate
    return key
end

要使用,调用方法是这样做的:

counter = SessionCounter.new
session[:counter_bucket] = counter.count(session[:counter_bucket])

要获得给定时间段内的会话计数,您可以简单地构造一段时间段的键,然后使用read_multi检索该时间内的计数。

例如:

keys = ["_session_count_10:15","_session_count_10:14","_session_count_10:13"]
values = Rails.cache.read_multi(*keys)

值是一个包含任何匹配键的哈希值。只需总结密钥的值即可获得该时间段内的计数。

<强>问题:

  • 这会有规模吗?当应用程序负载很重时,缓存中会有很多命中递增/递减计数器。密钥是否会锁定导致应用程序变慢?我想过将增量/减量部分放到一个线程中,但是你知道,在出现已知问题之前不要进行性能调整。

<强>更新

我们已经实施了这种模式并投入生产。它一直对我们很有效,并且还没有出现任何性能问题。