๊ฐ๋ณ๊ณ ๋น ๋ฅธ 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 ํน์ง
- Consumer๊ฐ ์ฃผ๊ธฐ์ ์ผ๋ก Topic์ ๋ฉ์์ง๊ฐ ์๋์ง ํ์ธํ๋ฉด์ ๋ฉ์์ง๋ฅผ Pollingํ๋ค.
- Topic์์ ๋ฉ์์ง๋ฅผ ๊ฐ์ ธ๊ฐ๋ ๋ฐ๋ก ์ญ์ ๋์ง ์๋๋ค. ๋ณด๊ด ์ฃผ๊ธฐ, ์ฉ๋์ด ์ด๊ณผ๋๋ฉด ์ญ์ ๋๋ค.
- Consumer๊ฐ ๋ฉ์์ง๋ฅผ ์ฝ๊ณ ํ์ธํ ์ ์์ด ๋ฉ์์ง์ ์ฒ๋ฆฌ ์ํ๋ฅผ ์ถ์ ํ ์ ์๋ค.
- Consumer๋ค์ ํ๋์ Consumer Group๋ก ๊ด๋ฆฌ๋๋ค.
- Consumer๋ ๊ฐ์ offset์ ๊ฐ์ง๊ณ ์๊ณ ๋ฉ์์ง๋ฅผ ์ด๋๊น์ง ์ฝ์๋์ง ๊ธฐ๋กํ๋ค.
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๊ฐ ๋์ด๋ค.
- Subscriber) redis-cli๋ก ์ ๊ทผํ๋ค.
- Subscriber)
test-channel
๋ผ๋ ์ด๋ฆ์ ์ฑ๋์ ๊ตฌ๋ ํ๋ค. (๊ตฌ๋ ๊ณผ ๋์์ ์ฑ๋ ์์ฑ, ๊ตฌ๋ ๋ชจ๋๋ก ์ ํ๋จ) - Publisher) redis-cli๋ก ์ ๊ทผํ๋ค.
- Publisher)
pubsub channels
๋ก ์ฑ๋ ๋ชฉ๋ก์ ํ์ธํ๋ค. - Publisher)
publish test-channel "hello world!"
๋ก ๋ฉ์์ง๋ฅผ ๋ฐํํ๋ค. - 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!"