【问题标题】:Writing to Cache vs Writing to database - Performance benchmarks?写入缓存与写入数据库 - 性能基准?
【发布时间】:2014-05-06 16:27:03
【问题描述】:

我有一个 ruby​​ on rails 应用程序,每分钟大约需要 10000 个请求。 其中一些请求执行对数据库表的写入。与数据库的最大连接数为 200。

我想知道什么更有效。在一次操作中写入缓存中的数组并在后台保存数据,还是将每个请求直接保存到数据库? 如果我将数据写入缓存中的数组,是否存在任何竞争条件或性能问题? 有没有更好的方法来优化性能并避免数据库瓶颈?

示例代码

 #...
  def self.add_data_message_to_queue(event_id, chat_item)
    bucket_name = 'BUCKET_GET_CHAT_' + event_id.to_s
    chat_queue = Rails.cache.fetch(bucket_name)
    if chat_queue.blank?
      chat_queue = []
    end
    chat_queue.push(chat_item)
    Rails.cache.write(bucket_name, chat_queue, expires_in:Integer(30).days)
  end
  • 服务器:独角兽(高并发)

提前致谢

【问题讨论】:

    标签: ruby-on-rails postgresql memcached


    【解决方案1】:

    解决方案

    根据基准,写入内存缓存的效率更高。 尽管有必要处理竞争条件。根据 memcachier 团队的反馈。

    测试将聊天消息保存到数据库

    相同的测试 - 不将聊天消息保存到当前数据库

    响应时间要好得多。该应用每分钟也可以处理更多请求。

    处理竞争条件 *(memcachier 团队的反馈)

    一般来说,在 memcache 中有两种方法可以解决这个问题:

    由于您要追加到数组,因此您可以改用 memcache 的 APPEND 和 PREPEND 操作。 Rails.cache 不支持它们,但底层库 Dalli 支持这些命令。它们的语义是它们会将字符串附加/附加到现有值。当您获取该值时,您将获得“附加”的所有字符串连接在一起,因此您必须例如用分号或类似的东西分隔每个元素以将其分解为一个数组。

    更通用的解决方案(适用于任何数据竞争条件)是使用内存缓存中的版本控制支持。具体来说,memcache 中的每个值都分配有一个版本,该版本会在任何 get 请求上返回。 memcache 中的设置操作可以采用可选的 CAS(用于比较和交换)字段,这样只有当版本与存储的当前值匹配时,操作才会成功。同样,我相信 Rails.cache 不支持这一点,但 Dalli 通过 cas 方法支持:

    cache.add("bucket_get_chat", [])
    while(!cache.cas("bucket_get_chat") {|val| val.push(chat_item)}); end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-29
      相关资源
      最近更新 更多