BigData/웹대기

Redis를 사용하여 작업 대기열 구현

승하연서빠 2023. 4. 3. 10:49
728x90

메시지 큐란?

메시지 큐 사이 비동기 통신 프로토콜을 제공 송신자  수신자 가 같은 시간에 메시지 큐와 상호 작용 필요가 없습니다 메시지를. 큐에 배치 된 메시지는받는 사람이 검색 할 때까지 저장됩니다.

메시지 큐 패러다임은 pub-sub 패턴 의 형제입니다 . 그러나 pub-sub 패턴을 사용하면 게시자 라고하는 메시지 발신자 가 어떤 구독자가 존재하는지 알지 못해도 채널을 통해 구독자 라고하는 수신자 에게 메시지를 게시 할 수 있습니다. 모든 구독자는 수신 된 메시지가 동시에 메시지를 수신 할 수있는 시점에 존재합니다..

 

Redis는 pub-sub 패턴 을 명시 적으로 지원합니다 . 그러나이 기사에서는 Redis의 List 기본 제공 유형을 사용하여 Message Queueing을 구현하는 방법을 살펴 봅니다.

 

게시물 끝에서 Redis가 지원하는 Job Dispatcher (Nodejs) 및 Job Consumer (Golang)를 구현하는 방법을 살펴 보겠습니다.

Redis의 List 데이터 구조에 대해 알아보기

Redis에는 삽입 순서로 정렬 된 문자열 목록 인 내장 목록 데이터 유형이 있습니다. 목록 LPUSH의 맨 앞 ( RPUSH) 또는 꼬리 ( )에 요소를 밀어 넣을 수 있습니다 .

LPUSH mylist a   # now the list is "a"
LPUSH mylist b   # now the list is "b","a"
RPUSH mylist c   # now the list is "b","a","c" (RPUSH was used)

다음은 목록에 사용할 수있는 모든 요소입니다.

목록 명령 (확대하려면 클릭)

redis-cli 작업

이 게시물에서는 기본 메시지 대기열 기능 을 구현 하기 위해 PUSH  POP 작업을 사용하는 방법을 살펴 봅니다 . AWS의 다음 다이어그램에 표시된 것처럼 메시지 대기열은 Redis 용 Amazon ElastiCache 의 사용 사례 중 하나 입니다.

그러나이 게시물에서는 시리즈의 첫 번째 기사에서 수행 한 로컬 Redis 설치를 사용합니다.

를 사용하여 명령을 시도해 보겠습니다. redis-cli먼저 1 부에서 Redis VM 에 연결해야합니다 .

$ vermin ssh vm_01

위와 같이 오른쪽에있는 두 개의 스택 터미널에서 실행했습니다. BLPOP jobQueue 0즉, 이름이 지정된 목록의 선두에서 POP를 실행 jobQueue하고 요소가 추가 될 때까지 영원히 기다립니다 (따라서 시간 제한 값 0).

그리고 세 번째 터미널 (오른쪽 중 하나)에서 목록 끝에 2 개의 요소 ( "Hello"및 "world")를 푸시했습니다.

두 요소를 푸시하면 각 요소가 클라이언트 세션에 의해 팝되고 있음을 알 수 있습니다.

다음 섹션에서는 Node.js와 Golang을 사용하여 간단한 작업 대기열을 구현하고 Redis를 메시지 대기열로 사용할 것입니다.

간단한 작업 대기열 구현

먼저 환경을 설정하겠습니다. Nodejs 앱을 사용하여 작업을 작업 대기열 ( job-dispatcher ) 로 발송 하고 Golang 앱을 사용하여 작업을 소비하고 작업 ( job-consumer )합니다. 디스패처와 소비자로부터 몇 가지 애플리케이션을 배포 할 것입니다.

이제 Redis VM 내부에 로컬 파일 시스템 디렉터리를 마운트 할 수 있는 vermin의 한 기능을 사용해 보겠습니다 . 호스트 OS 콘솔에서 다음을 작성하십시오.

