Elasticsearch、Chewy、Postgres 和公寓多租户
Elasticsearch, Chewy, Postgres, and Apartment Multi-Tenancy
我有一个多租户 rails-api 项目 rails 4.2.3 和 ruby 2.2.2。我找到了很多资源来处理 rails 和 postgres 的多租户问题,但关于 elasticsearch 的资源并不多,更具体地说是耐嚼的 gem。我 posted an issue on the chewy gem github page,在那里我得到了一些很好的反馈,帮助我最终找到了解决问题的方法。我认为为了更大的利益,在这里也 post 它不会有什么坏处。这是我的问题的具体内容。
我最近从 MySQL 切换到具有多个模式的 Postgres,但在使用 rake chewy:reset:all
时遇到了问题。它看起来好像默认为 "public" 模式,但我想指定模式。我正在使用公寓 gem,所以我将其放入我的索引之一:
Apartment::Tenant.switch!('tenant_name')
这暂时解决了抽成问题,但它让我对 elasticsearch 和一般的耐嚼多租户有了更大的思考。 Chewy 有任何类型的实现吗?如果没有,您有什么建议吗?
我创建了一个耐嚼的猴子补丁初始化程序:
# config/initializers/chewy_multi_tenancy.rb
module Chewy
class Index
def self.index_name(suggest = nil)
prefix = Apartment::Tenant.current
if suggest
@index_name = build_index_name(suggest, prefix: prefix)
else
@index_name = build_index_name(
name.sub(/Index\Z/, '').demodulize.underscore,
prefix: prefix
) if name
end
end
@index_name or raise UndefinedIndex
end
end
end
还有一个自定义的 rake 任务:
# lib/tasks/elastic.rake
namespace :elastic do
desc "resets all indexes for a given tenant ('rake elastic:reset TENANT=tenant_name')"
task reset: :environment do
if ENV['TENANT'].nil?
puts "Uh oh! You didn't specify a tenant!\n"
puts "Example: rake elastic:reset TENANT=tenant_name"
exit
elsif !Apartment.tenant_names.include?(ENV['TENANT'])
puts "That tenant doesn't exist. Please choose from the following:\n"
puts Apartment.tenant_names
exit
else
Apartment::Tenant.switch!(ENV['TENANT'])
Rake::Task['chewy:reset:all'].invoke
end
end
end
由于我有一个完全独立的测试集群,我们不需要在索引前加上 "test" 前缀,所以我用当前租户名称重新定义了 prefix
。据我现在所知,每次调用特定索引时,Chewy 都会调用 index_name
方法。然后它为当前租户获取正确的用户索引。
感谢 Eli,让我走上了正确的方向。我已经用最新的耐嚼代码更新了 Eli 的代码。
# config/initializers/chewy_multi_tenancy.rb
module Chewy
class Index
def self.index_name(suggest = nil, prefix: nil, suffix: nil)
tenant_prefix = [Apartment::Tenant.current, prefix]
if suggest
@base_name = (tenant_prefix + [suggest.to_s.presence]).reject(&:blank?).join('_')
else
(tenant_prefix + [ base_name, suffix ]).reject(&:blank?).join('_')
end
end
end
end
和自定义 rake 任务:
# lib/tasks/elastic.rake
namespace :elastic do
desc "resets all indexes for a given tenant ('rake elastic:reset TENANT=tenant_name')"
task reset: :environment do
if ENV['TENANT'].nil?
puts "Uh oh! You didn't specify a tenant!\n"
puts "Example: rake elastic:reset TENANT=tenant_name"
exit
elsif !Apartment.tenant_names.include?(ENV['TENANT'])
puts "That tenant doesn't exist. Please choose from the following:\n"
puts Apartment.tenant_names
exit
else
Apartment::Tenant.switch!(ENV['TENANT'])
Rake::Task['chewy:reset'].invoke
end
end
end
我有一个多租户 rails-api 项目 rails 4.2.3 和 ruby 2.2.2。我找到了很多资源来处理 rails 和 postgres 的多租户问题,但关于 elasticsearch 的资源并不多,更具体地说是耐嚼的 gem。我 posted an issue on the chewy gem github page,在那里我得到了一些很好的反馈,帮助我最终找到了解决问题的方法。我认为为了更大的利益,在这里也 post 它不会有什么坏处。这是我的问题的具体内容。
我最近从 MySQL 切换到具有多个模式的 Postgres,但在使用 rake chewy:reset:all
时遇到了问题。它看起来好像默认为 "public" 模式,但我想指定模式。我正在使用公寓 gem,所以我将其放入我的索引之一:
Apartment::Tenant.switch!('tenant_name')
这暂时解决了抽成问题,但它让我对 elasticsearch 和一般的耐嚼多租户有了更大的思考。 Chewy 有任何类型的实现吗?如果没有,您有什么建议吗?
我创建了一个耐嚼的猴子补丁初始化程序:
# config/initializers/chewy_multi_tenancy.rb
module Chewy
class Index
def self.index_name(suggest = nil)
prefix = Apartment::Tenant.current
if suggest
@index_name = build_index_name(suggest, prefix: prefix)
else
@index_name = build_index_name(
name.sub(/Index\Z/, '').demodulize.underscore,
prefix: prefix
) if name
end
end
@index_name or raise UndefinedIndex
end
end
end
还有一个自定义的 rake 任务:
# lib/tasks/elastic.rake
namespace :elastic do
desc "resets all indexes for a given tenant ('rake elastic:reset TENANT=tenant_name')"
task reset: :environment do
if ENV['TENANT'].nil?
puts "Uh oh! You didn't specify a tenant!\n"
puts "Example: rake elastic:reset TENANT=tenant_name"
exit
elsif !Apartment.tenant_names.include?(ENV['TENANT'])
puts "That tenant doesn't exist. Please choose from the following:\n"
puts Apartment.tenant_names
exit
else
Apartment::Tenant.switch!(ENV['TENANT'])
Rake::Task['chewy:reset:all'].invoke
end
end
end
由于我有一个完全独立的测试集群,我们不需要在索引前加上 "test" 前缀,所以我用当前租户名称重新定义了 prefix
。据我现在所知,每次调用特定索引时,Chewy 都会调用 index_name
方法。然后它为当前租户获取正确的用户索引。
感谢 Eli,让我走上了正确的方向。我已经用最新的耐嚼代码更新了 Eli 的代码。
# config/initializers/chewy_multi_tenancy.rb
module Chewy
class Index
def self.index_name(suggest = nil, prefix: nil, suffix: nil)
tenant_prefix = [Apartment::Tenant.current, prefix]
if suggest
@base_name = (tenant_prefix + [suggest.to_s.presence]).reject(&:blank?).join('_')
else
(tenant_prefix + [ base_name, suffix ]).reject(&:blank?).join('_')
end
end
end
end
和自定义 rake 任务:
# lib/tasks/elastic.rake
namespace :elastic do
desc "resets all indexes for a given tenant ('rake elastic:reset TENANT=tenant_name')"
task reset: :environment do
if ENV['TENANT'].nil?
puts "Uh oh! You didn't specify a tenant!\n"
puts "Example: rake elastic:reset TENANT=tenant_name"
exit
elsif !Apartment.tenant_names.include?(ENV['TENANT'])
puts "That tenant doesn't exist. Please choose from the following:\n"
puts Apartment.tenant_names
exit
else
Apartment::Tenant.switch!(ENV['TENANT'])
Rake::Task['chewy:reset'].invoke
end
end
end