【问题标题】:Memory usage concerns on Rails ActiveSupport::CachingKeyGeneratorRails ActiveSupport::CachingKeyGenerator 的内存使用问题
【发布时间】:2019-05-21 08:13:13
【问题描述】:

为了在数据库中加密和存储用户信息,我的 Rails 应用程序使用salt(每个用户)使用ActiveSupport::KeyGenerator 生成key。但是,generate_key 方法执行的默认迭代是2**16 [1]。在每次读取(用于解密)和写入(用于加密)时使用用户的 salt 执行密钥生成会降低我的应用程序的速度。

我发现如果salt 和用于密钥生成的length 保持相同,则ActiveSupport::CachingKeyGenerator 可以用于缓存密钥[2]。在内部,它使用Concurrent::Map [3] 来缓存密钥。使用 ActiveSupport::CachingKeyGenerator 提高了我的应用程序的性能,因为它并不总是生成密钥。

这会将我的应用程序的内存使用量增加到可能导致应用程序崩溃的程度吗?

参考文献:

  1. https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activesupport/lib/active_support/key_generator.rb#L16

  2. https://api.rubyonrails.org/classes/ActiveSupport/CachingKeyGenerator.html

  3. https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activesupport/lib/active_support/key_generator.rb#L33

【问题讨论】:

  • 真的吗?你有多少用户?键并没有真正占用那么多空间..
  • 我们有大约一百万用户。
  • 视情况而定。我建议对近乎真实的数据量使用内存分析,而不是依赖论坛意见:) 或许,不缓存所有内容也很有意义 - 用户的活动配置文件可能非常不同,并且有(粗略地说) 20% 的用户对您的基础架构造成 80% 的压力。仅缓存它们的键将通过合理的内存权衡减少性能问题...

标签: ruby-on-rails ruby encryption


【解决方案1】:

分享一个“有效”的解决方案

由于ActiveSupport::CachingKeyGenerator 使用Concurrent::Map,我发现缓存密钥会导致内存使用量与用户数量成正比(假设所有请求都以某种方式路由到同一个节点)。

为了解决这个问题,我写了一个类似的CachingKeyGenerator 包装ActiveSupport::KeyGeneratorActiveSupport::Cache::MemoryStore

class CachingKeyGenerator
  BASE = Rails.application.secrets.secret_key_base
  LENGTH = ActiveSupport::MessageEncryptor.key_len
  KEY_EXPIRY = 1.day

  def initialize
    @key_generator = ActiveSupport::KeyGenerator.new(Rails.application.secrets.secret_key_base)
    @keys_cache = ActiveSupport::Cache::MemoryStore.new(expires_in: KEY_EXPIRY)
  end

  def generate_key(salt)
    key = @keys_cache.fetch(salt)
    if key.nil?
      key = @key_generator.generate_key(salt, LENGTH)
      @keys_cache.write(salt, key)
    end
    key
  end
end

根据 Rails 文档,ActiveSupport::Cache::MemoryStore 是线程安全的,并实现了基于 LRU 的清理机制 [1]。这应该使缓存的内存使用具有确定性 - 为内存存储设置的大小限制(默认 - 32Mb,可以在初始化期间定义)。

P.S:尚未将其部署到生产环境中,如果我遇到任何意外问题,将在此处更新。

[1]http://api.rubyonrails.org/classes/ActiveSupport/Cache/MemoryStore.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    相关资源
    最近更新 更多