ํด๋น ์ํฐํด ์ ๋ฆฌ๋ ๊ท๋ก ๋ค์ผ๋ฉฐ ์ ๋ฆฌํ๋ ํฌ์คํ ์ ๋๋ค.
๊ตฌ๊ธ์ NotebookLM์ผ๋ก ์์ฝํ ๋ด์ฉ์
๋ผ๋์ค์ฒ๋ผ ์ฌ์ํด ๋ค์ผ๋ฉฐ ๊ณต๋ถํ๊ณ ์์ต๋๋ค.๐ง
ํ ์คํธ ์ฝ๋ ์ค์์ฑ, ํจ๊ณผ์ ์ธ ํ ์คํธ ์ ๋ต
ํ ์คํธ ์ฝ๋๊ฐ ์ค์ํ ์ด์
ํ ์คํธ ์ฝ๋์ ๋ํด ๊ฐ ๊ธฐ์ ์ ์๊ฐ์ ๋ค์๊ณผ ๊ฐ๋ค.
๐ ์ ํ
๊ธฐ๋ฅ ๊ฒ์ฆ, ๋ฒ๊ทธ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌ, ์ฝ๋ ์ ์ง๋ณด์์ฑ, ํ์ ๋์, ์ ๋ฐ์ ์ธ ์ฝ๋ ํ์ง๊ณผ ์์ ์ฑ ํ๋ณด ๋ฉด์์ ์ข๋ค.
๐ ํ ์ค
์๋ก์ด ๊ธฐ๋ฅ์ ๋ง๋ค ๋ ๊ฒ์ฆํ๊ณ , ๊ธฐ์กด ๊ธฐ๋ฅ ์์ ์ ํ๊ท ํ ์คํธ ํ์ํ๋ค.
ํ์ค์์๋ ํ ์คํธ์ฝ๋ ์์ฑ์ด ์ ์ด๋ ค์ธ๊น?
๊ฐ์ฅ ํฐ ์ด์ ๋ ์์ฑํด์ผํ ํ ์คํธ์ ์ ๋์ ์ธ ์์ด ๋ง๋ค๋ ๊ฒ. ๋๋ค๋ฅธ ๋ฌธ์ ๋ ๊ตฌํ ์ฝ๋๋ ๋ฐ์ ํ๊ฒ ์ฎ์ฌ์ ๊นจ์ง๊ธฐ ์ฌ์ด ํ ์คํธ(fragile test)๊ฐ ๋ ์ ์๋ค๋ ์ .
๐ ์นด์นด์คํ์ด
์๋น์ค๊ฐ ๋ณต์กํด์ง๊ณ ์ธ๋ถ ์์คํ ์์กด์ฑ์ด ๋์ด๋๋ฉด์ ํ ์คํธ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ ธ์ ๊ฐ๋ฐ ์์ฐ์ฑ์ด ์คํ๋ ค ๋จ์ด์ง๋ค๋ ์ .
๊ทธ๋ ๋ค๋ฉด ์ข์ ํ ์คํธ๋, ์ด๋ค ์กฐ๊ฑด์ ๊ฐ์ถฐ์ผํ ๊น?
ํ ์ค์์๋ FIRST ๊ท์น์ ์๊ฐํ๋ค.
- Fast: ๋น ๋ฅด๊ฒ ๋์ํ๊ธฐ
- Indenpendant: ๋ ๋ฆฝ์ ์ผ๋ก ์คํ ๊ฐ๋ฅํ๊ธฐ
- Repeatable: ๋ฐ๋ณตํด๋ ๊ฐ์ ๊ฒฐ๊ณผ ๋ด๊ธฐ
- Self-Validating: ์ค์ค๋ก ๊ฒ์ฆํ๊ธฐ
- Timely: ์ ์์ ์์ฑ๋๊ธฐ
์ ํ์์๋ ๋ ๋ฆฝ์ฑ, ๋ฐ๋ณต๊ฐ๋ฅ์ฑ, ๋ช ํ์ฑ, ๋น ๋ฅธ ์คํ, ์ง์์ ์ธ ์ ์ง๋ณด์๋ฅผ ๊ฐ์กฐํ๋ค.
ํ ์ค๋ ์ฌ๊ธฐ์ ๋๋ถ์ด, ์์ ์ฑ(ํ ์คํธ์ฝ๋๋ฅผ ์ดํดํ๋๋ฐ ํ์ํ ๋ชจ๋ ์ ๋ณด๊ฐ ์ฝ๋ ๋ด์ ๋ช ํํ ๋๋ฌ๋์ผ ํ๋ค) ๊ณผ ๊ฐ๊ฒฐ์ฑ(๋ถํ์ํ ๋ด์ฉ์ ๋นผ๊ณ ํต์ฌ ๊ฒ์ฆ ๋ก์ง์ ์ง์คํด์ผ ํ๋ค) ์ ์ด์ผ๊ธฐํ๋ค.
ํ์ง๋ง ์ด๋ฌํ ์์น๋ณด๋ค ๋์ฑ ์ค์ํ ๊ฒ์
๊ทธ ํ ์คํธ๊ฐ ๊ณผ์ฐ ๋น์ฆ๋์ค์ ์ผ๋ก ๊ฐ์น์๋๊ฐ?(Valuable Test)๊ฐ ์ ์ผ ์ค์ํ๋ค.
ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง ์ซ์๋ง ๋์ด๊ธฐ ์ํด์ ์์ฑ๋ ์ค์ง์ ์ธ ๋ฌธ์ ๋ฐ๊ฒฌ์ด๋ ์์ ์ฑ ํฅ์์ ๊ธฐ์ฌํ์ง ๋ชปํ ํ ์คํธ๋ ๊ทธ์ ์๊ฐ ๋ญ๋น์ผ ๋ฟ์ด๋ผ๋ ๊ฑฐ๋ค.
ํ ์คํ์์ ์ด์ผ๊ธฐํ ๊ฐ์น ์๋ ํ ์คํธ ์ฝ๋ ์ ๋ต์ด๋?
- ๋ชจ๋ ๊ฒ์ ํ ์คํธํ๋ ค ํ์ง ์๊ณ ์์ฑ ๊ฐ์น๋ฅผ ๋ฐ์ ธ์ ์ ํ์ ์ผ๋ก ์์ฑํ๋ค. => ํต์ฌ ๊ธฐ๋ฅ 20%์ ์ง์คํด์ 80%์ ์ ๋ขฐ๋ ํ๋ณดํ๊ธฐ!
- ์ต๋ํ ์ค์ฉ์ ์ผ๋ก ์์ฑํ๋ค. => ํตํฉ ํ ์คํธ ์์ฑ์ผ๋ก ํ ์คํธ ์ฝ๋์ ์ด๋ ์ค์ด๊ธฐ!
- ํ ์คํธ์ ํ์คํ ๋ชฉ์ ์ ๋ฐ๋ผ ๊ตฌ๋ถํด์ ์์ฑํ๊ธฐ
๊ทธ๋ผ ์ค์ ์ฝ๋ ๋ ๋ฒจ์์ ์ด๋ค ์ ๋ต์ ๋ค๋ฃจ๋์ง ์ดํด๋ณด์.
ํ ์คํ์์ ๋๋ฉ์ธ ์ ์ฑ ํ ์คํธ๋ฅผ ๋จ์/์ ๋ ํ ์คํธ๋ก ์์ฑํ๋ค๊ณ ํ๋ค. ex) ๋ง 19์ธ ๋ฏธ๋ง์ ํน์ ์ด๋ฒคํธ์ ์ฐธ์ฌํ๊ฒ ํ ์ ์๋ค
์ธ๋ถํ๊ฒฝ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์กด์ฑ ์์ด ํด๋น ๋ก์ง๋ง ๋น ๋ฅด๊ฒ ํ์ธํ๋๋ฐ ๋ชฉ์ ์ด ์๋ค. ํ ์ค๋ ์ด๋ฐ ๋จ์ํ ์คํธ๋ฅผ ์์ฑํ ๋ ํ ์คํธ ๋์์ SUT(System-Under-Test) ๋ผ๊ณ ๋ถ๋ฅธ๋ค. SUT์ ํ๋ ฅ์ด ํ์ํ ๊ฐ์ฒด๊ฐ ์์ ์ ์๋ค๋๋ฐ ์ด๋ฅผ ํ๋ ฅ์ ๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์ด๋ ํ ์คํธ ๋์ญ์ผ ์๋ ์๊ณ ์ค์ ๊ฐ์ฒด์ผ ์๋ ์๋ค.
ํ ์คํธ ๋์ญ์ ์ข ๋ฅ
- Dummy(์ธ์๋ก ์ ๋ฌ๋์ง๋ง ์ค์ ์ฌ์ฉ์๋๋)
- Spy(ํธ์ถ๋๋์ง ๊ธฐ๋กํ๋)
- Stub(์ ํด์ง ๊ฐ์ ๋ฐํํ๋)
- Mock(ํน์ ๋ฉ์๋๊ฐ ์์๋๋ก ํธ์ถ๋๋์ง ๊ฒ์ฆํ๋)
- Fake(์ค์ ๊ฐ์ฒด์ฒ๋ผ ๋์ํ์ง๋ง ์ด์์์๋ ์ฐ์ง ์๋)
์ค์ ๊ฐ์ฒด๋ฅผ ๋๊ณ ํ ์คํธ๋ฅผ ํ์ => ๊ณ ์ ํ(Classicist) ํ ์คํธ ๋์ญ(ํนํ Mock ๊ฐ์ฒด)์ ๋๊ณ ํ ์คํธ๋ฅผ ํ์ => ๋ฐ๋ํ(London School, Mockist)
ํ ์ค์์๋ ์ค์ ๊ฐ์ฒด๋ฅผ ํ์ฉํ๋ ๊ฒ์ ๋์ฑ ์ ์ฉํ ๊ฑฐ๋ผ๊ณ ํ๋๋ฐ, ์ด์ ๋ ํ ์คํธ ๋์ญ์ ์ฌ์ฉํ ๋, ํ ์คํธ ์์ฑ ์๋๋ฅผ ๋์ด๊ณ ๋ณต์กํ ์์กด์ฑ ์์ฑ์ ํผํ ์ ์๋ ์ฅ์ ์ด ์์ง๋ง, SUT์ ๋ด๋ถ ๊ตฌํ๊ณผ ๊ฐ๊ฒฐํฉ์ด ์๊ธฐ๊ฒ ๋์ด ํ ์คํธ๊ฐ ์คํจํ ์ ์๋ค๋ ๋จ์ ์ด ์๋ค.(์ฆ, ๊ตฌํ์ด ๋ฐ๋๋ฉด ํ ์คํธ๊ฐ ๊นจ์ ธ๋ฒ๋ฆฌ๋..) ๋ํ, ํ ์คํธ ์ฝ๋์ ๋ณต์กํ ์ฌ์ ์ค์ ๊ณผ์ ๋๋ฌธ์ ๋น์ฆ๋์ค ๋ก์ง๋ณด๋ค ์ดํดํ๊ธฐ ์ด๋ ค์์ง๋ฉด์ ๋ฌธ์ํ์ ์ญํ ๋ํ ํ์ง ๋ชปํ๋ ํน์ง๋ ์๋ค.
ํ ์ค์ ์ ์ค์ผ์ด์ค ํ ์คํธ ์ฌ์ฉ์์ ์ค์ ์๋๋ฆฌ์ค๋ฅผ ๊ฒ์ฆํ๋ ์ธ์ ํ ์คํธ์ด์ ํตํฉํ ์คํธ ๋ฐฉ์์ผ๋ก ์์ฑ๋๋ค. API ๋ช ์ธ ์ธ์ ์ธ๋ถ ๊ตฌํ์ ๋ชจ๋ฅด๋ ์ํ์ ๋ธ๋๋ฐ์ค ํ ์คํธ๋ก ์์ฑํ๋ค.
๊ฐ ํ ์คํธ๊ฐ ์๋ก ์ํฅ์ ์ฃผ์ง ์๊ณ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋๊ฒ ํ๊ธฐ ์ํด ํ ์คํธ ์์ ์ , ํ์ํ ๋ฐ์ดํฐ๋ฅผ DB์ ์ค๋น์ํค๊ณ (set-up) ํ ์คํธ๊ฐ ๋๋ ํ์๋ ๊นจ๋ํ๊ฒ ์ ๋ฆฌ(tear-down)ํ๋ค.
ํ ์คํ์์๋ JSON ํ์ผ์ ์ด์ฉํ๋๋ฐ ์ด๋ฐ์๋ SQL์ ์ฌ์ฉํ ๋ ํ ์ด๋ธ ๊ตฌ์กฐ ๋ณ๊ฒฝ๊ณผ ๊ฐ์ ๊ด๋ฆฌ๊ฐ ๋ฒ๊ฑฐ๋ก์์ ๋ ์ ์ฐํ๊ณ ์ฉ์ดํ JSON ๋ฐฉ์์ ์ฑํํ๋ค.
ํ ์คํธ ๋์ญ ํ์ฉ ์
ํ ์ค ์ธ๋ถ ์๋น์ค์ธ ๊ฒฝ์ฐ
- Fake ๊ฐ์ฒด ๊ตฌํ
ํ ์ค ๋ด๋ถ ์๋น์ค์ธ ๊ฒฝ์ฐ
- ๋น์ฆ๋์ค ์ธ์ ์ธ ๋ถ์ํจ๊ณผ๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ: Dummy ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ
- ๋ฐ์ดํฐ ํ๋ณด๊ฐ ์ด๋ ค์ด ๊ฒฝ์ฐ: ๋ชจ์ ๊ฐ์ฒด ํ๋ ์์ํฌ(Mockito)๋ฅผ ํตํด Stub ์ฌ์ฉ
- ๊ทธ ์ธ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ: ์ค์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ
ํ ์ค์ ์ง๋ ฌํ/์ญ์ง๋ ฌํ ํ ์คํธ
ํ ์ค์์๋ ์นด๋๋ฆฌ ๋ฐฐํฌ ์ ๋ต์ ์ทจํ๊ณ ์๋ค.
์นด๋๋ฆฌ ๋ฐฐํฌ๋? ์๋ก์ด ๋ฒ์ ์ ์ฝ๋๋ฅผ ์ผ๋ถ ์ฌ์ฉ์์๊ฒ๋ง ๋จผ์ ๋ฐฐํฌํ๊ณ ์ ์ง์ ์ผ๋ก ํ๋ํ๋ ๋ฐฐํฌ ๋ฐฉ์
์ฌ๊ธฐ์ ๋ฌธ์ ๋ ์ด์ ๋ฒ์ ๊ณผ ์๋ก์ด ๋ฒ์ ๊ณผ์ ํธํ์ฑ ๋ฌธ์ ์ด๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์บ์ ๋ฒ์ ๋ ์ ๋ต์ด ํ์ํ๋ฐ ์ด๊ฑธ ๊ผผ๊ผผํ๊ฒ ๋งค๋ฒ ์ฑ๊ธฐ๊ธฐ ์ด๋ ต๋ค.
ํ ์ค์์๋ ์ด๋ฌํ ํ ์คํธ ์คํจ๋ฅผ ํ๋์ ์ ํธ๋ก ๊ฐ์ ธ๊ฐ ๊ฒ์ฆํ๋ค๊ณ ํ๋ค.
์นด์นด์คํ์ด๋ ์ธ๋ถ ํํธ๋ ์๋น์ค์์ http ํต์ ์ ํ ์คํธํ๊ธฐ ์ํด Mock ์๋ฒ๋ฅผ ๋์ ์ง์ ์ฌ์ฉํ๋ค๊ณ ํ๋ค.
ํ์ง๋ง ์ด ๋ฐฉ์์ ์ฐ๋ํ๋ ์ธ๋ถ ์๋น์ค๊ฐ ๋ง์์ง๊ณ ๊ฐ ์๋น์ค๋ง๋ค ๋ค์ํ ์๋ต ์๋๋ฆฌ์ค๊ฐ ํ์ํ ์ํฉ์ด ๋์ ๋นํจ์จ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๊ณ ํ๋ค.
๋์์ผ๋ก, ์คํ๋ง๋ถํธ์ @MockBean์ ์ฌ์ฉํ๋ ๊ฒ์ธ๋ฐ, ์ด๋ ์ธ๋ถ ์๋น์ค์ ํต์ ํ๋ ์ญํ ์ ํ๋ค. ์ฆ, Bean ์์ฒด๋ฅผ mockingํ๋ ๊ฒ!
ํ์ง๋ง ์ด๋ฅผ ์ฌ์ฉํ๋ฉด์ ์ ์ฒด ํ ์คํธ ์คํ ์๊ฐ์ด ๊ธธ์ด์ง๋ค๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ์คํ๋ง์ ํ ์คํ ์คํ ์๋๋ฅผ ๋์ด๊ธฐ ์ํด ๋์ผํ ์ค์ ์ ์ฌ์ฉํ๋ ํ ์คํธ ํด๋์ค ๊ฐ์๋ Application context , ์ฆ ์ ํ๋ฆฌ์ผ์ด์ ์คํ์ ํ์ํ ๋ชจ๋ Bean ๊ฐ์ฒด์ ์ค์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ์ปจํ ์ด๋๋ฅผ ํ ๋ฒ๋ง ๋ง๋ค์ด์ ์บ์ฑํ๊ณ ์ฌ์ฌ์ฉ(Context Caching)ํ๋ค @MockBean์ ์ฌ์ฉํ๋ฉด ๊ฐ ํ ์คํธ ํด๋์ค๋ง๋ค ๊ณ ์ ํ Mock ์ค์ ์ ๊ฐ์ง๊ฒ ๋๋๊น ์คํ๋ง์ ์ปจํ ์คํธ๋ฅผ ์ฌ์ฌ์ฉํ์ง ๋ชปํ๊ณ ๋งค๋ฒ ์๋ก ๋ง๋ค๊ฒ ๋๋ค. ๊ทธ๋ ๊ธฐ์ ๊ณ์ ๋์ด๋๋ ํ ์คํธ ํด๋์ค ๋๋ฌธ์ ์ปจํ ์คํธ ๋ก๋ฉ ์๊ฐ ๋์ ์ด ๋๊ณ ์ ์ฒด ๋น๋ ์๊ฐ์ด ๊ธธ์ด์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ ๊ฒ์ด๋ค.
์นด์นด์คํ์ด๋ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ ์คํธ ํ๊ฒฝ ์ ์ฉ ์ค์ ํด๋์ค, @TestConfiguration์ ๋ง๋ค๊ณ ๊ทธ ์์ Mock ๊ฐ์ฒด๋ฅผ ์ ์ Bean์ผ๋ก ๋ฑ๋กํ๊ฒ ๋๋ค. ์ด๋ก ์ธํด ์คํ๋ง์ Mock ๊ฐ์ฒด๋ฅผ ์ผ๋ฐ Bean์ผ๋ก ์ธ์ํ๊ณ ์ปจํ ์คํธ๋ฅผ ์ฌ์ฌ์ฉํ๊ฒ ๋๋ค.
ํ ์คํธ ์ฝ๋ ํ๊ฒฝ์ ์ด์ํ๊ฒฝ๊ณผ ์ฒ ์ ํ ๋ถ๋ฆฌ๋์ด์ผ ํ๋ค!
๋๋์ : ํ์ฌ ํ๋ก์ ํธ ์ํฉ์ ๋ง๊ฒ ๊ฐ์ฅ ๊ฐ์น ์๋ ํ ์คํธ ์ ๋ต์ ๋ฌด์์ผ์ง ๋์์์ด ๊ณ ๋ฏผํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ์ง์์ ์ธ ๊ณผ์ ๋ผ๋ ๊ฒ์ ์ด๋ฒ ์ํฐํด์ ํตํด ํ์คํ ๋๋ผ๊ฒ ๋์๋ค. ์ ๋ต์ด๋ ์๊ณ , ๋์ ๋ฐ๋ผ ๊ทธ์ ๋ง๋ ์ฉ์ดํ ํ ์คํธ ์ฝ๋๋ฅผ ์ง๋ ๊ฒ์ด ์ค์ํ ๊ฒ ๊ฐ๋ค!
๐ https://d2.naver.com/helloworld/9921217
๐ https://toss.tech/article/test-strategy-server
๐ https://f-lab.kr/insight/backend-test-code-writing-20240716
๐ https://tech.kakaopay.com/post/mock-test-code/
Kafka ๋ฐ์ดํฐ ์ ์ค, ์ค๋ณต ๋ฐฉ์ง
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ฅผ ์นดํ์นด๋ ์ด๋ป๊ฒ ํ๋ฉด ์ฝ๊ฒ ์ฐ๊ฒฐํ ์ ์์๊น? ๋ ๊ทธ ๊ณผ์ ์์ ์์ ์ฑ์ ์ด๋ป๊ฒ ํ๋ณดํ ๊น?์ ๋ํ ๋ด์ฉ์ด๋ค.
๋ง์ผ์ปฌ๋ฆฌ์ ์ฌ๋ฆฌ๋ธ์์ ์ฌ๋ก๋ฅผ ๋ณด๋ฉด์ ์ ๋ฆฌํด๋ณด์.
๐ ๋ง์ผ์ปฌ๋ฆฌ
์ปฌ๋ฆฌ๋ ์ฌ๋ฌ ์ข ๋ฅ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฐ๋ฉด์ ํตํฉ์ ์ด๋ ค์์ ๊ฒช์ด ์นดํ์นด์ ์ปค๋ฅํธ๋ฅผ ๋์ ํ๋ค๊ณ ํ๋ค.
Kafka Connect๋?
๋ค์ํ ๋ฐ์ดํฐ์์ค(RDBMS, NoSQL, File System ๋ฑ)๋ค์ ์นดํ์นด๋ ์ฝ๊ฒ ์ฐ๊ฒฐํ๊ธฐ ์ํ ๋ค๋ฆฌ ์ญํ ์ด๋ค. ๊ฐ๋ฐ์๊ฐ ์ง์ ์ฝ๋๋ฅผ ์ง์ง ์๊ณ JSON ํ์์ ์ค์ ํ์ผ ๋ง์ผ๋ก ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋ง๋ค ์ ์๋ค๋ ์ !
๋ด๋ถ์ ์ผ๋ก๋ ์ด๋ป๊ฒ ๋์๊ฐ๊ณ ์๋๊ฑธ๊น?
์ถ์ฒ: ๋ง์ผ ์ปฌ๋ฆฌ ํ
ํฌ ๋ธ๋ก๊ทธ
์นดํ์นด ์ปค๋ฅํธ๋ผ๋ ์ ์ฒด ํ๋ ์์ํฌ๊ฐ ์๊ณ ๊ทธ ์์ Worker๋ผ๋ ํ๋ก์ธ์ค๊ฐ ๋์๊ฐ๋ค.
Worker๋ ์ค์ ํ์ผ์ ๋ฐ์๋ด๊ณ Connector๋ผ๋ ์นดํ์นด ์ปค๋ฅํธ ๋ด๋ถ์ ์ค์ ๋ฉ์์ง ํ์ดํ๋ผ์ธ์ ๋ง๋ค์ด์ ๊ด๋ฆฌํ๋ค.(์นดํ์นด ์ปค๋ฅํธ ํ๋ก์ธ์ค๊ฐ ์คํ๋๋ ์๋ฒ ๋๋ ์ธ์คํด์ค)
Connector๋ ์ค์ ๋ฐ์ดํฐ ๋ณต์ฌ ์์ ์ task(thread ๋ ๋ฒจ๋ก ์ํ)๋ผ๋ ์์ ์คํ ๋จ์๋ฅผ ๋ง๋ค์ด์ ๋ณ๋ ฌ๋ก ๋๋ฆฐ๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ฐ์ดํฐ ๋ณํ ์์ ์์๋ ์ด๋ป๊ฒ ๋๋ ๊ฑธ๊น?
Converter์ TransForm
Converter ๋ ๋ฐ์ดํฐ๊ฐ ์ฐ๋ ์ธ์ด๋ฅผ ๋ฐ๊พธ๋ ์ญํ .(DB์์ ๋์ค๋ ๋ฐ์ดํฐ๋ฅผ ์นดํ์นด๊ฐ ์์๋ฃ๊ธฐ ์ฝ๊ฒ json์ด๋ avro ๋ฑ ํฌ๋งท์ผ๋ก ๋ณํ)
Transform ์ ๋ค๋ฅธ ๋ง๋ก SMT(Single Message Transform) ์ด๋ผ ํ๋ค. ๋ฐ์ดํฐ๊ฐ ๋ด๊ณ ์๋ ๋ด์ฉ์ ๋ฐ๊พผ๋ค.(ํน์ ํ๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ๋ถํ์ํ ์ ๋ณด๋ฅผ ๋นผ๊ฑฐ๋, ๊ฐ์ ํ์์ ๋ฐ๊พธ๋ ๋ฑ)
๋ง์ผ ์ปฌ๋ฆฌ๋ JDBC ์์ค ์ปค๋ฅํฐ๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ด๋ ์ฃผ๊ธฐ์ ์ผ๋ก SQL ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ค ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ๊ฐ์งํ๋ค.
์ฆ๋ถ ์ฟผ๋ฆฌ ๋ชจ๋(Incremental Query Mode)
์ปค๋ฅํฐ๊ฐ ๋ง์ง๋ง์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ ํน์ ๊ฐ(ex. ์๋์ผ๋ก ์ฆ๊ฐํ๋ ID, PK, ํ์ ์คํฌํ)์ offset์ผ๋ก ๊ธฐ์ตํ๋ค. ์ดํ ์ด์ ์ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ๋ ๊ฑด๋๋ฐ๊ณ ์๋ก์ด ๋ฐ์ดํฐ๋ง ์ถ์ถํ๋๋ก ํ๋ค.
์ปฌ๋ฆฌ๋ ์ด๋ฅผ ์ด์ฉํ์ฌ CDC(Change Data Capture)๋ก ํ์ฉํ๋ค.
CDC(Change Data Capture)๋?
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์์คํ ์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ์ ๋ชจ๋ ์ถ์ ํ์ฌ ์ด๋ฅผ ์ธ๋ถ ์์คํ ์ผ๋ก ์ ๋ฌํ๋ ๊ธฐ์
๋ ๊ฐ์ง๊ฐ ์๋ค.
- ๋ก๊ทธ ๊ธฐ๋ฐ
- DB ๋ด๋ถ์ ํธ๋์ญ์ ๋ก๊ทธ๋ฅผ ์ฝ์ด์ ๋ณ๊ฒฝ ๋ด์ญ์ ์ค์๊ฐ์ผ๋ก ๊ฐ์ง
- ์ฅ์ : ์ค์๊ฐ์ผ๋ก ๋ณ๊ฒฝ์ ์ก์๋. DB ๋ถํ ์ ์. ์ญ์ ๋ฐ ๋ณ๊ฒฝ ๋ฑ์ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ๋์น์ง ์์.
- ๋จ์ : ๊ตฌํ ๋ณต์กํจ. DB์ ๋์ ๊ถํ ํ์. ์ค์ ๊น๋ค๋ก์. DB ์ข ๋ฅ๋ง๋ค ๋ก๊ทธ ๋ถ์ ๋ฐฉ์ ๋ค๋ฅผ ์ ์์.
- ์ฟผ๋ฆฌ ๊ธฐ๋ฐ
- ์ฅ์ : ์ฃผ๊ธฐ์ ์ผ๋ก ์ฟผ๋ฆฌ ์คํํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๊ธฐ ๋๋ฌธ์ ๊ตฌํ ๊ฐ๋จ. ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ธฐ ์ํ ์ฝ๊ธฐ ๊ถํ๋ง ์์ผ๋ฉด ๋๋ค. ๋ก๊ทธ ์์กด๋ ๋ฎ์. ๊ตฌ์ถ ๋น์ฉ ๋ฎ์.
- ๋จ์ : ๋ฐ์ดํฐ ๋๋ฝ์ด ๋ฐ์ํ ์ ์์.(์ญ์ , ๊ฐฑ์ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์ง์ฐ์ผ๋ก ์ด๋ฒคํธ ๋ฐ์ ์์์ ์ค์ DB์ ๋ฐ์๋๋ ์์๊ฐ ๋ฌ๋ผ์ง ๋)
์ฟผ๋ฆฌ ๊ธฐ๋ฐ์ ๋จ์ ์ค ํ๋์ธ ์์๊ฐ ๊ผฌ์ด๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ปฌ๋ฆฌ์์๋ timestamp.delay.interval.ms ๋ฅผ ์ฌ์ฉํ๋ค. ์ฆ, ์ง์ฐ์๊ฐ์ ์ฃผ๋ ๊ฒ์ด๋ค.(ex. 5๋ถ์ ์ฟผ๋ฆฌ ์คํํ๋ฉด, ์ง์ฐ์๊ฐ์ 2๋ถ์ผ๋ก ์ก์์ ๋ 3๋ถ๊น์ง์ ๋ฐ์ดํฐ๋ง ์นดํ์นด์ ์ ์ฌ์ํค๋ ๊ฒ)
์ด ์ต์ ์ ์ ์ฉํ ๋ ์ฃผ์์ฌํญ์ ์ด ๊ฐ์ด ํด์๋ก ๊ทธ๋งํผ์ ์ ์ฌ๊น์ง์ ์ง์ฐ๋ ์ฆ๊ฐํ๋ค๋ ์ ์ด๋ค.(์ค์๊ฐ์ฑ ์ ํ)
์ํฉ์ ๋ง๊ฒ ๊ท ํ ์๋ ์ค์ ์ ํ๋๋ก ํ์!
๐ซ ์ฌ๋ฆฌ๋ธ์
์ฌ๋ฆฌ๋ธ์์ ๋๊ท๋ชจ ์ฃผ๋ฌธ ๊ด๋ฆฌ์์คํ OMS๋ฅผ ๊ตฌ์ถํ๋ฉด์ ๊ธฐ์กด์ ๋ณต์กํ๋ EAI ์ Batch ๋ฐฉ์ ๋์ Kafka๋ฅผ ์ ๋ฉด ๋์ ํด์ ์ฑ๋ฅ์ 3๋ฐฐ์์ 45๋ฐฐ๋ก ์ฆ๊ฐ์์ผฐ๋ค๊ณ ํ๋ค.
Kafka์ ํน์ง ์ค ํ๋์ธ Exactly-once guarantees์ด ์๋๋ฐ, Kafka๋ Delivery Semantics๋ฅผ ์ค์ ํ ์ ์๋๋ฐ ํฌ๊ฒ ์ธ ๊ฐ์ง๊ฐ ์๋ค.
Message Delivery Semantics
- At most once: ์ต๋ ํ ๋ฒ์ ๋ฉ์ธ์ง๊ฐ ์ค๊ฐ์ ์ ์ค๋ ์๋ ์์ง๋ง ์ค๋ณต์ ์๋๋ค.
- At least once: ์ต์ํ ํ ๋ฒ์ ์ ์ค์ ์์ง๋ง, ์ค๋ณต์ ๋ฐ์ํ ์ ์๋ค.(Kafka์ ๊ธฐ๋ณธ๊ฐ)
- Exactly once: ์ ํํ ํ ๋ฒ์ ์ ์ค๋ ์๊ณ ์ค๋ณต๋ ์์ด ๋ฑ ํ ๋ฒ๋ง ์ ๋ฌ๋๋ค. ๊ตฌํ์ด ๊ฐ์ฅ ๊น๋ค๋ก์.
์ฌ๋ฆฌ๋ธ์์ ์ฌ์ฉ์์ ๊ฑฐ๋ ์ ๋ณด์ ๊ฐ์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ค์ ๋ค๋ฃจ๊ณ ์๊ธฐ ๋๋ฌธ์ Exactly once ์์ค์ ์ ๋ขฐ์ฑ์ ํ๋ณดํ๋๊ฒ ํ๋ก์ ํธ์ ํต์ฌ ๊ณผ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ฉ์์ง์ ์ ์ค๊ณผ ์ค๋ณต์ ์ด๋ ๋จ๊ณ์์ ๋ฐ์ํ๊ณ , ์ฌ๋ฆฌ๋ธ์์ ์ด๋ป๊ฒ ์ด ํต์ฌ ๊ณผ์ ์ ๋ํ ๊ณผ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ํ์๊น?
์ถ์ฒ: ์ฌ๋ฆฌ๋ธ์ ํ
ํฌ ๋ธ๋ก๊ทธ
๋ฉ์ธ์ง๋ฅผ ๋ณด๋ด๋ ์ชฝ(Producer)์ Kafka Broker ์ฌ์ด, ๋ฉ์์ง๋ฅผ ๋ฐ๋ ์ชฝ(Consumer)์ Kafka Broker ์ฌ์ด ๋ ๊ตฌ๊ฐ์ผ๋ก ๋๋ ์ ๋ณด์.
๋ฉ์ธ์ง๋ฅผ ๋ณด๋ด๋ ์ชฝ(Producer)์ Kafka Broker ์ฌ์ด
์ฌ๊ธฐ์ ์ ์ค์ ๊ฐ๋จํ๋ค. ๋คํธ์ํฌ ๋ฌธ์ ๋ก ๋์ฐฉ์ ์ ๋๋ก ๋ชปํ์ ์ ์๋ค. ์ด๋ฅผ ๋ง๊ธฐ ์ํด acks=all๊ณผ retry ์ต์ ์ ์ฌ์ฉํ๋ค.
์ฌ๊ธฐ์ acks=all์ ๋ชจ๋ ์๋ต์ ๋ค ํ์ธํ๋ค๋ ๋ป์ด๋ค. ์ด๋ ์ค๊ฐ์ Broker ํ๋์ ๋ฌธ์ ๊ฐ ์๊ฒจ๋ ๋ฐ์ดํฐ๊ฐ ์ ์ค๋ ๊ฐ๋ฅ์ฑ์ ์ค์ผ ์ ์๋ค. retry ์ค์ ์ ํตํด ์คํจํ๋ฉด ์ฌ์๋๋ ํ ์ ์๋๋ก ํ๋ค.
retry ์๋๋ก ์ค๋ณต ๋ฉ์์ง๊ฐ ๋ฐ์ก๋ ๊ฒฝ์ฐ, ๋ฉฑ๋ฑ์ฑ์ ์ด์ฉํ์ฌ ๋ง์๋ผ ์ ์๋ค. enable.idempotence=true ์ค์ ์ ํตํด Producer๊ฐ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ๋๋ง๋ค ๊ณ ์ ํ id๋ ์์ ์ํ์ค ๋ฒํธ๋ฅผ ๋ถ์ฌ์ ๋ณด๋ธ๋ค. Broker๋ ์ด id์ ์ํ์ค ๋ฒํธ๋ฅผ ๋ณด๊ณ ์ค๋ณต ์ ์ฅ์ ์์์ ๋ง์๋ธ๋ค. => ์ด๋ Kafka 3.0 ๋ถํฐ๋ ๊ธฐ๋ณธ ์ต์ ์ผ๋ก ์ค์ ๋์ด ์๋ค๊ณ ํ๋ค.
๋ฉ์์ง๋ฅผ ๋ฐ๋ ์ชฝ(Consumer)์ Kafka Broker ์ฌ์ด
์ ์ค(ex. Consumer๊ฐ ์ฌ๊ธฐ๋ ๋ ๋, Broker์ ๋ฉ์์ง๊ฐ ์ ์ฌ๋๋ ๊ฒฝ์ฐ => auto.offset.reset=earliest ์ฌ์ฉ, spring.kafka.listener.immediate-stop=false ์ฐ์ํ ์ค๋จ ์ฌ์ฉ)
์ค๋ณต(ex. Consumer๋ ์์ ์ด ์ฒ๋ฆฌํ ์ ๋ณด๋ฅผ ์คํ์ ์ ์ ๋ฆฌํด์ Broker์ ์ปค๋ฐ์ ํด์ฃผ์ด์ผ ํ๋ค. ๋ง์ฝ ์ด๋ ํ ๋ฌธ์ ๋ก ์ปค๋ฐ์ด ๋์ง ์์๋ค๋ฉด? Broker๋ Consumer๊ฐ ์๋ฐ์ ์ค ์๊ณ ๋ค์ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ์ง๋ง, ์ด๋ฏธ Consumer๋ ์ฒ๋ฆฌ๋ ๋ฉ์์ง์ด๋ฏ๋ก ์ค๋ณต ๋ฌธ์ ๋ฐ์! => AcksMode=MANUAL_IMMEDIATE(์ฆ์ ์๋ ์ปค๋ฐ) ์ฌ์ฉ, spring.kafka.listener.immediate-stop=false ์ฐ์ํ ์ค๋จ ์ฌ์ฉ )
์ด ์ธ์๋ ๋ฉ์์ง ์ฒ๋ฆฌ์๊ฐ์ด ๊ธธ์ด ์ค๋ณต์ด ๋ฐ์ํ ๊ฒฝ์ฐ๊ฐ ์๋ค๊ณ ํ๋ค.
Consumer๊ฐ Broker๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ํ ๋ฒ ๊ฐ์ ธ๊ฐ ๋ค์(poll) ๋ค์ poll ์์ฒญ๊น์ง ํ์ฉ๋๋ ์ต๋ ์๊ฐ(max.poll.interval.ms)์ด ์๋ค. ์ด๋ฅผ ์ด๊ณผํ์ ๋, Broker๋ ๋ฌธ์ ๊ฐ ์๋ค๊ณ ์๊ฐํ๊ณ ํด๋น Consumer๋ฅผ ์ ์ธํด๋ฒ๋ฆฐ๋ค.(kicked out) ์ดํ ๋ค๋ฅธ Consumer์๊ฒ ๋๊ฒจ์ค๋ค.(Rebalancing)
์ด์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก ๋ฒ์ ์ ์ด๋ session.timeout.ms, heartbeat.interval.ms, max.poll.interval.ms ์ค์ ๊ฐ์ ์กฐ์ ํด์ ์ปจ์๋จธ์๊ฒ ์ฌ์ ๋ฅผ ์ฃผ๋ ๋ฐฉ์, ๋ฉ์์ง ์ฒ๋ฆฌ ๋ก์ง์ ์ต์ ํํด์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
Kafka ๊ณ ๊ฐ์ฉ์ฑ ๋ณด์ฅ๊ณผ MSK ๋ณด์์ฑ ํจ์น ์ด์
- Broker ๋ค์คํ(Multi-AZ): ๋ธ๋ก์ปค ์๋ฒ๋ค์ ํ๋์ ๋ฐ์ดํฐ ์ผํฐ๊ฐ ์๋๋ผ ์ฌ๋ฌ ๊ฐ์ ๋ถ๋ฆฌ๋ ๊ฐ์ฉ ์์ญ์ ๋๋ ์ ๋ฐฐ์นํ๋ ๊ฒ
- Replication Factor: ๋ฐ์ดํฐ ๋ณต์ ๋ณธ ์
- Min In-Sync Replicas: Producer๊ฐ ๋ณด๋ธ ๋ฉ์์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ ์ฅ๋์๋ค๋ ์๋ต์ ๋ฐ๊ธฐ ์ํด ์ต์ํ ๋ช ๊ฐ์ ๋ณต์ ๋ณธ์ด ๋๊ธฐํ ๋์ด์ผ ํ๋์ง
Min In-Sync Replicas + acks=all ๊ฐ์ด ์ค์ ํ๋ฉด ๋ฉ์์ง ์ ์ค ๋ฐฉ์งํ ์ ์๋ค!
CooperativeSticky Strategy -> Rebalancing ์์ ๊ธฐ์กด Partition ํ ๋น์ ์ต๋ํ ์ ์งํ ์ฑ๋ก ํ์ํ ๋ถ๋ถ๋ง ๋ค๋ฅธ Consumer์๊ฒ ์ฎ๊ธด๋ค.
DLQ(Dead Letter Queue) ์๋ ๋ฐฑ์ ์์คํ ๊ตฌ์ถ
- DLQ ๋ฐ์ดํฐ ์ ์ฌ
- AWS Kinesis Data Firehose ๋ฐ์ดํฐ ์บก์ณ
- S3 ์ Json ํ์ผ๋ก ์ ์ฅ
- AWS Lambda ํจ์๋ก Json ํ์ผ์ Xlsx ํ์ผ๋ก ๋ณํ
- ๋ฐฑ์ ์ฑ๊ณต ์ SNS ํธ์ถ
- Slack ์ ํตํด DLQ ์ ์ฌ ๋ฐ ๋ฐฑ์ ์ํ ์๋
์ถ์ฒ: ์ฌ๋ฆฌ๋ธ์ ํ
ํฌ ๋ธ๋ก๊ทธ
๋๋์ : ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ์์ ์ฑ ์๊ณ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ณ ๋ฏผ๋ค์ ์๋กญ๊ฒ ์ ์ ์์๋ค. ์ค์ํ ๋ฉ์์ง๋ค์ ์์ง ์๋๋ก ๋จ๋จํ๊ฒ ์ค๊ณํ๋ ๊ณ ๋ฏผ์ ๊ณผ์ ์ ๋ณผ ์ ์์ด์ ์ข์๋ค!
๐ https://helloworld.kurly.com/blog/kafka-connect-pipeline/ ๐ https://oliveyoung.tech/2024-10-16/oliveyoung-scm-oms-kafka/
Vite
์ Webpack์์ Vite๋ก ๋ฐ๊ฟจ๋๊ฐ?
์นด์นด์ค MY๊ตฌ๋ ์๋น์ค๋ 5๋ ์ ๋ฆฌ์กํธ 16๋ฒ์ , ์นํฉ 4๋ฒ์ ์ผ๋ก ์์๋์๋ค. ์ต๊ทผ์๋ ๋ฆฌ์กํธ 19๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ ๋์ด์๋ค. ์คํ ๋ฆฌ๋ถ์ผ๋ก ์ปดํฌ๋ํธ ๊ฐ๋ฐ ์งํํ๋ค.
์ต์ ๊ธฐ์ ๋์ ๊ณผ์ (๋ฆฌ์กํธ 19 ์ ์ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ)์์ ๊ธฐ์กด ํ๋ก์ ํธ ๋ด์ ์์กด์ฑ์ด ๊ผฌ์ฌ๋ฒ๋ฆฐ ํ์์ด ๋ฐ์ํ๋ค.
์นํฉ ๊ทธ๋๋ก ์จ๋ ๋๋๊ฐ?
HMR๋ ๋น ๋ฅด๊ณ ํ๋ก๋์ ๋น๋๋ ์์ ์ ์ด์๋๋ฐ ์ ๋ฐ๊พธ๋ ๊ฑธ ๊ณ ๋ คํด์ผ ํ ๊น?
5๋ ๊ฐ ์ ๋ฐ์ดํธ ์์ ์ด ๋ง์์ง๋ฉด์ ์นํฉ ์ค์ ํ์ผ์ด ์ ์ ์ปค์ง๊ณ ๋ณต์กํด์ ธ์ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ก๋ค.
์ค์ ๋ณต์ก๋, ํธํ์ฑ, ์ํ๊ณ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋น๋ ๋๊ตฌ ์ ์ ํ๋ค.(์ฑ๋ฅ ๋ฐ ์๋ ๋ณด๋ค๋ ์ํ๊ณ์ ํ์ ์ค์)
Vite์ ํน์ง
- ์ค์ ํ์ผ์ด ์นํฉ๋ณด๋ค ํจ์ฌ ๊ฐ๋จํ๊ณ ์ง๊ด์ ์ด๋ผ๋ ํน์ง์ด ์๋ค!
- ์นํฉ์ ๋ฒ๋ค๋ง์ผ๋ก ์์ํ๋๋ฐ, vite๋ esm ๋ฐฉ์์ผ๋ก ํ์ํ ํ์ผ๋ก ๊ทธ๋๊ทธ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์์ฒญํด์ ์ฌ์ฉํ๋ค.(์ด๊ธฐ ๋ก๋ฉ์ด๋ hmr ์๋ ๋น ๋ฅธ ์ด์ )
- rollup ์ฌ์ฉ๊ณผ ์ํ๊ณ ํฌ๋ค๋ ํน์ง์ด ์๋ค.
- ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ํด ์๋ก ์ฌ์ฉํ๊ธฐ ์ข๋ค.
Parcel์ ํน์ง
- ์ ๋ก config => ์ค์ ์์ด ๋ฐ๋ก ์ธ ์ ์๋ค.
- ๋ณต์กํ ์๊ตฌ์ฌํญ์ ํ๋ก์ ํธ์๋ ์ ๋ง์ ์ ์๋ค.
- ์ํ๊ณ ์๋ค.
RsBuild์ ํน์ง
- rust ๊ธฐ๋ฐ => ์ฑ๋ฅ ์ข๊ณ ๋น๋ ์๋ ๋น ๋ฅด๋ค.
- ์นํฉ ํธํ์ฑ good
- ๊ฐ์ฅ ํฐ ์ฝ์ ์ ์ํ๊ณ ๋ถ์กฑ..
์์ฒญ๋ ์๋ ํฅ์ vs ๊ฒ์ฆ๋๊ณ ํ๋ถํ ์ํ๊ณ์ ์์ ์ฑ
์ Vite๋ฅผ ํํ์๊น?
- ์ค์ ์ ๋ณต์ก๋ -> ์ค๊ฐ ์ ๋์ vite ์น
- ํธํ์ฑ -> ์คํ ๋ฆฌ๋ถ๊ณผ์ ํธํ์ฑ ๊ณ ๋ ค
- ์ํ๊ณ -> llm๋ ์ถ์ฒํ ์ ๋์ ์ํ๊ณ(์ค..)
- ์ฑ๋ฅ -> RsBuild๋ณด๋จ ๋๋ฆฌ์ง๋ง ์นํฉ๋ณด๋จ ๋น ๋ฅด๋ค
๋ง์ด๊ทธ๋ ์ด์ ์์ ํ ๊ฒฐ๊ณผ๋? ๊ฐํธํด์ง ์ค์ , ๋นจ๋ผ์ง ์ปดํ์ผ ์๊ฐ๊ณผ hmr
๋๋์ : 5๋ ๊ฐ ์ด์ด์จ ํ๋ก์ ํธ ๋ง์ด๊ทธ๋ ์ด์ ์์ ์ฝ์ง ์์ํ ๋ฐ ์์์ ์๊ฐ 3์ผ๋ง์ ๋๋ธ ์นด์นด์ค ๊ฐ๋ฐ์๋ค ๋ฉ์๋ค!
Kafka์ ๋ด๋ถ ์๋ ๋ฐฉ์
Apache Kafka์ ์คํ ๋ฆฌ์ง ๊ตฌ์กฐ์ KRaft ํ๋กํ ์ฝ์ ๋ํ ๋ด์ฉ์ด๋ค.
์ฐ๋ฆฌ๊ฐ Kafka์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด ๋์คํฌ ์ด๋๊ฐ์ ์ ์ฅ๋ ํ ๋ฐ ์ด๋์ ์ ์ฅ๋๋๊ฑธ๊น?
Kafka Broker ์ค์ ํ์ผ์ log.dirs ํ๋ผ๋ฏธํฐ๊ฐ ์๋๋ฐ, ์ด๊ฒ์ด ์นดํ์นด๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋์คํฌ ์์ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ ์ญํ ์ ํ๋ค.
์นดํ์นด๋ฅผ ์ธ ๋ topic๊ณผ partition ๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ๋๋๋๋ฐ, ๋์คํฌ์๋ partition ๋ณ๋ก ํ์ผ์ด ํ๋์ฉ ์๊ธฐ๋ ๊ฑธ๊น?
=> ์ค์ ๋ก๋ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋ ์๊ฒ ์ชผ๊ฐ์ ธ ์๋ค. ํ๋์ ๋ฐ์ดํฐ๋ ์ฌ๋ฌ ๊ฐ์ ์ธ๊ทธ๋จผํธ ํ์ผ ์กฐ๊ฐ์ผ๋ก ๋๋์ด์ ์ ์ฅ๋๋ค.
์ ์ธ์ ์ธ๊ทธ๋จผํธ๋ก ๋๋๊น?
=> ๊ด๋ฆฌ์ ํจ์จ์ฑ ๋๋ฌธ์ด๊ณ ํ์ฌ ์ฌ์ฉ ์ค์ธ ์ธ๊ทธ๋จผํธ(ํ์ฑ ์ธ๊ทธ๋จผํธ)์ ํฌ๊ธฐ๊ฐ ํน์ ์๊ณ๊ฐ์ ๋๋ฌํ์ ๋ ๋๋์ด์ง๋ค.
๊ทธ๋ผ ์ธ๊ทธ๋จผํธ ํ์ผ๋ค์ ์ด๋ค ๊ฑธ๋ก ๊ตฌ์ฑ๋์ด ์๋๊ฑธ๊น?
=> ๊ฐ ์ธ๊ทธ๋จผํธ๋ ๋จ์ํ ๋ฐ์ดํฐ ๋ฟ๋ง ์๋๋ผ ํจ์จ์ ์ธ ๊ฒ์๊ณผ ๊ด๋ฆฌ๋ฅผ ์ํด ์ธ ๊ฐ์ง ์ข ๋ฅ์ ํ์ผ๋ก ๊ตฌ์ฑ๋๋ค.
- .log : ์ค์ ๋ฉ์์ง ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ ๊ณณ(๋ฉ์์ง offset, timestamp, key, value, header ๋ฑ)
- .index : ๋ชจ๋ offset ์ ๋ณด๊ฐ ์๋ ์ผ์ ํ ๊ฐ๊ฒฉ๋ง๋ค ์๋ offset๊ณผ ํด๋น ๋ฉ์์ง๊ฐ .log ํ์ผ ๋ด์ ์ ์ฅ๋ ๋ฌผ๋ฆฌ์ ์์น๋ฅผ ๋งคํํ ์ ๋ณด๋ง ๋๋ฌธ๋๋ฌธ ์ ์ฅํ๋ค.
- .timeIndex : ์๊ฐ ๊ธฐ๋ฐ ๊ฒ์์ ํจ์จํํ๊ธฐ ์ํจ. ๋ฉ์์ง timestamp์ ๊ทธ ์์ ์ offset์ ๋งคํํ๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ค.
DumpLogSegments๋?
์ฑ๋ฅ ํฅ์์ ์ํด ์ฌ๋ฌ ๋ฉ์์ง๋ฅผ ๋ฌถ์ด batch ๋จ์๋ก ์ ์ฅํ๋ค. .log file์ ์ค์ ๋ฉ์์ง ๋ฐ์ดํฐ๊ฐ ์์ฐจ์ ์ผ๋ก batch ๋จ์๋ก ์์ธ๋ค.
๊ทธ๋ ๋ค๋ฉด ํน์ ๋ฒํธ์ ๋ฉ์์ง๋ฅผ ์ฐพ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
=> index ํ์ผ์์ targetOffset ์ดํ์ ๊ฐ์ฅ ํฐ ์คํ์ ์ ์ด์ง ํ์์ผ๋ก ์ฐพ๊ณ , ๊ฑฐ๊ธฐ ์ ํ position์ผ๋ก .log๋ฅผ ํ์ํ ๋ค ์์ผ๋ก ์์ฐจ ์ค์บํด์ targetOffset ๋ ์ฝ๋์ ๋๋ฌํ๋ฉด ์ฝ๋๋ค.
์ธ๋ฑ์ค๋ฅผ ๋๋ฌด ๋๋ฌผ๊ฒ ํ๋ฉด ๊ฒ์ ์๋๊ฐ ๋๋ ค์ง๊ณ , ์ธ๋ฑ์ค๋ฅผ ๋ง์ด ์ค์ ํ๋ฉด ์ ์ฅ๊ณผ ์บ์ ๋น์ฉ๊ณผ ๋ถํ๋ผ๋ ํธ๋ ์ด๋ ์คํ๊ฐ ์๋ค. ์๋น์ค ์ํฉ์ ๋ง๊ฒ ์กฐ์ ํ์!
์ด๋ ๋ฏ ์นดํ์นด๋ ๋์คํฌ ๊ธฐ๋ฐ์์๋ ๋ถ๊ตฌํ๊ณ ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ๋งค์ฐ ํจ์จ์ ์ด๊ณ ๋น ๋ฅด๊ฒ ์ฝ์ ์ ์๋ ๊ฒ์ด๋ค!
KRaft ํ๋กํ ์ฝ
Kafka๋ ์ค๋ซ๋์ Zookeeper ๋ฅผ ์ด์ฉํ๋ค. ํด๋ฌ์คํฐ์ ์ค์ํ ์ ๋ณด(๋ฉํ๋ฐ์ดํฐ๋ค(topic ์ ๋ณด Broker ์ํ ๋ฑ))๋ฅผ ๊ด๋ฆฌํ๊ณ ํํฐ์ ๋ง๋ค ๋ฆฌ๋๋ฅผ ๋ฝ๋ ์ญํ ์ Zookeeper์๊ฒ ๋งก๊ฒผ๋ค.
ํ์ง๋ง ์ด๋ฐ ์ธ๋ถ์์คํ ์ ์์กด์ฑ์์ ๋ฒ์ด๋๊ณ ์ ๋ง๋ค์ด์ง ๊ฒ์ด KRaft์ด๋ค.
์นดํ์นด๊ฐ ์์ฒด์ ์ผ๋ก Raft ํฉ์ ์๊ณ ๋ฆฌ์ฆ ์ ์ฌ์ฉํด์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋๋ก ๋ง๋ ๊ฒ์ด๋ค. ๊ฐ์ฅ ํฐ ์ฅ์ ์ผ๋ก, ์ด์์ด ํจ์ฌ ๋จ์ํด์ก๊ณ , ์ ์ฌ์ ๋ณ๋ชฉ ํ์์ด๋, ์ธ๋ถ ์์คํ ๊ณผ์ ์ํ ๋ถ์ผ์น ๋ฌธ์ ๊ฐ ๊ทผ๋ณธ์ ์ผ๋ก ํด๊ฒฐ๋ ์ ์ด๋ค.
Raft ํฉ์ ์๊ณ ๋ฆฌ์ฆ์ด๋?
๋ถ์ฐ ์์คํ ์์ ์ฌ๋ฌ ๋ ธ๋๋ค์ด ์ด๋ป๊ฒ ํฉ์๋ฅผ ๋ณด๋์ง์ ๋ํ ๊ตฌ์ฒด์ ์ธ ๋ฐฉ๋ฒ๋ก ์ผ๋ก ๋ณด๋ฉด ๋๋ค.
ํฌ๊ฒ ๋ค์๊ณผ ๊ฐ์ 3๊ฐ์ง ๋ฌธ์ ๋ก ๋๋์ด์ ํด๊ฒฐํ๋ค.
- ๋ฆฌ๋ ์ ์ถ(Leader Election): ์ฌ๋ฌ ๋ ธ๋ ์ค์์ ๋๊ฐ ๋ฆฌ๋ ์ญํ ์ ํ ์ง ๋ฏผ์ฃผ์ ์ผ๋ก ์ ํ๋ ๊ณผ์ .
- ๋ก๊ทธ ๋ณต์ (Log Replication): ๋ฆฌ๋๊ฐ ์ ํด์ง ํ, ํด๋ฌ์คํฐ์ ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ(์๋ก์ด topic์ ๋ง๋ ๋ค๊ฑฐ๋ ์ค์ ์ ๋ฐ๊พธ๋ ๋ฑ)์ ๋ฐ๋์ ๋ฆฌ๋๋ฅผ ํตํด์๋ง ์ฒ๋ฆฌ๋๋ค. ๋ฆฌ๋๋ ์ด ๋ณ๊ฒฝ ์์ฒญ์ ๋ฐ์ผ๋ฉด ๋จผ์ ์์ ์ ๋ก๊ทธ์ ์์๋๋ก ๊ธฐ๋กํ๋ค. ์ดํ, ๋ค๋ฅธ ๋ ธ๋๋ค์๊ฒ ๋ก๊ทธ์ ์ ์ผ๋ผ๊ณ ์ ๋ฌํ๋ค.
- ์์ ์ฑ ๊ท์น(Safety Rule): ์์คํ ์ด ์ด๋ค ์์ธ์ ์ธ ์ํฉ์์๋ ์ด์ํ๊ฒ ๋์๊ฐ์ง ์๋๋ก ์ฌ๋ฌ ์์ ์ฅ์น๋ฅผ ๋ง๋ จํด๋๋ค.
๊ทธ๋ฌ๋ฉด ์นดํ์นด ํด๋ฌ์คํฐ์์ ์ด๋ค ๋ ธ๋๋ค์ด KRaft๋ฅผ ์ํํ ๊น?
๋ชจ๋ Broker๊ฐ ์ฐธ์ฌํ๋ ๊ฒ ์๋, KRaft ๋ชจ๋์์๋ ๋ชจ๋์ ์ญํ ์ ์ค์ ํ์ผ(process.roles)์์ ์ง์ ํ ์ ์๋ค. ์ผ๋ถ ๋ ธ๋๋ ์ปจํธ๋กค๋ฌ ์ญํ ๋ก ํน๋ณํ ์ง์ ํ๋ค.
์ปจํธ๋กค๋ฌ ๋ ธ๋๋ค์ด ๋ชจ์ฌ Quorum ์ด๋ฃธ => Raft ํ๋กํ ์ฝ์ ๋ฐ๋ผ ํ์ฑ ์ปจํธ๋กค๋ฌ ์ ์ถ
์ฌ๊ธฐ์ ๋ฆฌ๋๋ก ์ ์ถ๋ ํ๋์ ๋ ธ๋๋ ํ์ฑ ์ปจํธ๋กค๋ฌ ๊ฐ ๋๋ค.
์ผ๋ฐ Broker ๋ ธ๋๋ค์ ํ์ฑ ์ปจํธ๋กค๋ฌ๋ถํฐ ์ต์ข ์ ์ผ๋ก ํ์ ๋ ๋ฉํ๋ฐ์ดํฐ ๋ก๊ทธ๋ฅผ ๋ฐ์ ์์ ์ ์ํ๋ฅผ ์ต์ ์ผ๋ก ์ ์งํ๋ค.
Kraft์์๋ ์ต์๋ฒ ์ญํ ์ ํ๋ Broker ๋ ธ๋๋ ํ๋ก์ ์ํ์ธ ์ปจํธ๋กค๋ฌ ๋ ธ๋๊ฐ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐํํ ๋ pull ๊ธฐ๋ฐ ๋ณต์ ๋ฐฉ์ ์ ์ฌ์ฉํ๋ค.
์ฌ๊ธฐ์ pull ๋ฐฉ์์ด๋?
Broker๋ ํ๋ก์ ์ปจํธ๋กค๋ฌ๊ฐ ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ฑ ์ปจํธ๋กค๋ฌ์๊ฒ fetch RPC ๋ผ๋ ์์ฒญ์ ๋ณด๋ธ๋ค. ๊ฐ๋จํ ๋งํด์ โ๋ก๊ทธ ์ง๊ธ ์ฌ๊ธฐ๊น์ง ๋ฐ์๋๋ฐ ํน์ ์ต์ ๋ฉํ๋ฐ์ดํฐ ๋์จ ๊ฑฐ ์์ ์ฃผ์ธ์~โํ๊ณ ๋ฌผ์ด๋ณด๋ ๊ฒ! ๊ทธ๋ฌ๋ฉด ํ์ฑ ์ปจํธ๋กค๋ฌ๊ฐ ์๋ต์ ํด์ค๋ค.
๋์ Quorum ๊ด๋ฆฌ ์ง์
Kraft๋ ๋์ Quorum ๊ด๋ฆฌ ์ง์ํ๊ธฐ ๋๋ฌธ์ ์นดํ์นด ์๋น์ค๋ฅผ ์ค๋จํ์ง ์๊ณ ๋ ์ปจํธ๋กค๋ฌ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค. ํ ๋ฒ์ ํ๋์ฉ๋ง ๊ฐ๋ฅํ๋ค! Quorum์ด ๋ ์ด์์ผ๋ก ์ชผ๊ฐ์ ธ์ ์๋ก ๋ค๋ฅธ ๋ฆฌ๋๋ฅผ ์ ์ถํ๊ฒ ๋๋ ๋ฌธ์ (split brain)๋ฅผ ๋ฐฉ์งํด์ผ ํ๋ค!
๋๋์ : ๋ฐฉ๋ํ๋ค..! ์นดํ์นด์ ๋ํด ์ด๋ ๊ฒ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์ดํดํด ๋ณผ ์ ์์ด์ ๋งค์ฐ ์ ์ตํ๋ค. ์์์ ์ด๋ฃจ์ด์ง๋ ์๋ฆฌ๋ค์ด ์ ๋ง ์ธ์ธํ๊ฒ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ ์ด๋ฃจ์ด์ ธ ์๋ค๋ ๊ฒ์ ๋ณผ ์ ์์๋ค.
๐ https://rohithsankepally.github.io/Kafka-Storage-Internals/
๐ https://developers.redhat.com/articles/2025/09/17/deep-dive-apache-kafkas-kraft-protocol