Redis를 통해 메시지 대기열을 구현하는 방법은 무엇입니까?


29

왜 Redis를 큐잉해야합니까?

Redis가 큐잉 시스템을 구현하기에 좋은 후보가 될 수 있다는 인상을 받고 있습니다. 지금까지는 폴링 또는 RabbitMQ와 함께 MySQL 데이터베이스를 사용했습니다. RabbitMQ를 사용하면 많은 문제가 발생했습니다. 클라이언트 라이브러리는 매우 가난하고 버그가 많으며 서버 관리 콘솔에 몇 가지 문제 등을 해결하는 데 너무 많은 개발자 시간을 투자하고 싶지 않습니다. 시스템이 큐를 지능적으로 지원하는 아키텍처를 가지고있는 한 우리는 아마도 밀리 초나 성능을 크게 향상 시키지는 않을 것입니다.

자, 이것이 배경입니다. 본질적으로 나는 매우 고전적이고 간단한 대기열 모델을 가지고 있습니다. 여러 생산자가 작업을 생산하고 여러 소비자가 작업을 소비하며 생산자와 소비자 모두 지능적으로 확장 할 수 있어야합니다. 순진한 방식으로 PUBSUB작동하지 않는 것으로 나타났습니다. 모든 구독자가 작업을 소비 하지 않기 때문에 명의 구독자가 작업을 받기를 원합니다 . 처음 BRPOPLPUSH에는 지능적인 디자인 인 것 같습니다 .

BRPOPLPUSH를 사용할 수 있습니까?

기본 디자인 BRPOPLPUSH은 하나의 작업 대기열과 진행 대기열이 있다는 것입니다. 소비자가 작업을 수신하면 원자 적으로 항목을 진행 큐로 푸시하고 작업을 완료하면 완료 LREM됩니다. 이렇게하면 클라이언트가 죽으면 작업이 블랙홀 링되는 ​​것을 방지 할 수 있습니다. 예를 들어 소비자가 작업을 수행하는 데 시간이 오래 걸리는 문제와 대량의 작업이 있는지를 알려주는 문제가 있는지 알 수 있습니다.

그것은 보장합니다

  • 작업은 정확히 한 소비자에게 전달됩니다
  • 작업이 진행 대기열에 들어가므로 소비자에게는 블랙홀이되지 않습니다.

단점

  • 내가 찾은 최고의 디자인 PUBSUB이 실제로 사용하지 않는다는 것이 다소 이상하게 보입니다. 그래서 나는 명백한 것을 놓치고있는 것처럼 느낍니다. PUBSUB작업을 두 번 소비하지 않고 사용하는 유일한 방법 은 작업이 도착했다는 알림을 푸시하는 것입니다. 소비자는이를 막을 수 없습니다 RPOPLPUSH.
  • 한 번에 둘 이상의 작업 항목을 요청할 수 없으며 이는 성능 문제인 것 같습니다. 우리의 상황에는 큰 것이 아니지만 오히려이 작업은 높은 처리량이 나이 상황을 위해 설계된 것이 아니라고 분명히 말합니다
  • 한마디로 : 바보 같은 것이 빠졌습니까?

또한 내가 다루는 언어이기 때문에 node.js 태그도 추가합니다. Node는 단일 스레드 및 비 차단 특성을 고려하여 구현시 약간의 단순화를 제공 할 수 있지만, 노드 Redis 라이브러리를 사용하고 있으며 솔루션은 강점과 약점에도 민감하거나 민감 할 수 있습니다.

답변:


5

Node.js의 메시지 대기열에 Redis를 사용하고 모듈을 사용하는 것이 마음에 들지 않으면 RSMQ -Redis Simple Message Queue for Node를 사용해보십시오 . 이 질문을 할 당시에는 사용할 수 없었지만 오늘날에는 실행 가능한 옵션입니다.

질문에 언급 한대로 실제로 큐를 직접 구현 하려면 요청하는 것과 정확히 일치하는 코드가 20 화면이므로 RSMQ 소스를 읽으십시오.

만나다:


나중에 실제로 결함이 있거나 깨진 것을 배우지 않으면 이것을 받아 들일 것입니다.
djechlin

22

나는 지금까지 문서화하고 싶은 몇 가지 어려움에 부딪쳤다.

재 연결 논리를 어떻게 처리합니까?

이것은 메시지 큐를 설계하고 구현할 때 어려운 문제이며 특히 어려운 문제입니다. 소비자가 오프라인 일 때 메시지가 어딘가에 대기 할 수 있어야하므로 간단한 pub-sub가 충분히 강력하지 않으며 소비자는 수신 상태로 다시 연결해야합니다. 팝 차단은 비등 전성 청취 상태이므로 유지하기 어려운 상태 입니다. 청취는 dem 등원 (imdempotent) 조작이어야하지만, 차단 팝과 관련하여 단절을 처리 할 때, 단절 직후 또는 단절 직전에 단절이 발생했는지에 대해 매우 열심히 생각할 수 있습니다. 이것은 극복 할 수 없지만 바람직하지 않습니다.

