Rails:基于每个请求的命名空间redis,用于多功能应用程序

时间:2016-11-16 17:34:48

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

考虑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进行铁路缓存。

# 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

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

2 个答案:

答案 0 :(得分:1)

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

没有什么可以阻止用户A发出flushall并为每个"租户"擦除每一位数据。什么都没有。也没有任何东西阻止用户B发出选择命令来联系其他租户。数据。

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

Redis不适合多租户使用。试图将其合并成一个将导致问题。如果您确实需要多租户使用,请使用其他内容或为每个租户运行单个实例。

答案 1 :(得分:0)

您可以使用redis数据库功能。因此,在请求上创建redis连接后,选择$ id到redis,其中每个tennant的id都不同。

每个数据库都有自己的密钥空间,因此不会产生任何干扰。默认情况下允许16 dbs,但您可以在redis.conf中配置所需的数量。

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