2009-07-11 90 views
2

我想弄清楚使用memcached存储选项来计算活动会话数的最直接和最安全的方法。使用基于数据库的会话存储,我只能计算表中的行数,但不能对memcached执行相同的操作。Rails - 活动会话列表

感谢, 维克拉姆

回答

0

我不认为你可以做到这一点与内存缓存。

必须承认我还没有使用MemCacheStore都,但你也许可以实现使用前和你的数据库cron作业和表格应用控制器过滤器的东西。

1

Memcache中明确不提供一种方式来遍历所使用的密钥。您可以基于特定密钥进行读取或写入,但您可以通过而不是获取所有密钥的列表或对其进行迭代。这是memcache的限制。

不幸的是,before_filter不会工作,因为会话可以在memcached中没有您的应用程序将到期被通知这件事。

为什么你想要得到这些信息?

+0

嗨,谢谢你的回答。我希望这些信息能够显示网站上的用户数量,无论是登录还是其他。 Vikram – 2009-07-11 22:22:00

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) 

值是其中将包含任何匹配的密钥的散列。简单地总结一下这些时间段内的键值。

问:

  • 请问这样的规模?当应用程序处于高负载状态时,会有很多命中递增/递减缓存中的计数器。密钥锁上会导致应用程序减速吗?我想过把递增/递减部分放到一个线程中,但是你知道,直到有一个已知问题时才会调整性能。

更新:

我们已经实现了这个模式,并投入生产。它一直在为我们工作得很好,而且还没有出现性能问题。