本周我遇到了这个非常有趣的问题,最好从一些事实开始:
pylibmc
是not thread safe,当用作django memcached后端时,直接在shell中启动多个django实例会在遇到并发请求时崩溃。python-memcached
,它也会解决这个问题,但这个问题与此无关。从第一个事实开始,这就是我重现pylibmc
问题的方法:
pylibmc
我有一个django应用程序,它执行了大量的memcached读写,并且有这个部署策略,我在shell中启动多个django进程,绑定到不同的端口(8001,8002),并使用nginx进行平衡
我使用locust
针对这两个django实例启动了两个单独的负载测试,这就是:
在上面的屏幕截图中,他们都崩溃并报告完全相同的问题,如下所示:
断言“ptr-> query_id == query_id +1”函数“memcached_get_by_key”失败,可能是“程序员错误,query_id没有递增。”,libmemcached / get.cc:107
所以在上面的例子中,我们了解到通过pylibmc
对memcached的多线程并发请求可能会导致问题,这在某种程度上不会打扰uWSGI
多个工作进程。
为证明这一点,我使用以下设置启动uWSGI
:
master = true
processes = 2
这告诉uWSGI启动两个工作进程,然后告诉nginx服务器任何django静态文件,并将非静态请求路由到uWSGI
,看看会发生什么。在服务器启动的情况下,我在localhost中针对django启动了相同的蝗虫测试,并确保每秒有足够的请求来引发对memcached的并发请求,结果如下:
在uWSGI
控制台中,没有死工作进程的迹象,并且没有工作人员重新生成,但是查看屏幕截图的上半部分,肯定有并发请求(5.6 req / s) )。
我非常好奇uWSGI
如何让它消失,我无法在他们的文档中了解到,回顾一下,问题是:
uWSGI如何管理工作进程,以便多线程memcached请求不会导致django崩溃?
事实上,我甚至不确定这是uWSGI
管理工作流程以避免这个问题的方式,还是uWSGI
附带的其他一些魔术,我已经看到了在他们的文档中称为memcached路由器,我不太明白,这有关系吗?
答案 0 :(得分:2)
不是因为你实际上有两个由uWSGI管理的独立进程吗?当您设置processes选项而不是workers选项时,您应该实际拥有多个uWSGI进程(由于您使用的配置,我假设一个master +两个worker)。每个进程都有自己加载的pylibmc,因此线程之间没有状态共享(毕竟你还没有在uWSGI上配置线程)。