【问题标题】:Should I use a Redis hash or a Ruby hash?我应该使用 Redis 哈希还是 Ruby 哈希?
【发布时间】:2016-10-04 13:41:15
【问题描述】:

我有 Rails 应用程序,我必须在其中维护将由多个线程同时访问的哈希值。

大部分访问都是读取,写入很少。我正在尝试在使用 Ruby 哈希和 Redis 哈希之间做出决定。

Redis 哈希是线程安全的,可以将数据存储到磁盘。但是,坚持并不是那么必要。

此外,对哈希的写入并不频繁,要写入的数据基本上是写入数据的时间本身。因此,即使它不是线程安全的,由于竞态条件导致的精度损失也是可以接受的,因为并发写入之间的时间最多可能只有几秒钟的变化。

我对使用单例 Ruby 哈希的唯一担忧是更新不是线程安全的,也不是原子的。那么,同步的非原子密钥更新会导致异常吗?

如果不是,那么在没有锁的情况下维护单例 Ruby 哈希是否有意义?

我对使用 Redis 哈希的担忧是内存中哈希的大小可能大于 Ruby 哈希以及调用 redis-server 的开销。并发性和持久性很好,但不是必需的。

请告诉我你的想法。谢谢。

【问题讨论】:

  • 在生产环境中运行应用程序后,您可能希望运行多个工作器,甚至在多个服务器上运行应用程序。也就是说:Redis 可能是更好的主意。
  • 我在 Puma 上运行该应用程序,它可以使用多个工作人员。那么,这是否意味着如果我在涉及多个工作人员时使用单例散列,不同的工作人员将有不同的应用程序实例,因此每个实例都有不同的散列?如果是这样,Redis 是否会成为制作全局可用哈希的唯一选择?
  • 这是正确的:Puma 工作人员在不同的进程中运行并且不共享内存。但是您也可以将 puma 配置为在共享内存的多个线程中运行。所以答案是:这取决于你的配置。 Redis 可以在所有配置中工作——即使有多个服务器......

标签: ruby-on-rails ruby multithreading hash redis


【解决方案1】:

(这是基于 Holger Just 的评论纠正我的更正。)

有一个专门为您的需要设计的库,名为concurrent-ruby

查看https://github.com/ruby-concurrency/concurrent-ruby

它有一个 Hash 类 (http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Hash.html) 和一个 Map 类 (http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Map.html),他们说这更快但不完全符合 Ruby Hash 的语义(例如,不保证按插入键的顺序排序) .

注意,安装gem后,使用它所需的require与gem名称不同;你require concurrent

require 'concurrent'
h = Concurrent::Hash.new

虽然我没有使用过,所以我无法提供任何关于它的个人反馈。

【讨论】:

  • thread_safe gem 被合并到包含许多附加原语的 concurrent-ruby gem 中。 thread_safe gem 因此被弃用,并被认为仅处于维护模式。对于新的开发,您可能应该使用 concurrent-ruby 来代替。由于 ActiveSupport 5 依赖于 concurrent-ruby,因此使用起来也应该相当安全。
猜你喜欢
  • 2012-07-02
  • 2014-06-05
  • 2011-08-01
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 2017-02-22
  • 2011-07-01
相关资源
最近更新 更多