为啥 unicorn+mysql2 gem 不显示多工人产品设置的最新版本的模型数据?

Posted

技术标签:

【中文标题】为啥 unicorn+mysql2 gem 不显示多工人产品设置的最新版本的模型数据?【英文标题】:Why isn't unicorn+mysql2 gem showing latest version of model data on multi-worker prod setup?为什么 unicorn+mysql2 gem 不显示多工人产品设置的最新版本的模型数据? 【发布时间】:2012-12-06 17:42:00 【问题描述】:

我的模型似乎没有正确更新。

独角兽彩虹!在 EventMachine 上 mysql2 宝石

我可以在 production 环境中以 1000 rpm 的速度在 8 个工作人员上进行复制。如果我在 Rails 控制台中更新my_model(调用reload!),一切正常。在本地我无法重现它。

从控制器:

# params[:my_model] = :name => "new name" 
def update
  @my_model = MyModel.first # :name => "old name"
  Rails.logger.info @my_model.name
  @my_model.update_attributes(params[:my_model])
  redirect_to :action => :index
end

日志:

new name
old name
old name
old name
new name

我做错了什么?感谢您的提前!

【问题讨论】:

【参考方案1】:

模型中的数据是否被某些工作人员缓存,因此数据看起来是一个工作人员中的新名称,但旧名在另一个工人?

添加每个工作的 ID 并将其输出到您的日志中可能会有所帮助。换句话说,当您的工作人员启动时,它应该为自己分配一个与其他工作人员不同的 ID(工作人员的 PID 将是一个很好的候选者)。通过这种方式,您可以查看是否有一个或多个工人一直有问题,是否是所有工人,或者有时只是一些工人。如果这被证明是一个缓存问题,那么您可能只需要等待该对象的所有工作人员的 catch 无效,并且它最终会为所有工作人员显示正确的更新值。

如果不能在本地复现,是不是因为在本地开发时只使用了一个Web服务器实例(一个worker)?

另外,请检查您的 production 日志,看看在显示 旧名称 的实例中是否出现了 CACHE 一词。

【讨论】:

【参考方案2】:

看起来根本原因是当服务器处于高负载状态时,操作之间的 sql 缓存没有清除,因为工作进程没有执行操作。 我在没有负载的服务器上进行了测试-没有重现问题。 以下来自 ApplicationController 的代码解决了这个问题,但这个解决方案有点难看:

  before_filter do 
    MyModel.current.connection.clear_query_cache
  end

【讨论】:

以上是关于为啥 unicorn+mysql2 gem 不显示多工人产品设置的最新版本的模型数据?的主要内容,如果未能解决你的问题,请参考以下文章

为啥带有 Mysql2 Gem ActiveRecord::Base.connection.execute(sql) 的 Rails 3 返回 Array 而不是 Hash?

安装 mysql2 gem 错误

Ruby:mysql2-Gem 不工作(Mac OS X Snow Leopard,Ruby 1.9.2)

如何在 OS X 上使用 ruby​​ 2.3 解决 mysql2 gem 的“不兼容的库版本”?

LoadError:MySQL2 gem 问题,Ubuntu LTS 20.04 上的 libmysqlclient.so.20 版本不正确

在 80 端口启动 webrick(mysql2 gem 问题)