【问题标题】:Rails: Namespace redis on a per-request basis for a multi-tenency appRails:基于每个请求的多租户应用程序的命名空间 redis
【发布时间】:2023-03-17 05:01:01
【问题描述】:

考虑一个multi-tenancy rails 应用程序。我将如何命名空间我的 redis 连接以每个请求为基础,这样每个租户都生活在自己的命名空间中?

多租户

对于多租户,我使用的是apartment gem。通过读出request.host,根据每个请求确定租户。

# config/initializers/apartment.rb
#
Rails.application.config.middleware.use 'Apartment::Elevators::Generic', lambda { |request|
  Tenant.find_identifier_by_host(request.host)
}

Redis

Redis 用于sidekiqredis-analytics,最重要的是,使用redis-rails 进行rails 缓存。

# config/initializers/cache.rb
# http://stackoverflow.com/a/38619281/2066546
#
Rails.application.config.cache_store = :redis_store, {
  host: ENV['REDIS_HOST'],
  port: '6379',
  expires_in: 1.week,
  namespace: "#{::STAGE}_cache",
  timeout: 15.0
}
Rails.cache = ActiveSupport::Cache.lookup_store(Rails.application.config.cache_store) 

# config/initializers/redis_analytics.rb
#
RedisAnalytics.configure do |configuration|
  configuration.redis_connection = Redis.new(host: ENV['REDIS_HOST'], port: '6379')
  configuration.redis_namespace = "#{::STAGE}_redis_analytics"
end

# config/initializers/sidekiq.rb
#
Sidekiq.configure_server do |config|
  config.redis = {host: ENV['REDIS_HOST'], port: '6379', namespace: "#{::STAGE}_sidekiq", timeout: 15.0 }
end
Sidekiq.configure_client do |config|
  config.redis = {host: ENV['REDIS_HOST'], port: '6379', namespace: "#{::STAGE}_sidekiq", timeout: 15.0 }
end

非常感谢您提出的任何建议!

【问题讨论】:

    标签: ruby-on-rails redis multi-tenant


    【解决方案1】:

    使用命名空间是隔离 Redis 以尝试多租户的一种糟糕方法。内幕消息:您只有一个实例密码。 Redis 中没有用户的概念。

    没有什么可以阻止用户 A 发出刷新并清除每个“租户”的每一位数据。什么都没有。也没有任何东西阻止用户 B 发出选择命令来获取其他租户的数据。

    Redis 是单线程的。它客户 C 发出一个睡眠命令,它为每个人阻止服务器。具有大量键的数据库上的键命令将导致整个服务器被阻塞,直到它完成。

    Redis 不是为多租户使用而设计的。试图将它硬塞进一个会导致问题。如果您确实需要多租户使用,请使用其他东西或为每个租户运行单独的实例。

    【讨论】:

    • 谢谢!您会推荐哪种替代品作为替代品?我已经在体验独角兽工人等待 redis 的效果了。或者,是否可以有多个(同步的)redis 实例和一个知道哪个实例s 属于哪个租户的负载均衡器?
    【解决方案2】:

    您可以为此使用 redis 数据库功能。因此,在根据请求创建 redis 连接后,将 select $id 发送到 redis,其中每个租户的 id 都不同。

    每个数据库都有自己的键空间,因此不会出现干扰。默认情况下允许 16 个 db,但您可以在 redis.conf 中配置任意数量。

    另见http://redis.io/commands/select

    【讨论】:

    • 从我粘贴到问题中的初始化程序中,我认为 redis 连接是在应用程序启动时建立的。它是否正确?我将如何设法在每个请求上创建一个新连接?考虑到性能,这是一个好主意吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-01-06
    • 2015-03-30
    • 2022-01-27
    • 2018-08-29
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 2020-08-01
    相关资源
    最近更新 更多