保持从 Websocket 更新 Rails 数据而不保存到数据库

Posted

技术标签:

【中文标题】保持从 Websocket 更新 Rails 数据而不保存到数据库【英文标题】:Keeping Rails data updated from Websocket without saving to database 【发布时间】:2017-10-27 00:56:42 【问题描述】:

我有 websocket 价格数据流到我的 rails api 应用程序,我想保持更新,这样任何 api 请求都会得到更新的响应。将每次更新都保存到数据库中的成本太高了。我怎样才能做到这一点?在 Ember 中,我可以修改模型并且它仍然存在。它似乎不会发生在 Rails 中。

频道控制器:

def receive(message)
  #ActionCable.server.broadcast('channel', message)

  platform = Platform.find(params[:id]);
  market = platform.markets.find_by market_name: message["market_name"]
  market.attributes = 
    market.price = message.values["price"],
    etc......
  
  #market.save [this is too expensive every time]
end

我是否以正确的方式处理这件事?每次我想更新时使用 find 似乎效率也很低,这可能是每秒多次。在 Ember 中,我创建了一个记录 Id 查找数组,以便我可以快速匹配市场名称,我不知道如何在 Rails 中执行此操作。

【问题讨论】:

【参考方案1】:

对某个存储的持久性是让其他线程响应最新值的唯一方法。

而不是 3 个查询(2 selects 和 1 update),您只需 1 update 就可以做到这一点

Market.where(platform_id: params[:id], market_name: message["market_name"]).
       update_all(price: message.values["price"])

使用适当的索引,每次更新的性能可能会低于毫秒。

取决于您的业务需求:

如果您每秒钟都在为某个市场获得大量更新(使之前的所有更新变得陈旧和无用),您可以选择忽略少数并且根本不触发更新。

【讨论】:

感谢简化查询语句。如果再添加几个平台,那么每秒可以轻松获得超过 1000 次更新。我希望能够将此数据与后台作业队列一起使用,以执行诸如提醒 Ember 前端达到的价格水平或更复杂的任务之类的事情。将更新保存到数据库是行不通的。也许我应该使用 Redis 并减少保存到数据库的频率。 1000 per second 远低于大多数数据库的处理能力。 如果你走 Redis 路径,可能你会想到根本不保存在 SQL DB 中。

以上是关于保持从 Websocket 更新 Rails 数据而不保存到数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Rails 和 Websocket 显示更新的数据?

从 rails runner 内部触发/订阅 websocket-rails 事件

Websocket-Rails 和 IE 8

Rails/Ajax 在提交后将表单从创建更改为更新

Rails:使范围数据从索引到显示页面保持不变

Rails 可以让 Ajax 保持开放多久