如果我在SimpleCache应用程序中用错了什么

2024-04-29 15:39:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我们使用以下设置:NGINX+Gunicorn+Flask。我们只需要添加一点缓存,每个Flask worker不超过5Mb。SimpleCache似乎是最简单的解决方案——它在Python进程本身内部本地使用内存。在

不幸的是,文件中指出:

"Simple memory cache for single process environments. This class exists mainly for the development server and is not 100% thread safe."

但是,我没有看到线程安全在我们的设置中有什么重要的意义。我认为Gunicorn让几个烧瓶工人运转,每个工人都有自己的小储藏室。可能出什么问题?在


Tags: 文件内存flaskcachefor进程nginx解决方案
2条回答

我目前正在处理一个场景,在用户登录应用程序后,我想将他的IP、用户名插入数据库。在

现在,我只能做一次的方法是使用缓存将用户的ip和用户名存储在缓存中。在

现在,当每个gunicorn进程初始化自己的缓存时,问题就出现了。如果为proc1的缓存添加username+ip组合,如果proc2接收到同一用户的下一个请求,它将不会在其缓存中找到它,因此再次将其添加到缓存和数据库中,这是不合适的。因此,在这种情况下,线程安全(进程安全)缓存非常重要。在

日志示例:

2015-07-07 22:42:31 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:31 - myapp.views:30 - DEBUG - from cache : user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:40 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:40 - myapp.views:30 - DEBUG - from cache : user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:41 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14779]
2015-07-07 22:42:41 - myapp.views:30 - DEBUG - from cache : None, <type 'NoneType'> [14779]
2015-07-07 22:42:41 - myapp.views:32 - DEBUG - new username ip [14779]
2015-07-07 22:42:41 - myapp.views:38 - DEBUG - User : user1, ip : 100.100.100.100, noted at time : Tue Jul  7 22:42:41 2015, login_count : None [14779]

您可以看到gunicorn进程14776首先将其添加到缓存中,下一个请求被14776选中,因此数据库条目只发生了一次,但是在那之后,下一个请求被14779选中,14779将其添加到缓存中,从而将其添加到数据库中。在

^{pr2}$

使用memcache或基于redis的缓存可以解决这个问题。我自己也在试验。在

对于gunicorn的用例,不存在多线程问题,因为每个服务在其自己的进程中以单线程方式运行。但一个潜在的问题是数据的“脏”读。在

考虑以下情况:

  1. process1从数据库读取并填充自己的缓存cache1
  2. process2使用相同的查询从同一个表中读取,并填充自己的缓存cache2
  3. process2用新数据更新表并使旧缓存失效2
  4. process1再次执行相同的查询,从缓存1读取过期数据!。这是因为process1/cache1不知道数据库更新而发生问题的时候

相关问题 更多 >