[์นํ์] 11/14 ๊ฐ๋ฐ์ผ์ง ์ฟ ํฐ ๋ฐ๊ธ ์ ๋์์ฑ ๋ฌธ์ ํด๊ฒฐ 2 : ๋น๊ด์ ๋ฝ, ๋ถ์ฐ ๋ฝ ( Redisson ), Redis, Lua Script ์ ์ฉ ๋ฐ ์์ฌ๊ฒฐ์
๐ก ์ด์ ๊ธ
https://hanstory33.tistory.com/262
[์นํ์] 11/13 ๊ฐ๋ฐ์ผ์ง ์ฟ ํฐ ๋ฐ๊ธ ์ ๋์์ฑ ๋ฌธ์ ํด๊ฒฐ 1 : ๋์์ฑ ๋ฌธ์ ๋ฐ์ ๋ฐ ๋๊ด์ , ๋น๊ด์ ,
๐ก ๋ชฉํ์ฟ ํฐ 300 ๊ฐ๋ฅผ ์ ์ 1000 ๋ช ์ด 5์ด๋์ ๋ฐ๊ธ์ ๋ฐ๊ธฐ ์ํด ํ ์คํธ๋ฅผ ์งํํ๋๋ฐ, ์ค๋ณต๋ ์ฟ ํฐ์ด ๋ฐ๊ธ๋๋ค๋ ์ง, ์๋ 300 ๊ฐ๋ฅผ ๋์ด์์ ๋ฐ๊ธ์ด ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์
hanstory33.tistory.com
๐ก ๋ชฉํ
๋น๊ด์ ๋ฝ๊ณผ ๋ถ์ฐ ์บ์ ์์คํ ์ธ Redisson ์ ์ด์ฉํ ๋ถ์ฐ๋ฝ์ ๊ฑธ์ด ๊ธฐ์กด์ ๋ฝ์ ๊ฑธ์ง ์์๋ ๋ฐฉ์๊ณผ ๋น๊ตํด Test ๋ฅผ ์งํ.
+ python script ๋ฅผ ํ์ฉํด ์ด ๋ฐ๊ธ๋ ์ฟ ํฐ ์์ ์ค๋ณต๋ ์ฟ ํฐ ์ฝ๋๋ฅผ ํ์ธ
๐ Test : DB ๋๊ด์ ๋ฝ ( Skip )
๋งค ๋ฐ๊ธ ๋ง๋ค ์ฟ ํฐ์ ์ํ๋ฅผ ๋ณ๊ฒฝํด์ผํ๋ ์ง๊ธ ์ํฉ์์๋ ์ถฉ๋ ๋ฐ์ ์ ๋งค ๋ฒ ์ฌ์๋๋ฅผ ํด์ผํ๋ ๋๊ด์ ๋ฝ์ ์ ํฉํ์ง ์๋ค๊ณ ํ๋จ
๐ Test : DB ๋น๊ด์ ๋ฝ
- ๊ฐ๋ ฅํ ๋ฝ์ ๊ฑธ๊ธฐ ์ํด์ ์ฑ๋ฅ์ ์ํด๋ฅผ ๋ณด๋๋ผ๋ ๋น๊ด์ ๋ฝ์ ํตํด ํ ์คํธ ์งํ
- Number of Threads (users) : 1000
- Ramp-up period (seconds) : 5
- Loop Count : 1
- ๋ฐ๊ธํ ์ ํจ ์ฟ ํฐ ์ : 300
- ์ค์ ์ฟ ํฐ์ ๋ฐ๊ธ๋ฐ์ ์ ์ ์ : 300
@Lock(LockModeType.PESSIMISTIC_WRITE)
300 ๊ฐ์ ์ฟ ํฐ์ด ๋ฐ๊ธ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋์์ฑ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํ๊ท ์๋ต ์๋ 1609 ms ๊ฐ ๋์๊ณ , ์ด๋น ์ฒ๋ฆฌ์์ 174.7 ๊ฑด์ผ๋ก ์์ ์ ์ธ ๊ฐ์ด ๋์๋ค.
๐ ๊ฒฐ๋ก
๊ธฐ์กด์ ๋ฝ์ ๊ฑธ๊ธฐ ์ ์ ํ๊ท ์๋ต ์๋๊ฐ 171 ms ์๋ ๊ฒ์ ๋นํด ํ๊ท ์๋ต์๋๊ฐ 1609 ms ์ฑ๋ฅ์ ์ผ๋ก ์ฝ 841% ๊ฐ์๋์ง๋ง, ๋์์ฑ ๋ฌธ์ ๋ ํ์คํ๊ฒ ํด๊ฒฐ๋ ๊ฒ์ ์ ์ ์์๋ค.
๐ Test : ๋ถ์ฐ ๋ฝ - Redisson
- ๊ธฐ์กด CouponService ํธ๋์ญ์ ์ CouponLockService ๋ก Rapping ํด์ Redisson ์ ํ์ฉํด ๋ฝ์ ๋ง๋ค๊ณ ํด์ ํ๋ค.
- ๋์์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด์ ๋ฝ ํ๋ ์๋ ์๊ฐ๊ณผ ๋ฝ ์ ์ง ์๊ฐ์ ์ง์ ํด์คฌ๋ค.
- ์๊ฐ์ ์ง์ ํ๋ค๋ณด๋ ์ฑ๋ฅ์ ์ผ๋ก ์ด๋ ์ ๋ ์ํด๋ฅผ ๋ณผ ์ ๋ฐ์ ์์๋ค.
- ๋ด ์ปดํจํฐ๋ก ํ ์คํธ๋ฅผ ํ์ ๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด์ ์ฒ๋ฆฌํ ์ ์๋ ์ต์ ์๊ฐ ์ค์ ์ด์๋ค.
// ๋ฝ ํ๋ ์๋ ์๊ฐ 2์ด, ๋ฝ ์ ์ง ์๊ฐ 3์ด
boolean isLocked = lock.tryLock(2, 3, TimeUnit.SECONDS);
- Number of Threads (users) : 1000
- Ramp-up period (seconds) : 5
- Loop Count : 1
- ๋ฐ๊ธํ ์ ํจ ์ฟ ํฐ ์ : 300
- ์ค์ ์ฟ ํฐ์ ๋ฐ๊ธ๋ฐ์ ์ ์ ์ : 300
๐ ๊ฒฐ๋ก
Redisson ์ ํ์ฉํด ๋ถ์ฐ ๋ฝ์ ํ ์คํธ ํด๋ณด์๋๋ฐ, ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฝ ํ๋ ์๋ ์๊ฐ๊ณผ ๋ฝ ์ ์ง ์๊ฐ์ ์ค์ ํ๋ ๊ณผ์ ์์ ์ปดํจํฐ ์ฑ๋ฅ ์ด์๋ก ๊ณผํ๊ฒ ์ค์ ์ด ๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
๊ทธ ๋๋ฌธ์ ํ๊ท ์๋ต์๋๊ฐ 2870 ms ๋ผ๋ ๋ค์ ์์ฌ์ด ๊ฒฐ๊ณผ๊ฐ ๋์๋ค.
Redis ํ๊ฒฝ์์ ๋ฐ์ดํฐ๊ฐ ์ฃผ๊ณ ๋ฐ์์ง๊ธฐ ๋๋ฌธ์ ๋ ๋น ๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋์์ด์ผํ๋ค๊ณ ์๊ฐํ๋ค.
์ดํ ์ถ๊ฐ๋ก ์ด ๊ณผ์ ์ ๋ ํ ์คํธ ํด๋ณผ ์์ ์ด๋ค.
๐ Test : Redis ์ ์ฉ (๋ฝX)
- ๋ฝ์ ๊ฑธ๋ฉด ์ฑ๋ฅ์ด ๋ง์ด ์ ์ข์์ ธ์ ๋ฝ์ ๊ฑธ์ง ์๊ณ Redis ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํ
์คํธ ํด๋ณด์๋ค.
- Redis ๋ ์ฑ๊ธ ์ค๋ ๋ ๋ชจ๋ธ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ์์ฒญ์ด ๋์์ ์ค๋๋ผ๋ ๊ฐ ์์ฒญ์ด ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌ๋ ๊ฒ์ด๋ผ ์์ํ๊ณ Redis ๋ก๋ง ํ
์คํธ ์งํํ๋ค.
- Number of Threads (users) : 1000
- Ramp-up period (seconds) : 5 / 10 / 15 / 20
- Loop Count : 1
- ๋ฐ๊ธํ ์ ํจ ์ฟ ํฐ ์ : 300
- ์ค์ ์ฟ ํฐ์ ๋ฐ๊ธ๋ฐ์ ์ ์ ์ : 440 / 400 / 320 / 305
๊ธฐ์กด๊ณผ ๋์ผํ๊ฒ 1000 ๋ช ์ ์ ์ ๊ฐ 5์ด ๋์ ์์ฒญ์ ๋ณด๋ด๋๋ก ํ๋๊น ๋์์ฑ ๋ฌธ์ ๊ฐ ์ฌํ๊ฒ ๋ฐ์ํ๋ค.
์์ธ ๋ถ์ : ์์์ฑ ๋ณด์ฅ ๋ถ์กฑ
Redis๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ช ๋ น์ด๊ฐ ์์์ ์ผ๋ก ์ฒ๋ฆฌ๋์ง๋ง, ๋ณต์กํ ํธ๋์ญ์ ์ด๋ ๋ค์์ ๋ช ๋ น์ด๊ฐ ๊ฒฐํฉ๋ ์์ ์ ๋ํด์๋ ์์์ฑ์ด ๋ณด์ฅ๋์ง ์๋๋ค.
- ์ฟ ํฐ์ ์์ฌ ์๋์ ํ์ธ.
- ์๋์ด ๋จ์์์ผ๋ฉด ์ฟ ํฐ์ ๋ฐ๊ธ.
- ๋ฐ๊ธ๋ ์ฟ ํฐ ์๋์ ์ ๋ฐ์ดํธ
ํ์ฌ ์์ ๊ฐ์ ๋ก์ง์ผ๋ก ์ค๋ณต ๋ฐ๊ธ์ด ๋ฐ์ํ ์ ์๋ค.
์ ๊ทธ๋ํ๋ฅผ ๋ณด๋ค์ํผ 1000๋ช ์ ์ ์ ๊ฐ 20 ์ด ๋์ 300๊ฐ์ ์ฟ ํฐ๋ฐ๊ธ์ ์๋ํ๋ค๊ณ ๊ฐ์ ํ์ ๋ ๋ถํฐ ๋์์ฑ ๋ฌธ์ ๊ฐ ๊ฑฐ์ ํด๊ฒฐ๋์๋ค.
๐ ๊ฒฐ๋ก
redis ๋ฅผ ํ์ฉํด ํ๊ท ์๋ต์๋๊ฐ 8ms ๋ก ๋ํญ ์์นํ๋ค.
์ฑ๋ฅ์ ์ธ ๋ถ๋ถ์์ ๊ธฐ์กด ๋ฝ์ ๊ฑธ์์ ๋ ๋ณด๋ค Redis ๋ง ์ฌ์ฉํ์ ๋ ์๋ฑํ ์ฆ๊ฐํ๋๋ฐ, ๋์์ฑ ๋ฌธ์ ๋ถ๋ถ์์ ๋์ ์ฒ๋ฆฌ๋์ ๋ณด์ฌ์ฃผ์ง๋ ๋ชปํ๋ค.
๐ Test : Lua Script ์ ์ฉ
- Redis ์ Lua Script ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๋ช ๋ น์ ํ๋์ ์์์ ์์ ์ผ๋ก ๋ฌถ์ด ์คํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฟ ํฐ ๋ฐ๊ธ ๋ฉ์๋์์ ์คํ๋๋ ์ฝ๋๋ค์ Lua Script ๋ฅผ ์์ฑํ์ฌ ํธ๋์ญ์ ์ฒ๋ผ ์ฒ๋ฆฌํ ์ ์๋ค.
- Lua Script ๋ฅผ ์ฌ์ฉํด Redis ์ ์ฑ๋ฅ์ ์ธ ์ด์ ๊ณผ ๋์์ฑ ๋ฌธ์ ๋ฅผ ๋ ๋ค ํด๊ฒฐํ ์ ์์ ๊ฒ์ด๋ผ ์์๋์ด ํ ์คํธ๋ฅผ ์งํํ๋ค.
- Number of Threads (users) : 1000
- Ramp-up period (seconds) : 5
- Loop Count : 1
- ๋ฐ๊ธํ ์ ํจ ์ฟ ํฐ ์ : 300
- ์ค์ ์ฟ ํฐ์ ๋ฐ๊ธ๋ฐ์ ์ ์ ์ : 300
๐ ๊ฒฐ๋ก
Redis์ Lua ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฉํ ๊ฒฐ๊ณผ, ํ๊ท ์๋ต ์๋๊ฐ 16ms์ ๋๋ฌํ์ฌ, Redis์ ๊ธฐ๋ณธ ์ฌ์ฉ์์ ํ์ธ๋ ์ฑ๋ฅ๊ณผ ๊ฑฐ์ ๋์ผํ ๋์ ํผํฌ๋จผ์ค๋ฅผ ์ ์งํ๋ค.
์ด๋ ๋จ์ํ ์ฑ๋ฅ ํฅ์์ ๊ทธ์น์ง ์๊ณ , ๋์์ฑ ๋ฌธ์ ๊น์ง ์๋ฒฝํ๊ฒ ํด๊ฒฐํ๋ค.
Redis Lua ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฉํด ํจ์จ์ ์ธ ์ฒ๋ฆฌ ์๋๋ฅผ ์ ๊ณตํ ๋ฟ ์๋๋ผ, ์ฌ๋ฌ ์์ฒญ์ด ๋ชฐ๋ฆด ๋๋ ์์ ์ ์ธ ์ฑ๋ฅ์ ์ ์งํ ์ ์๋๋ก ๋์์ฑ ๊ด๋ฆฌ๋ฅผ ๊ฐํํ๋ค.
์ด๋ฅผ ํตํด Redis๋ ๋๊ท๋ชจ ํธ๋ํฝ ํ๊ฒฝ์์๋ ๋์ ์ฒ๋ฆฌ๋๊ณผ ์์ ์ฑ์ ๋ณด์ฅํ๋ฉฐ, ํนํ ๋ฏธ์ ํฌ๋ฆฌํฐ์ปฌํ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ํ์คํ ์ ๋ขฐ์ฑ์ ์ ๊ณตํ๋ค.
๐ก ์ต์ข ์์ฌ ๊ฒฐ์
- ๊ทธ๋ํ๋ก ํ์ธํ ์ ์๋ฏ์ด ๋์์ฑ ๋ฌธ์ ๋ฅผ ์๋ฒฝํ๊ฒ ํด๊ฒฐํ ์ธ ๊ฐ์ง ๋ฐฉ๋ฒ์ DB ๋น๊ด์ ๋ฝ, Redisson์ ํ์ฉํ ๋ถ์ฐ ๋ฝ, ๊ทธ๋ฆฌ๊ณ Lua Script ํ์ฉ์ด๋ค.
- ์ด ์ค์์ Lua Script๋ฅผ ํ์ฉํ ๋ฐฉ์์ด ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด์๋ ๊ฐ์ฅ ๋น ๋ฅธ ์๋ต ์๋๋ฅผ ๋ณด์๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ์ด์์ ์ด๋ผ๊ณ ํ ์ ์๋ค.
- ์ค์ ๋ก, ๋น๊ด์ ๋ฝ ๋ฐฉ์์์ 1609ms์ ์๋ต ์๊ฐ์ด ์์๋์๋ ๊ฒ์ ๋นํด, Lua Script๋ฅผ ํ์ฉํ ํ์๋ 16ms๋ก ์ฑ๋ฅ์ด ๋ํญ ํฅ์๋์๋ค.