๐Ÿ’Œ

๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ Message queue๋ฅผ ์›ํ•œ๋‹ค๋ฉด - Redis Publisher, Subscriber

๊ฐœ์š”

Redis์˜ pub/sub์€ MSA์—์„œ ๋ชจ๋“ˆ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” Message Queue์˜ ์šฉ๋„๋กœ redis๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

์ฑ„ํŒ…, ๊ตฌ๋…, ํ‘ธ์‹œ ์•Œ๋ฆผ, ๊ฒฐ์ œ ์‹œ์Šคํ…œ ๋“ฑ์— ์‚ฌ์šฉ๋œ๋‹ค.

Message Queue๋ž€

MSA๊ฐ™์€ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ ๋ชจ๋“ˆ๊ฐ„ ๋ฉ”์‹œ์ง€๋ฅผ ๊ตํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ํ†ต์‹  ๋ฐฉ๋ฒ•์ด๋‹ค. ์‹œ์Šคํ…œ๊ฐ„ Coupling์„ ๋‚ฎ์ถ”๊ณ  ํ™•์žฅ์„ฑ์„ ๋†’์ธ๋‹ค.

์‹œ์Šคํ…œ๊ฐ„ Coupling์„ ๋‚ฎ์ถ”๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ์šด์˜๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” ๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฉ”์‹œ์ง€ ํ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ž„์‹œ ์ €์žฅํ•˜์—ฌ ์ˆ˜์‹ ์ž๊ฐ€ ์ฒ˜๋ฆฌํ•  ์ค€๋น„๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐœ์‹ ์ž์™€ ์ˆ˜์‹ ์ž์˜ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ์†๋„๋ฅผ ์กฐ์ ˆํ•˜์—ฌ ์‹œ์Šคํ…œ์˜ ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•˜๊ณ  ์•ˆ์ •์„ฑ์„ ๋†’์ด๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค.

Redis pub/sub์˜ ๊ตฌ์„ฑ์š”์†Œ

Publisher: ๋ฉ”์‹œ์ง€๋ฅผ ๊ตฌ๋…์ž์—๊ฒŒ ๋ฐœํ–‰ํ•œ๋‹ค. pub ๋ฉ”์‹œ์ง€๋Š” ์ €์žฅ๋˜์ง€ ์•Š๊ธฐ ๋–„๋ฌธ์— Subscriber๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฉ”์‹œ์ง€๊ฐ€ ์‚ฌ๋ผ์ง€๊ฒŒ ๋œ๋‹ค.

Subscriber: ๊ตฌ๋… ์ค‘์ธ Topic์— ๋Œ€ํ•˜์—ฌ, Publisher์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹  ๋ฐ›๋Š”๋‹ค.

Channel(Topic): ๋ฐœํ–‰๋œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ๊ตฌ๋…์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. Topic์ด ์žˆ์Œ์œผ๋กœ์จ ๊ฐ๊ฐ์˜ ๊ด€์‹ฌ์‚ฌ๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ๋ฐœํ–‰์ž์™€ ๊ตฌ๋…์ž๊ฐ€ Loose Coupling์ด ๋œ๋‹ค.

Kafka์™€์˜ ์ฐจ์ด์ 

Kafka ํŠน์ง•

kafka
  • Consumer๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ Topic์— ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ฉด์„œ ๋ฉ”์‹œ์ง€๋ฅผ Pollingํ•œ๋‹ค.
  • Topic์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ๊ฐ€๋„ ๋ฐ”๋กœ ์‚ญ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋ณด๊ด€ ์ฃผ๊ธฐ, ์šฉ๋Ÿ‰์ด ์ดˆ๊ณผ๋˜๋ฉด ์‚ญ์ œ๋œ๋‹ค.
  • Consumer๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ณ  ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด ๋ฉ”์‹œ์ง€์˜ ์ฒ˜๋ฆฌ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Consumer๋“ค์€ ํ•˜๋‚˜์˜ Consumer Group๋กœ ๊ด€๋ฆฌ๋œ๋‹ค.
  • Consumer๋Š” ๊ฐ์ž offset์„ ๊ฐ€์ง€๊ณ ์žˆ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋Š”์ง€ ๊ธฐ๋กํ•œ๋‹ค.

Redis ํŠน์ง•

redis
  • Channel์€ Subscriber๊ฐ€ ๊ตฌ๋…ํ•˜๋Š” ์ˆœ๊ฐ„์— ์ƒ์„ฑ๋œ๋‹ค.
  • Publisher๊ฐ€ Channel์— ๋ฐœํ–‰์„ ํ•˜๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น Channel์„ ๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  Subscriber์—๊ฒŒ ๋ฉ”์‹œ์ง€๊ฐ€ ์ „์†ก๋œ๋‹ค.
  • ๋ฉ”์‹œ์ง€๋ฅผ ์ผ๋ฐฉ์ ์œผ๋กœ ๋ฐœํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Subscriber๊ฐ€ ์ •์ƒ ์ˆ˜์‹ ํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • Kafka์™€ ๋‹ค๋ฅด๊ฒŒ polling์ด ์•„๋‹Œ ์ฑ„๋„๋กœ๋ถ€ํ„ฐ ์ˆ˜์‹ ๋ฐ›๋Š” ๋ฐฉ์‹์ด๋‹ค.
  • Group์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— Subscriber๋“ค์€ ์ฑ„๋„์˜ ๋ชจ๋“  ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹  ๋ฐ›๋Š”๋‹ค.
  • Subscriber๋Š” ํŠน์ • ํŒจํ„ด์„ ํ†ตํ•ด ์ฑ„๋„์„ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋‹ค.

