1. ๋ถ์ฐ๋ฝ์ ์ ์ฉํ๊ฒ ๋ ์ํฉ
๋ง์ฝ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ๊ฐ์ ์๊ฐ๋์ด๊ฑฐ๋ ๊ฒน์น๋ ์๊ฐ๋์ ์์ฝ ์งํ ์ ์ด๋ป๊ฒ ์ค๋ณต ์์ฝ์ ๋ง์ ์ ์์์ง ๋ฌธ์ ์๋ค.
ํด๋น ์์ฝ ํ ์ด๋ธ์ ์๋์ ๊ฐ์ด ์์ฑ ๋์ด์๋ค. ํ๋์ ํ์ ํ ์ด๋ธ์ ์ด๋ฏธ ์์ฝ๋ ๋ฐ์ดํฐ์ ์๊ฐ์ด ๊ฒน์น์ง ์์์ผ๋ง ์์ฝ์ด ๊ฐ๋ฅํ๋ค.
๋์์ 100๋ช ์ ์ฌ์ฉ์๊ฐ ๋๊ฐ์ (์๊ฐ + ์ฅ์)๋ฅผ ์์ฝํ์ ๋ 8๊ฐ์ ์ค๋ณต ๋ฐ์ดํฐ๊ฐ ๋ฐ์ํ์๋ค.
2. MySQL์ ์ด์ฉํ ๋ถ์ฐ๋ฝ์ ๊ตฌํํ ์ด์
๋ถ์ฐ๋ฝ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๊ฒ์ํด๋ณด๋ฉด Redis๋ฅผ ์ด์ฉํ ๋ฐฉ๋ฒ์ด ๋ง์ด ๋ณด์ธ๋ค.
ํ์ง๋ง Redis๋ฅผ ์ด์ฉํ๊ฒ ๋๋ฉด ์ถ๊ฐ์ ์ธ ์ธํ๋ผ ๊ตฌ์ถ๋น์ฉ์ด๋ ์ ์ง๋ณด์ ๋น์ฉ์ด ๋ฐ์ํ๋ค.
๋ฐ๋ผ์, ๋๋ ๊ธฐ์กด์ ์ฌ์ฉํ๊ณ ์๋ MySQL์์ ์ ๊ณตํ๋ NAMED LOCK์ ์ด์ฉํ์ฌ Lock์ ์ด๋ฆ์ ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ํด๋น Lock์ ์ด๋ฆ์ ์ด์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ๋จ์์ ์ ์ด๊ฐ ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ ์ด์ฉํ๊ธฐ๋ก ํ๋ค.
3. Named Lock์ ๋ํ ๊ฐ๋จ ์ค๋ช
Named Lock์ ์ด๋ฆ์ ๊ฐ์ง metadata lock์ด๋ผ๊ณ ํ ์ ์๋ค. ์ด๋ฆ์ ๊ฐ์ง lock์ ํ๋ํ ํ ํด์ ํ ๋๊น์ง ๋ค๋ฅธ ์ธ์ ์ ์ด Lock์ ํ๋ํ ์ ์๋๋ก ํ๋ค. ๋ฐ์ดํฐ ์ฝ์ ์์ ์ ํฉ์ฑ์ ๋ง์ถฐ์ผ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
โ ์ฃผ์ํ ์ ์ผ๋ก๋ transaction์ด ์ข ๋ฃ๋ ๋ lock์ด ์๋์ผ๋ก ํด์ ๋์ง ์๋๋ค๋ ๊ฒ์ด๋ค. ๋ณ๋์ ๋ช ๋ น์ด๋ก ํด์ ๋ฅผ ์ํํด ์ฃผ๊ฑฐ๋ ์ ์ ์๊ฐ์ด ๋๋์ผ ํด์ ๋๋ค.
- ์ด๋ฆ๊ณผ ํจ๊ป lock์ ํ๋ํ๋ค. ํด๋น lock ์ ๋ค๋ฅธ ์ธ์ ์์ ํ๋ ๋ฐ ํด์ ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
- mysql์์๋ get_lock()์ ํตํด lock์ ์ป๊ณ , release_lock()์ด๋ผ๋ ๋ช ๋ น์ด๋ฅผ ํตํด named lock์ ํด์ ํ ์ ์๋ค.
- Pessimistic, Optimistic lock์ item์ ๋ํด์ lock์ ๊ฑธ์๋ค๋ฉด named Lock์ ๋ณ๋ MySQL ์๋ฒ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ lock์ ๊ฑด๋ค.
GET_LOCK(name, timeout)
- ์ ๋ ฅ๋ฐ์ ์ด๋ฆ์ผ๋ก timeout์ด ๋์ ์ ๊ธ ํ๋์ ์๋ํ๋ค.
- ๋ง์ฝ์๋ผ๋ ์ ๊ธ์ ํ๋ํ ๋๊น์ง ๋ฌดํ๋๋ก ๋๊ธฐํ๋๋ก ํ๋ ค๋ฉด timeout์ ์์๋ก ์ค์ ํ๋ฉด ๋๋ค.
- ํ session์์ ์ ๊ธ์ ์ ์งํ๊ณ ์๋ ๋์์๋ ๋ค๋ฅธ session์์ ๋์ผํ ์ด๋ฆ์ ์ ๊ธ์ ํ๋ํ ์ ์๋ค.
- GET_LOCK()์ ์ด์ฉํ์ฌ ํ๋ํ ์ ๊ธ์ Transaction์ด commit ๋๋ rollback ๋๋๋ผ๋ ์ค์ค๋ก ํด์ ๋์ง ์๋๋ค.
- GET_LOCK์ ๊ฒฐ๊ณผ๊ฐ์ 1, 0, null์ ๋ฐํํ๋ค.
- 1 : ์ ๊ธ์ ํ๋ํ๋๋ฐ ์ฑ๊ณต
- 0 : timeout ์ด ๋์ ์ ๊ธ ํ๋ ์คํจ
- null : ์ ๊ธ ํ๋ ์ค ์๋ฌ๊ฐ ๋ฐ์ (ex : Out of Memory, ํ์ฌ ์ค๋ ๋๊ฐ ๊ฐ์ ์ข ๋ฃ๋จ)
- MySQL 5.7 ๋ฒ์ ์ดํ๋ถํฐ๋ ๋์์ ์ฌ๋ฌ๊ฐ์ ์ ๊ธ์ ํ๋ ๊ฐ๋ฅํ๊ณ , ์ ๊ธ ์ด๋ฆ ๊ธ์์๊ฐ 60์๋ก ์ ํ๋์์์ ์ ์ํ์.
RELEASE_LOCK(name)
- ์ ๋ ฅ๋ฐ์ ์ด๋ฆ์ ์ ๊ธ์ ํด์ ํ๋ค.
- RELEASE_LOCK์ ๊ฒฐ๊ณผ๊ฐ์ 1, 0, null์ ๋ฐํํ๋ค.
- 1 : ์ ๊ธ์ ์ฑ๊ณต์ ์ผ๋ก ํด์
- 0 : ์ ๊ธ์ด ํด์ ๋์ง๋ ์์์ง๋ง, ํ์ฌ ์ฐ๋ ๋์์ ํ๋ํ ์ ๊ธ์ด ์๋๊ฒฝ์ฐ
- null : ์ ๊ธ์ด ์กด์ฌํ์ง ์์
- RELEASE_ALL_LOCKS() ๋ช ๋ น์ ํตํด ํ์ฌ ์ธ์ ์์ ์ ์ง๋๊ณ ์๋ ๋ชจ๋ ์ ๊ธ์ ํด์ ํ๊ณ ํด์ ํ ์ ๊ธ ๊ฐ์๋ฅผ ๋ฐํ๋ฐ์ ์ ์๋ค.
ETC
- IS_FREE_LOCK(name)
- ์
๋ ฅํ ์ด๋ฆ์ ํด๋นํ๋ ์ ๊ธ์ด ํ๋ ๊ฐ๋ฅํ์ง ํ์ธํ๋ค.
- 1 : ์ ๋ ฅํ ์ด๋ฆ์ ์ ๊ธ์ด ์์
- 0 : ์ ๋ ฅํ ์ด๋ฆ์ ์ ๊ธ์ด ์์
- null: ์๋ฌ ๋ฐ์ (ex: ์๋ชป๋ ์ธ์)
- ์
๋ ฅํ ์ด๋ฆ์ ํด๋นํ๋ ์ ๊ธ์ด ํ๋ ๊ฐ๋ฅํ์ง ํ์ธํ๋ค.
- IS_USED_LOCK(name)
- ์ ๋ ฅํ ์ด๋ฆ์ ์ ๊ธ์ด ์ฌ์ฉ์ค์ธ์ง ํ์ธํ๋ค.
- ์ ๋ ฅ๋ฐ์ ์ด๋ฆ์ ์ ๊ธ์ด ์กด์ฌํ๋ฉด connection id๋ฅผ ๋ฐํํ๊ณ , ์์ผ๋ฉด null์ ๋ฐํํ๋ค.
4. ๋ถ์ฐ๋ฝ ๊ตฌํ
1. DataSource ๋ถ๋ฆฌ
Lock์ ์ป๊ธฐ ์ํ DataSource๋ฅผ ๋ถ๋ฆฌํจ์ผ๋ก์จ, Lock์ด ํ์ํ์ง ์์ ์์ฒญ๋ค์ ๋ํด์ ์ปค๋ฅ์
ํ์ ๋ณด์ฅํด์ค ์ ์๋ค.
์๋ํ๋ฉด, ์ปค๋ฅ์
ํ๋ง ๋ ๋๋ ค๋ดค์ Lock์ด ํ์ํ ์์ฒญ๋ค์๊ฒ ๋ชจ๋ ์ ์ ๋นํด๋ฒ๋ฆฐ๋ค๋ฉด Lock์ด ํ์ํ์ง ์์ ์์ฒญ๋ค์ ์ปค๋ฅ์
ํ์ ๋ฐํ๋๊ธฐ ๊น์ง ๋๊ธฐํด์ผ ํ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฏ๋ก ConnectionPool์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ค.
2. ๋ถ๋ฆฌ๋ Named Lock์ฉ DataSource๋ฅผ ์ด์ฉํ JDBC ๊ตฌํ
โ
JdbcTemplate์ ์ด์ฉํ์ง ์์ ์ด์ ๋?
JdbcTemplate์ ํน์ฑ์ GET_LOCK์ ์ํํ๋ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๊ณ ํธ๋์ญ์
์ด ์ข
๋ฃ๋๊ฒ ๋๋ฉด poll์์ ์ป์ด์จ Connection์ ๋ฐํํ๊ฒ ๋๋ค.
1. ๊ทธ๋์ RELEASE_LOCK์ ์คํํ ๋ GET_LOCK์ ์คํํ ๋์ ๋ค๋ฅธ Connection์ ์ป์ด์ค๋ ๋ฌธ์ ๊ฐ ์๊ธฐ์ LOCK์ ์ ๋๋ก ๋ฐํ ๋ชปํ ์๋ ์๋ค.
2. ๋ํ ๋์์ ๋์ผํ Lock ์ด๋ฆ์ผ๋ก ์์ฒญํ ๋ค๋ฅธ ์ค๋ ๋์์ GET_LOCK์์ ๋ฐํํ๋ Connection์ ํ๋ํ์ฌ ์ ๊ธ์ ํ์ด๋ฒ๋ฆด ์ํ๋ ์กด์ฌํ๋ค.
๋ฐ๋ผ์ ๋๋ ๋ถ๋ฆฌ๋ DataSource๋ฅผ ์ฃผ์ ๋ฐ์ JDBC๋ก ์ง์ ๊ตฌํํ์๋ค. JDBC๋ฅผ ์ด์ฉํด ์ง์ ๊ตฌํํ์๊ธฐ์ Connection์ ์ง์ ๊ด๋ฆฌํ ์ ์์ด์ GET_LOCK๊ณผ RELEASE_LOCK์ด ๋ชจ๋ ๋์ผํ Connection์ ์ฌ์ฉํ ์ ์์๊ณ ํ๋ํ LOCK์ ์ ์์ ์ผ๋ก ๋ฐํํ ์ ์๊ฒ ๊ฒ ๋์๋ค.
executeWithLock() ๋ฉ์๋์์๋ @Transactional์ ๋ถ์ด์ง ์์๋ค. ์๋ํ๋ฉด Lock์ ์ป๋ ๋ถ๋ถ๊ณผ ์์ฝ ๋ก์ง์ ์ํํ๋ ๋ถ๋ถ์์ ์ฌ์ฉํ๋ ConnectionPool์ ๊ฐ๊ธฐ ๋ค๋ฅด๊ฒ ํ๊ธฐ ์ํด @Transactional์ ๋ถ์ด์ง ์์๋ค.
ํ๋ฒ์ ํธ์ถ๋ก Lock์ ์ป๊ณ , Lock์ ํด์ ํ๋ ์์
์ ํ๊ธฐ ์ํด ์์ฝ ๋น์ง๋์ค ๋ก์ง์ Supplier ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํ ์ฝ๋ฐฑ์ผ๋ก ์ํ๋๋๋ก ๊ตฌํํ๋ค.
GET_LOCK๊ณผ RELEASE_LOCK์ 1, 0, null์ ๊ฐ์ ๋ฐํํ๋ค.
๋ฐ๋ผ์ getLock๊ณผ releaseLock ๋ฉ์๋์์ ๋ฐํ๊ฐ์ด 0, null์ธ ๊ฒฝ์ฐ๋ฅผ ์ฒดํฌํ์ฌ ์ ๊ธ์ด ํด์ ๋๋์ง๊น์ง ํ์ธํด์ผํ๊ณ , ์ ์ ํ โ
์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ค.
timeout ์๊ฐ์ ์งง๊ฒ ์ฃผ์์ ๊ฒฝ์ฐ๋ ๋ฝ์ด ํ๋ ค๋ฒ๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์๊ณ ์๊ฐ์ ๋๋ฌด ๊ธธ๊ฒ ์ฃผ๋ฉด release๋ฅผ ํ์ง ๋ชปํ์ ๊ฒฝ์ฐ ์๋น์ค์๋์ ํ๋ก ์ด์ด์ง ์ ์๋ค. ์ผ๋ฐ์ ์ผ๋ก 2~5์ด ์ฌ์ด๋ฉด ์ ๋นํ๋ค.
5. ๋์์ฑ ํ ์คํธ + TPS ์ธก์
1.Jmeter๋ฅผ ์ด์ฉํ ํ ์คํธ
์ด์์๋ฒ์ ๋ํด์ 100๋ช
์ด ๋์์ ์ค๋ณต ์์ฝํ๋ ์ํฉ์ ํ
์คํธํ๋ค.
ํ
์คํธ ํ ๊ฒฐ๊ณผ ํ๋์ ์์ฒญ๋ง ์ฑ๊ณตํ๊ณ ๋ค๋ฅธ ์์ฒญ๋ค์ ์คํจํจ์ผ๋ก์จ ๋์์ฑ ์ฒ๋ฆฌ๊ฐ ์๋์์์ ๋ณผ ์ ์์๋ค.
2. Junit์ ์ด์ฉํ ํ ์คํธ
์์ ๊ฐ์ด 100๋ช ์ด ๋์์ ์ค๋ณต๋๋ ์์ฝ์ ์์ฒญํ๋ ํ ์คํธ์์ 1๊ฐ์ ์์ฝ๋ง DB์ ์ฝ์ ๋์์์ ๋ณผ ์ ์์๋ค.