首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Memcached / Dalli无法从其他服务器获取数据

Memcached / Dalli无法从其他服务器获取数据
EN

Stack Overflow用户
提问于 2015-05-27 05:25:06
回答 1查看 574关注 0票数 2

我们使用memcached作为应用程序的会话存储,我们有两个生产服务器,memcached客户端是dalli (https://github.com/mperham/dalli)。配置如下:

代码语言:javascript
复制
# Server A
config.cache_store = :dalli_store, '127.0.0.1', SERVER_B_IP, {namespace: 'Myapp', expires_in: 1.day, compress: true, failover: false}
# Server B
config.cache_store = :dalli_store, SERVER_A_IP, '127.0.0.1', {namespace: 'Myapp', expires_in: 1.day, compress: true, failover: false}

我们面临的问题是,我们的一台服务器似乎没有查找另一台来获取数据。例如,如果我在服务器B上有some_key的数据,当我尝试在控制台中进行调试时:

代码语言:javascript
复制
options = {namespace: 'Myapp', expires_in: 1.day, compress: true, failover: false}
# Server A
dalli = Dalli::Client.new(['127.0.0.1', SERVER_B_IP], options)
dalli.get("some_key") # nil

# Server B
dalli = Dalli::Client.new([SERVER_A_IP, '127.0.0.1'], options)
dalli.get("some_key") # { "_csrf_token" => "..." }

我试过用failover: true,但仍然得到同样的结果。但是,如果密钥some_key停留在服务器A上,我可以从两个服务器获得相同的数据。

另外,我在上面的例子中,如果我只使用SERVER_B_IP (即dalli = Dalli::Client.new(SERVER_B_IP, options) )初始化dalli客户端,我可以得到数据。

稍微挖掘一下代码,我发现服务器A上的ring.continuum总是指向自己:

代码语言:javascript
复制
# Server B
ring = dalli.send :ring
hkey = ring.send :hash_for, 'some_key'                    # got same hkey
entryidx = ring.send :binary_search, ring.continuum, hkey # 300
ring.continuum[entryidx].server                           # server B
ring.continuum[302].server                                # server A

# Server A
ring = dalli.send :ring
hkey = ring.send :hash_for, 'some_key'                    # got same hkey
entryidx = ring.send :binary_search, ring.continuum, hkey # 302
ring.continuum[entryidx].server                           # server A
ring.continuum[300].server                                # server A

我是不是错过了memcached / dalli配置中的一些东西?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-27 09:31:56

我快速查看了Daili代码库。它使用一致的散列将密钥分发到服务器。

https://github.com/mperham/dalli/blob/master/lib%2Fdalli%2Fring.rb#L10

代码语言:javascript
复制
entry_count_for(server, servers.size, total_weight).times do |idx|
     hash = Digest::SHA1.hexdigest("#{server.name}:#{idx}")
     value = Integer("0x#{hash[0..7]}")
     continuum << Dalli::Ring::Entry.new(value, server)
end

代码语言:javascript
复制
def entry_count_for(server, total_servers, total_weight)
     ((total_servers * POINTS_PER_SERVER * server.weight) / Float(total_weight)).floor
end

每个服务器的密钥空间取决于服务器总数、权重和服务器名称。这样,不同的服务器或服务器名称的密钥空间就会有所不同。我认为这个解释符合你的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30473828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档