Kafka, Redis ๋น„๊ต

  • ๋ฉ”์‹œ์ง€ ์ €์žฅ ์—ฌ๋ถ€
    • Kafka: ํ† ํ”ฝ์— ์ผ์ • ๊ธฐ๊ฐ„๋™์•ˆ ๋ฉ”์‹œ์ง€๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ
    • Redis: ๋ฉ”์‹œ์ง€๊ฐ€ Subscriber์—๊ฒŒ ์ „์†ก๋˜๋ฉด์„œ ์ฑ„๋„์—์„œ ๋ฐ”๋กœ ์‚ญ์ œ๋จ
  • ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ๋ฐฉ์‹
    • Kafka: Consumer๊ฐ€ polling๋ฐฉ์‹์œผ๋กœ Topic์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ๊ฐ
    • Redis: ์ฑ„๋„์—์„œ Subscriber์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœ์†ก
  • ์ „์†ก๋ณด์žฅ
    • Kafka: ack ์˜ต์…˜์— ๋”ฐ๋ผ ๋ณด์žฅ ๊ฐ€๋Šฅ
    • Redis: ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ–ˆ๋Š”์ง€ ๋”ฐ๋กœ ํ™•์ธํ•˜์ง€ ์•Š์Œ
  • ์ง€์—ฐ์‹œ๊ฐ„
    • Kafka: ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•ด ack ์˜ต์…˜์— ๋”ฐ๋ผ ์ž‘์—…์ด ์žˆ์–ด์„œ redis์— ๋น„ํ•ด ๋น„๊ต์  ๋Š๋ฆฌ๋‹ค
    • Redis: In-memory ๊ธฐ๋ฐ˜์ด๊ณ , ์ˆ˜์‹ ํ™•์ธ ๊ฐ™์€ ์ž‘์—…์ด ์—†์–ด์„œ kafka์— ๋น„ํ•ด ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๋‹ค
  • ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ๋‹จ์œ„(์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ๋Š” ํ™˜๊ฒฝ)
    • Kafka: ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ™์€ Consumer Group์— ๋ฌถ์—ฌ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค์—์„œ๋งŒ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•œ๋‹ค.
    • Redis: ๊ฐ Subscriber ๋‹จ์œ„๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•œ๋‹ค.

์ •๋ฆฌ

๋‚ฎ์€ Latency์™€ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—” โ†’ Redis pub/sub์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์˜์กด์„ฑ์„ ๋ถ„๋ฆฌํ•˜๊ณ  ํŠน์ • ์ด๋ฒคํŠธ๋ฅผ ์ค‘๋ณต์—†์ด(๋ฉฑ๋“ฑ์„ฑ) 1๊ฑด๋งŒ ๋ฐ›์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— Kafka ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์‹ค์Šตํ•ด๋ณด๊ธฐ

์ด ์‹ค์Šตํ™˜๊ฒฝ์—์„  docker๋กœ redis๋ฅผ ๋„์šฐ๊ณ  ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ์— redis-cli๋ฅผ 2๊ฐœ ๋„์šด๋‹ค.

  1. Subscriber) redis-cli๋กœ ์ ‘๊ทผํ•œ๋‹ค.
  2. Subscriber) test-channel ๋ผ๋Š” ์ด๋ฆ„์˜ ์ฑ„๋„์„ ๊ตฌ๋…ํ•œ๋‹ค. (๊ตฌ๋…๊ณผ ๋™์‹œ์— ์ฑ„๋„ ์ƒ์„ฑ, ๊ตฌ๋… ๋ชจ๋“œ๋กœ ์ „ํ™˜๋จ)
  3. Publisher) redis-cli๋กœ ์ ‘๊ทผํ•œ๋‹ค.
  4. Publisher) pubsub channels๋กœ ์ฑ„๋„ ๋ชฉ๋ก์„ ํ™•์ธํ•œ๋‹ค.
  5. Publisher) publish test-channel "hello world!" ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•œ๋‹ค.
  6. Subscriber) ๋ฉ”์‹œ์ง€๋ฅผ ์ž˜ ์ˆ˜์‹ ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

terminal 1 (Publisher)

docker exec -it f834e54cbcdbff0882c2da9909369242e56acd5c8e790642db248d7e8c1f6f6f /bin/sh
# cli ์ ‘๊ทผ
$ redis-cli

# ์ฑ„๋„ ๋ชฉ๋ก์„ ํ™•์ธํ•œ๋‹ค.
$ pubsub channels
# 1) "test-channel"

$ publish test-channel "hello world!"
# (integer) 1

terminal 2 (Subscriber)

docker exec -it f834e54cbcdbff0882c2da9909369242e56acd5c8e790642db248d7e8c1f6f6f /bin/sh
# cli ์ ‘๊ทผ
$ redis-cli

# test-channel์ด๋ผ๋Š” ์ฑ„๋„์„ ๊ตฌ๋…ํ•œ๋‹ค.
$ subscribe test-channel
# subscribed mode๋กœ ์ ‘๊ทผ(๋Œ€๊ธฐ ๋ฐ›๋Š” ์ƒํƒœ๊ฐ€ ๋จ)

# 1) "message"
# 2) "test-channel"
# 3) "hello world!"
yoon.homme
yoon.homme

๊ธฐ์ˆ ๊ณผ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์˜ ํž˜์ด ์„ธ์ƒ์„ ๋ฐ”๊พผ๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

ํŽธ๋ฆฌํ•œ ์„ธ์ƒ์œผ๋กœ ๋‚˜์•„๊ฐ€๊ธฐ ์œ„ํ•ด ๊ณ ๋ฏผํ•˜๊ณ  ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.