【发布时间】:2009-07-11 06:43:01
【问题描述】:
我正在尝试找出使用 memcached 存储选项计算活动会话数的最直接和安全的方法。使用基于数据库的会话存储,我可以只计算表中的行数,但不能对 memcached 做同样的事情。
谢谢, 维克拉姆
【问题讨论】:
标签: ruby-on-rails count session memcached
我正在尝试找出使用 memcached 存储选项计算活动会话数的最直接和安全的方法。使用基于数据库的会话存储,我可以只计算表中的行数,但不能对 memcached 做同样的事情。
谢谢, 维克拉姆
【问题讨论】:
标签: ruby-on-rails count session memcached
Memcache 明确不提供迭代使用的键的方法。您可以根据特定键读取或写入,但您可以不获取所有键的列表或迭代它们。这是内存缓存的限制。
很遗憾,before_filter 不起作用,因为会话可能会在 memcached 中过期而您的应用不会收到通知。
您为什么要获取此信息?
【讨论】:
我认为你不能用 memcache 做到这一点。
必须承认我还没有使用 MemCacheStore,但您可能可以在应用程序控制器中使用 before 过滤器来实现一些东西,其中包含一个 cron 作业和一个数据库中的表。
【讨论】:
我知道这篇文章很老了,但我想我会在这里添加一个潜在的解决方案,看看社区有哪些类型的 cmets。
我们正在考虑将会话转移到 memcached,因为我们将它用于片段缓存(和其他事情)。这种方法在我的机器上有效,但还没有机会清理代码并在更健壮的环境中对其进行测试。
解决方案非常简单。它使用基于小时:分钟的密钥,并在会话延长时增加/减少密钥。会话放入的桶(key)被返回并存储在会话中。下次会话访问应用程序时,会将之前放入的存储桶提供给 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)
Values 是一个哈希,它将包含任何匹配的键。只需将键的值相加即可得到该时间段内的计数。
问题:
更新:
我们已经实现了这种模式并将其投入生产。它对我们来说运行得非常好,还没有出现任何性能问题。
【讨论】: