[REDIS] sidekiq 두 개의 별도의 레디 스 인스턴스에 대한 작업?
REDISsidekiq 두 개의 별도의 레디 스 인스턴스에 대한 작업?
안녕하세요,
나는 두 개의 별도하지만, 관련 응용 프로그램을 가지고있다. 그들은 모두 자신의 배경 큐 (: 별도의 Sidekiq & 레디 스 프로세스를 읽기)이 있어야합니다. 그러나, 나는 가끔 APP1에서 APP2의 큐에 작업을 밀어 수 있도록하고 싶습니다.
간단한 큐 / 푸시 관점에서, 그것은 APP1 기존 Sidekiq / 레디 스 스택을 가지고 있지 않은 경우이 작업을 수행하기 쉬운 것입니다 :
# In a process, far far away
# Configure client
Sidekiq.configure_client do |config|
config.redis = { :url => 'redis://redis.example.com:7372/12', :namespace => 'mynamespace' }
end
# Push jobs without class definition
Sidekiq::Client.push('class' => 'Example::Workers::Trace', 'args' => ['hello!'])
# Push jobs overriding default's
Sidekiq::Client.push('queue' => 'example', 'retry' => 3, 'class' => 'Example::Workers::Trace', 'args' => ['hello!'])
그러나 이미 APP1에서 Sidekiq.configure_client 및 Sidekiq.configure_server라는 것이다 주어진, 아마 뭔가 요구 사항이 발생하는 경우 여기 사이의 단계가있다.
분명히 난 그냥 바로 Sidekiq 내부에서 직렬화 및 정규화 코드를 취할 수 있으며, 수동으로 APP2의 레디 스 큐에 밀어하지만 부서지기 쉬운 해결책처럼 보인다. 나는 Client.push 기능을 사용할 수 있도록하고 싶습니다.
나는 나의 이상적인 솔루션은 다음과 같을 것입니다 가정 :
SidekiqTWO.configure_client {원격 연결 .....} SidekiqTWO :: Client.push (작업 ....)
또는:
$는 = 원격 remote_connection을 레디 스 .....
Sidekiq :: Client.push (작업, $ redis_remote)
분명히 조금 우스운 만의 내 이상적인 사용 사례가.
감사!
해결법
-
==============================
1.그래서 한 가지의 FAQ에 따르면,는 "Sidekiq 메시지 형식은 매우 간단하고 안정적이다. : 그것은 JSON 형식으로 단지 해시이다"이다 내가 sidekiq에 JSON을 보낼 생각하지 않는다 mine-- 강조 할 너무 취성이다. 당신이 OP의 상황으로,에 작업을 전송하는 레디 스 예를 중심으로 세밀한 제어를 할 때 특히, 아마 그냥 날 작업이 큐에되는과 함께 레디 스 인스턴스를 표시 할 것입니다 조금 래퍼를 쓸 것입니다.
그래서 한 가지의 FAQ에 따르면,는 "Sidekiq 메시지 형식은 매우 간단하고 안정적이다. : 그것은 JSON 형식으로 단지 해시이다"이다 내가 sidekiq에 JSON을 보낼 생각하지 않는다 mine-- 강조 할 너무 취성이다. 당신이 OP의 상황으로,에 작업을 전송하는 레디 스 예를 중심으로 세밀한 제어를 할 때 특히, 아마 그냥 날 작업이 큐에되는과 함께 레디 스 인스턴스를 표시 할 것입니다 조금 래퍼를 쓸 것입니다.
레디 스 인스턴스에 라운드 로빈 작업에 케빈 베델의 일반적인 상황에, 난 당신이 컨트롤을하고 싶지 않아 다 치지는의 레디 스 인스턴스는 그냥 대기열 및 분포를 자동으로 관리 할 수있다 할 used--입니다. 한 사람 만이 지금까지를 요청하고, 그들이 레디 스를 사용하는 솔루션 :: 분산 해낸 것 같습니다 :
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
또 다른 한가지는 고 가용성을 얻을 수 및 장애 복구하기 위해 당신의 탐구에서 고려해야 할 것은 안정성 기능을 포함하는 Sidekiq 프로를 얻는 것입니다 :는 "Sidekiq 프로 클라이언트가 과도 레디 스 중단을 견딜 수 그것은 오류에 로컬 작업을 대기열에 그 일자리를 제공하려고합니다. 일단 연결이 복원됩니다. " sidekiq 어쨌든 배경 프로세스이기 때문에, 약간의 지연은 레디 스 인스턴스는 응용 프로그램에 영향을 미치지 않습니다 다운 된 경우. 당신이 개 레디 스 인스턴스 중 하나가 다운 당신이 라운드 로빈을 사용하는 경우이 기능을 사용하지 않는, 당신은 여전히 일자리를 잃었습니다.
-
==============================
2.carols10cents 말한다으로는 아주 간단하지만 난 항상 기능을 캡슐화하고 다른 프로젝트 나 호텔 오늘부터 블로그에서 아이디어를 업데이트에서 재사용 할 수 좋아. 이것은 다음과 같은 솔루션은 호텔 오늘의 레일 4.1 및 봄 프리 로더를 생존하지 않습니다에 향상시킨다.
carols10cents 말한다으로는 아주 간단하지만 난 항상 기능을 캡슐화하고 다른 프로젝트 나 호텔 오늘부터 블로그에서 아이디어를 업데이트에서 재사용 할 수 좋아. 이것은 다음과 같은 솔루션은 호텔 오늘의 레일 4.1 및 봄 프리 로더를 생존하지 않습니다에 향상시킨다.
현재 내가 lib 디렉토리 / remote_sidekiq / 다음 파일을 추가로 할 수 있도록 :
remote_sidekiq.rb
class RemoteSidekiq class_attribute :redis_pool end
remote_sidekiq_worker.rb
require 'sidekiq' require 'sidekiq/client' module RemoteSidekiqWorker def client pool = RemoteSidekiq.redis_pool || Thread.current[:sidekiq_via_pool] || Sidekiq.redis_pool Sidekiq::Client.new(pool) end def push(worker_name, attrs = [], queue_name = "default") client.push('args' => attrs, 'class' => worker_name, 'queue' => queue_name) end end
당신은 세트 redis_pool하는 초기화를 만들어야합니다
설정 / 초기화 / remote_sidekiq.rb
url = ENV.fetch("REDISCLOUD_URL") namespace = 'primary' redis = Redis::Namespace.new(namespace, redis: Redis.new(url: url)) RemoteSidekiq.redis_pool = ConnectionPool.new(size: ENV['MAX_THREADS'] || 6) { redis }
알렉스겠습니까 EDITH :
대신 라인의 sidekiq 결코 버전에서 :
redis = Redis::Namespace.new(namespace, redis: Redis.new(url: url)) RemoteSidekiq.redis_pool = ConnectionPool.new(size: ENV['MAX_THREADS'] || 6) { redis }
사용 라인 :
redis_remote_options = { namespace: "yournamespace", url: ENV.fetch("REDISCLOUD_URL") } RemoteSidekiq.redis_pool = Sidekiq::RedisConnection.create(redis_remote_options)
당신이 원하는 어디든지 당신은 단순히는 RemoteSidekiqWorker 모듈을 포함 할 수 있습니다. 작업이 완료!
**** 더 많은 대규모 환경 ****
RemoteWorker 모델에 추가하면 추가 혜택을 추가합니다 :
다음의 예는 RemoteWorker
class RemoteTraceWorker include RemoteSidekiqWorker include ActiveModel::Model attr_accessor :message validates :message, presence: true def perform_async if valid? push(worker_name, worker_args) else raise ActiveModel::StrictValidationFailed, errors.full_messages end end private def worker_name :TraceWorker.to_s end def worker_args [message] end end
-
==============================
3.내가 메시지 큐의 판독 방법이 복잡 ActiveJob를 사용하고 있기 때문에 나는 몇 가지 문제로 이것으로 실행을 가로 질러왔다.
내가 메시지 큐의 판독 방법이 복잡 ActiveJob를 사용하고 있기 때문에 나는 몇 가지 문제로 이것으로 실행을 가로 질러왔다.
ARO의 대답에 구축, 당신은 여전히 redis_pool 설치가 필요합니다 :
remote_sidekiq.rb
class RemoteSidekiq class_attribute :redis_pool end
설정 / 초기화 / remote_sidekiq.rb
url = ENV.fetch("REDISCLOUD_URL") namespace = 'primary' redis = Redis::Namespace.new(namespace, redis: Redis.new(url: url)) RemoteSidekiq.redis_pool = ConnectionPool.new(size: ENV['MAX_THREADS'] || 6) { redis }
이제 대신 근로자의 우리가 요청을 대기하는 ActiveJob 어댑터를 만듭니다 :
lib 디렉토리 / active_job / queue_adapters / remote_sidekiq_adapter.rb
require 'sidekiq' module ActiveJob module QueueAdapters class RemoteSidekiqAdapter def enqueue(job) #Sidekiq::Client does not support symbols as keys job.provider_job_id = client.push \ "class" => ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) job.provider_job_id = client.push \ "class" => ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end def client @client ||= ::Sidekiq::Client.new(RemoteSidekiq.redis_pool) end end end end
지금은 이벤트를 큐에 어댑터를 사용할 수 있습니다 :
require 'active_job/queue_adapters/remote_sidekiq_adapter' class RemoteJob < ActiveJob::Base self.queue_adapter = :remote_sidekiq queue_as :default def perform(_event_name, _data) fail " This job should not run here; intended to hook into ActiveJob and run in another system " end end
지금은 정상적인 ActiveJob API를 사용하여 작업을 대기 할 수 있습니다. 무엇이든 응용 프로그램은 큐의 아웃 작업을 수행 할 수 일치 RemoteJob가 필요합니다 읽습니다.
from https://stackoverflow.com/questions/14741700/work-with-two-separate-redis-instances-with-sidekiq by cc-by-sa and MIT license
'REDIS' 카테고리의 다른 글
[REDIS] 레디 스 감시 고정 표시기 이미지 / Dockerfile (0) | 2020.01.13 |
---|---|
[REDIS] 셀러리 작업을 설정하는 문제는 파이썬에서 백엔드 (0) | 2020.01.13 |
[REDIS] 서비스 스택 레디 스 목록 업데이트 (0) | 2020.01.13 |
[REDIS] 어떻게 비동기 토네이도와 레디 스를 사용할 수 있습니까? (0) | 2020.01.13 |
[REDIS] 시작 설정 파일에 서버를 레디 스 (0) | 2020.01.13 |