つまり、FAQによると、「Sidekiqメッセージの形式は非常にシンプルで安定している :JSON形式の単なるハッシュです。」強調私の-sidekiqにJSONを送信するのはあまりにも脆弱ではないと思います。特に、ジョブの送信先のRedisインスタンスをきめ細かく制御したい場合は、 OPの状況では、キューに入れられているジョブとともにRedisインスタンスを示すことができる小さなラッパーを作成するだけです。
ジョブをRedisインスタンスにラウンドロビンするKevinBedellのより一般的な状況については、しないと思います。 どのRedisインスタンスを使用するかを制御したい-エンキューして、ディストリビューションを自動的に管理したいだけです。これまでにリクエストしたのは1人だけのようで、Redis::Distributed
を使用するソリューションを考え出しました。 :
datastore_config = YAML.load(ERB.new(File.read(File.join(Rails.root, "config", "redis.yml"))).result)
datastore_config = datastore_config["defaults"].merge(datastore_config[::Rails.env])
if datastore_config[:host].is_a?(Array)
if datastore_config[:host].length == 1
datastore_config[:host] = datastore_config[:host].first
else
datastore_config = datastore_config[:host].map do |host|
host_has_port = host =~ /:\d+\z/
if host_has_port
"redis://#{host}/#{datastore_config[:db] || 0}"
else
"redis://#{host}:#{datastore_config[:port] || 6379}/#{datastore_config[:db] || 0}"
end
end
end
end
Sidekiq.configure_server do |config|
config.redis = ::ConnectionPool.new(:size => Sidekiq.options[:concurrency] + 2, :timeout => 2) do
redis = if datastore_config.is_a? Array
Redis::Distributed.new(datastore_config)
else
Redis.new(datastore_config)
end
Redis::Namespace.new('resque', :redis => redis)
end
end
高可用性とフェイルオーバーを実現するために考慮すべきもう1つのことは、信頼性機能を備えたSidekiq Proを入手することです。「SidekiqProクライアントは、一時的なRedisの停止に耐えることができます。エラーが発生すると、ローカルでジョブをキューに入れ、それらのジョブの配信を試みます。接続が復元されたら」とにかくsidekiqはバックグラウンドプロセス用であるため、Redisインスタンスがダウンした場合の短い遅延はアプリケーションに影響を与えません。 2つのRedisインスタンスの1つがダウンし、ラウンドロビンを使用している場合でも、この機能を使用していない限り、一部のジョブが失われています。