Memcached / Dalli 无法从其他服务器获取数据
Memcached / Dalli couldn't fetch data from other servers
我们使用 memcached 作为应用程序的会话存储,我们有 2 个生产服务器,memcached 客户端是 dalli (https://github.com/mperham/dalli)。配置如下:
# 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
的数据,当我尝试在控制台中进行调试时:
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 = Dalli::Client.new(SERVER_B_IP, options)
,我可以取回数据。
稍微挖掘一下代码,我发现服务器 A 上的 ring.continuum
总是指向它自己:
# 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 配置中的某些内容?
提前致谢。
我快速浏览了一下 Daili 代码库。它使用一致性哈希将密钥分发到服务器。
https://github.com/mperham/dalli/blob/master/lib%2Fdalli%2Fring.rb#L10
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
和
def entry_count_for(server, total_servers, total_weight)
((total_servers * POINTS_PER_SERVER * server.weight) / Float(total_weight)).floor
end
每个服务器的密钥空间取决于服务器总数、权重和服务器名称。这样密钥空间将随着总服务器或服务器名称的不同而不同。我认为这个解释符合你的问题。
我们使用 memcached 作为应用程序的会话存储,我们有 2 个生产服务器,memcached 客户端是 dalli (https://github.com/mperham/dalli)。配置如下:
# 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
的数据,当我尝试在控制台中进行调试时:
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 = Dalli::Client.new(SERVER_B_IP, options)
,我可以取回数据。
稍微挖掘一下代码,我发现服务器 A 上的 ring.continuum
总是指向它自己:
# 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 配置中的某些内容?
提前致谢。
我快速浏览了一下 Daili 代码库。它使用一致性哈希将密钥分发到服务器。
https://github.com/mperham/dalli/blob/master/lib%2Fdalli%2Fring.rb#L10
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
和
def entry_count_for(server, total_servers, total_weight)
((total_servers * POINTS_PER_SERVER * server.weight) / Float(total_weight)).floor
end
每个服务器的密钥空间取决于服务器总数、权重和服务器名称。这样密钥空间将随着总服务器或服务器名称的不同而不同。我认为这个解释符合你的问题。