또한 청취 작업은 가능한 한 간단 해야 합니다. 이상적으로는 다음과 같은 속성이 있어야합니다.

  • 듣는 것은 dem 등합니다.
  • 소비자는 항상 청취하고 있으며 조절 논리는 청취 논리 코드 외부에서 처리됩니다. RabbitMQ는 소비자가 보유 할 수있는 비킹 메시지 수를 제한하여이를 캡슐화합니다.
    특히 나는 블로킹 팝을 다시 입력하는 것이 이전 작업의 성공에 달려 있었고, 취하기 어려웠고 열심히 생각해야하는 열악한 디자인을 사용했습니다.

이제 Redis PUBSUB + RPOPLPUSH 솔루션을 선호합니다. 이것은 작업 소비와 작업 알림을 분리하여 깨끗한 청취 솔루션을 제외시킵니다. PUBSUB는 작업 알림 만 담당합니다. RPOPLPUSH의 원자 적 특성은 소비를 담당하고 정확히 하나의 소비자에게 작업을 위임합니다. 처음에는이 솔루션이 차단 팝에 비해 불필요하게 복잡해 보였지만 이제는 합병증이 전혀 필요하지 않다는 것을 알았습니다. 어려운 문제를 해결하고있었습니다.

그러나이 솔루션은 그리 간단하지 않습니다.

  • 소비자는 또한 재 연결 작업을 점검해야합니다.
  • 소비자는 어쨌든 중복성을 위해 새로운 작업에 대한 여론 조사를 원할 수 있습니다. 폴링이 실제로 성공하면 PUBSUB의 소비와 RPOPLPUSH의 폴링 사이에서만 발생하므로 경고가 발생해야합니다. 따라서 많은 폴링 성공은 구독 시스템이 손상되었음을 나타냅니다.

PUBSUB / RPOPLPUSH 디자인에도 스케일링 문제가 있습니다. 모든 소비자는 모든 메시지에 대해 간단한 알림을받습니다 . 이는 불필요한 병목 현상이 있음을 의미합니다. 채널을 사용하여 작업을 마무리하는 것이 가능하다고 생각하지만 이것은 잘 작동하기 까다로운 디자인 일 것입니다.


소비자 차단과 관련된 문제를 잘 모르겠습니다. 소비자가 처리 할 작업이 없다면 일부 소비자가있을 때까지 차단해야하지만 소비자가 다른 이야기 일 수도있는 다른 일을하고 있다고 생각하지만 응용 프로그램 내에서 더 큰 문제는 아닙니다. 그리고 대기열에 그렇게 많이하지? IE는 더 큰 응용 프로그램 내에서 스레드 차단이 더 우아한 솔루션이 아니므로 스레드가 응용 프로그램이 대기열에서 작업을 검색했을 때 응용 프로그램에 알릴 수 있습니다. 아마도 합병증을 일으키는 노드를 사용하는 것일 수도 있습니다.
AaronM

9
지난 8 월 이후 얼마나 멀리 왔는지 궁금합니다. 문제를 만족스럽게 해결할 수 있었습니까? 어떻게 해결 했습니까?
AaronM

3
AAA : @AaronM과 마찬가지로 진행 상황을 듣고 싶습니다.
bjornl

동의했다. 이것은 어떻게 진행 되었습니까? 나는 스택에서 RabbitMQ를 제거하고 어쨌든 Redis를 사용한다는 아이디어를 좋아합니다. 내 문제는 RSMQ (node ​​lib)를 사용하여 소비자를 등록하는 방법입니다.
ra9r

@raiglstorfer 2 년 동안이 일을하지 않은 : P는 ... 연구와 포스트 주시기
djechlin

0

따라서 Redis보다 RabbitMQ를 사용하는 가장 큰 이유는 장애 시나리오 및 클러스터링입니다.

이 기사는 실제로 가장 잘 설명하므로 링크를 제공합니다.

https://aphyr.com/posts/283-jepsen-redis

Redis 센티넬과 최근 Redis 클러스터링은 대기열에 대한 잘못된 선택이 된 여러 가지 기본적인 실패 시나리오를 처리 할 수 ​​없습니다.

RabbitMQ에는 자체 문제 세트가 있지만 프로덕션 환경에서는 믿을 수 없을 정도로 견고하며 좋은 메시지 대기열입니다.

토끼의 게시물은 다음과 같습니다.

https://aphyr.com/posts/315-jepsen-rabbitmq

CAP 정리 (일관성, 가용성 및 파티션 처리)를 볼 때 3 개 중 2 개만 선택할 수 있습니다. 메시지로드와 함께 CP (일관성 및 파티션 처리)에 대한 RMQ를 활용하고 있습니다. 세상의 끝. 메시지를 잃지 않기 위해 메시지를 잃지 않기 위해 파티션 처리에 대해 ignore를 사용합니다. 소스가 UUID를 관리하기 때문에 중복을 처리 할 수 ​​있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.