Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django如何处理多个memcached服务器?_Python_Django_Memcached_Sharding - Fatal编程技术网

Python django如何处理多个memcached服务器?

Python django如何处理多个memcached服务器?,python,django,memcached,sharding,Python,Django,Memcached,Sharding,在django文档中,它说: Memcached的一个优秀特性是它能够通过网络共享缓存 多台服务器。这意味着您可以在多个服务器上运行Memcached守护进程 程序将把这组机器视为一个单独的机器 缓存,无需在每台机器上复制缓存值。到 利用此功能,将所有服务器地址包括在 位置,以分号分隔或作为列表 这到底是怎么回事?我在这个网站上读到了一些答案,这些答案表明这是通过基于密钥散列的服务器分片来实现的 那很好,但我需要一个更具体、更详细的答案。将django与pylibmc或PythonMe

在django文档中,它说:

Memcached的一个优秀特性是它能够通过网络共享缓存 多台服务器。这意味着您可以在多个服务器上运行Memcached守护进程 程序将把这组机器视为一个单独的机器 缓存,无需在每台机器上复制缓存值。到 利用此功能,将所有服务器地址包括在 位置,以分号分隔或作为列表

这到底是怎么回事?我在这个网站上读到了一些答案,这些答案表明这是通过基于密钥散列的服务器分片来实现的

那很好,但我需要一个更具体、更详细的答案。将django与pylibmc或PythonMemcached一起使用时,该切分实际上是如何执行的?配置设置中的IP地址顺序是否重要?如果运行同一个django应用程序的两个不同web服务器具有两个不同的设置文件,并且memcached服务器的IP地址顺序不同,该怎么办?这是否会导致每台机器使用不同的分片策略,从而导致密钥重复和其他效率低下

如果某台机器在列表中出现两次怎么办?例如,如果我做这样的事情,其中127.0.0.1实际上是与172.19.26.240相同的机器,该怎么办

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '127.0.0.1:11211',
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ]
    }
}
如果其中一个memcached服务器的容量大于其他服务器,该怎么办?如果机器1有64MB的memcached,机器2有128MB的memcached,那么分片算法会考虑到这一点,并为机器2提供更大比例的密钥吗

我还读到,如果memcached服务器丢失,那么这些密钥也会丢失。当涉及到切分时,这是显而易见的。更重要的是,如果memcached服务器宕机,我将其IP地址保留在设置文件中,会发生什么?django/memcached会不会只是无法获取任何本应分片到该故障服务器的密钥,或者它会意识到该服务器出现故障并提出新的分片策略?如果有一种新的分片策略,它是否会智能地获取最初用于故障服务器的密钥,并将其分配给其余服务器,还是会像第一台服务器不存在一样提出一种全新的策略,并导致密钥被复制


我试着阅读python memcached的源代码,但完全弄不明白这一点。我计划尝试阅读libmemcached和pylibmc的代码,但我想如果有人已经知道,在这里提问会更容易

执行切分的是实际的memcached客户端。Django仅将配置从
settings.CACHES
传递给客户端

服务器的顺序并不重要*,但是(至少对于python memcached),您可以为每个服务器指定一个“权重”:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
                ('cache1.example.org:11211', 1),
                ('cache2.example.org:11211', 10),
            ],
}
我认为快速浏览一下
memcache.py
(来自python memcached),特别是
memcached.Client.\u get\u server
,应该可以回答您的其余问题:

def _get_server(self, key):
    if isinstance(key, tuple):
        serverhash, key = key
    else:
        serverhash = serverHashFunction(key)

    for i in range(Client._SERVER_RETRIES):
        server = self.buckets[serverhash % len(self.buckets)]
        if server.connect():
            #print "(using server %s)" % server,
            return server, key
        serverhash = serverHashFunction(str(serverhash) + str(i))
    return None, None
我希望其他memcached客户端也以类似的方式实现



澄清@Apreche:在一种情况下,服务器的顺序确实很重要。如果您有多个web服务器,并且希望它们都将相同的密钥放在相同的memcached服务器上,那么您需要使用相同的服务器列表以相同的顺序配置它们,并使用相同的权重

我测试了其中的一部分,并在django 1.1和python memcached 1.44中发现了一些有趣的东西

在django上使用2个memcache服务器

cache.set('a',11000)

cache.get('a')#返回1

我使用另外两个django设置查找了哪个memcache服务器“a”被切分到另一个memcache服务器上。我通过在原始django实例和存储“a”的memcache服务器之间设置防火墙来模拟连接中断

cache.get('a')#暂停几秒钟,然后返回无

cache.set('a',2,1000)

cache.get('a')#立即返回2

如果服务器停机,memcache客户端库会更新其分片策略。

然后我拆除了防火墙

cache.get('a')#返回了2位,直到检测到服务器备份,然后返回1

当memcache服务器断开并返回时,您可以读取过时数据!Memcache没有做任何聪明的事情来阻止这种情况。

如果您使用的是一种缓存策略,这种策略会将内容长时间放在memcache中,并且依赖缓存失效来处理更新,那么这确实会把事情搞得一团糟。可以将该密钥的旧值写入“普通”缓存服务器,如果您在该窗口期间失去连接且无效,当服务器再次变得可访问时,您将读取不应读取的陈旧数据

还有一个注意事项:我一直在阅读一些对象/查询缓存库,我认为johnny cache应该不会受到这个问题的影响。它不会显式地使条目无效;相反,它会在表更改时更改缓存查询的键。所以它永远不会意外地读取旧值


编辑:我认为我关于johnny cache正常工作的说明是废话。表示“每个请求上都有额外的缓存读取以加载当前代”。如果代存储在缓存中,上述场景可能会导致读取过时的代。

在问题提出两年后考虑添加此答案,因为它在搜索中排名非常高,而且我们确实发现django只与一个memcached服务器对话

当一个站点运行在django 1.4.3上,python memcached 1.51与四个memcached实例对话时,我们发现查询数据库的频率远远高于预期。挖
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    },
    'rusty': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11222',
    }
}
from django.core.cache import cache, caches

cache.set("activity", 'great stuff', 15 ) # Default cache
caches["rusty"].set("activity", "A great time}", 32) # New rusty cache interface