$ mkdir -p ~/temp/mq
$ vermin mount vm_01 ~/temp/mq

호스트 OS에 코드를 작성한 다음 VM 내에서 실행 해 보겠습니다.

IntellijIDEA를 사용하지만 원하는 편집기를 사용할 수 있습니다 (VSCode도 좋은 선택입니다).

내부에 두 개의 디렉토리를 만들 것입니다 ~/temp/mq.

$ mkdir -p ~/temp/mq/{job-dispatcher,job-consumer}

먼저 Golang ( go-redis 사용)에서 작업 소비자를 구현 하고 redis-cli클라이언트 에서 메시지를 전송하여 테스트합니다 .

다음은 소스 코드입니다.

// ~/temp/mq/job-consumer/main.go
package main

import (
   "fmt"
   "github.com/go-redis/redis/v7"
   "log"
   "time"
)

const key = "myJobQueue"

func main() {

   c := redis.NewClient(&redis.Options{
      Addr: "localhost:6379",
   })

   fmt.Println("Waiting for jobs on jobQueue: ", key)

   go func() {
      for {
         result, err := c.BLPop(0*time.Second, key).Result()

         if err != nil {
            log.Fatal(err)
         }

         fmt.Println("Executing job: ", result[1])
      }
   }()

   // block for ever, used for testing only
   select {}
}
$ GOOS=linux go build
vermin@verminbox:~$ /vermin/job-consumer/job-consumer
Waiting for jobs on jobQueue:  myJobQueue
vermin@verminbox:~$ redis-cli
127.0.0.1:6379> RPUSH myJobQueue "100"
(integer) 1
redis-cli를 사용하여 작업 소비자 앱에 작업 보내기

다음 단계는 Nodejs 에서 작업 디스패처를 만들고 높은 빈도로 여러 작업을 보내는 클라이언트를 시뮬레이션하는 것입니다.

작업 디스패처 구현

Nodejs 내에서 Node Redis 를 Redis 클라이언트로 사용할 것입니다 . 소스 코드는 다음과 같습니다.

// ~/temp/mq/job-dispatcher/index.js
const redis = require("redis");
const client = redis.createClient({
    address: "localhost:6379"
});

client.on("error", function (error) {
    console.error(error);
});

let myArgs = process.argv.slice(2);
let start = Number(myArgs[0])
let end = start + 10000

console.log(end)

for (let i = start; i < end; i++) {
    client.rpush("myJobQueue", i);
}

client.quit();
 

하지만 먼저 job-consumer6 개의 다른 터미널에서 6 개의 인스턴스를 실행 해 보겠습니다 . ( /vermin/job-consumer/job-consumer이전 섹션에 표시된 명령 사용 )

 

그리고 job-dispatcher다음과 같이 두 개의 터미널 에서 2 를 실행 해 보겠습니다 .

$ cd /vermin/job-dispatcher
$ node index.js 0
$ cd /vermin/job-dispatcher
$ node index.js 10000

Redis의 Lists를 Message Queue 로 사용하고이를 사용 하여 NodeJs에서 job-dispatcher 를 구현하고 Golang에서 job-consumer 를 구현하여 Job Queue 를 구축하는 방법 을 살펴 보았습니다.

RabbitMQ 또는 ActiveMQ와 같은 완전한 메시지 브로커를 가져 오는 대신 간단한 메시지 큐가 필요한 경우이 방법을 간단한 대안으로 사용할 수 있습니다.

 

Github에서 디스패처 및 소비자에 대한 소스 코드를 찾을 수 있습니다. https://github.com/mhewedy-playground/redis-mq

 

게시물에서 본 구현은 기본 작업 대기열이지만 처리중인 작업이 포함 된 처리 대기열을 포함하는 고급 작업 대기열을 찾는 경우 명령 RPOPLPUSH및 BRPOPLPUSH설명서를 확인하여 신뢰할 수있는 대기열 사용 사례를 확인할 수 있습니다 .

 

참조 : Korean (ichi.pro)

반응형