k6 ๋ Grafana ์ฌ์์ ์ ๊ณต๋๋ ํผํฌ๋จผ์ค ํ ์คํธ ํด์ ๋๋ค. k6 ๋ฅผ ์ด์ฉํ๋ฉด ๋ง์น ์ฌ๋ฌ ๋ช ์ ์ ์ ๊ฐ ์๋ ๊ฒ์ฒ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ํผํฌ๋จผ์ค ํ ์คํธ๋ฅผ ์งํํ ์ ์์ต๋๋ค.
Smoke Test, Load Test, Stress Test ๋ฑ ๋ค์ํ ํ ์คํธ๋ฅผ ์ฝ๊ฒ ์งํํ ์ ์๋๋ก ๋์์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ ๊ณต๋๊ธฐ ๋๋ฌธ์ ์ด๋ ต์ง ์๊ฒ ํ ์คํธ ์๋๋ฆฌ์ค๋ฅผ ์์ฑํ ์๋ ์์ฃ .
์๋๋ ์์ฃผ ๊ฐ๋จํ k6 ์คํฌ๋ฆฝํธ์ ๋๋ค.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 10,
duration: "10s",
}
export default function() {
http.get('http://test.k6.io');
sleep(1)
}
k6 run ๋ช ๋ น์ด๋ก ์คํํ๋ฉด ์๋์ ๊ฐ์ ํ ์คํธ ๋ฉํธ๋ฆญ์ ์ป์ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ "k6 ๋ฅผ ์์ํ๊ธฐ ์ ์ ์์๋๋ฉด ์ข์ ์ " ์ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์ ์ฝ๋์ ๋ํ ์ค๋ช ์ ์ถํ ๊ธ์์ ๋ค๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด๋ ๋ฏ ์ฝ๊ฒ ํผํฌ๋จผ์ค ํ ์คํธ๊ฐ ๊ฐ๋ฅํ ๊ฒ์ด k6 ์ ํฐ ์ฅ์ ์ ๋๋ค.
์๋ฅผ ๋ค์ด ์ฟ ๋ฒ๋คํฐ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ํ๋๋ฅผ ๋ฐฐํฌํ๋ค๊ณ ๊ฐ์ ํ์๋, ํ๋์ resources ๋ฅผ ์ง์ ํด์ค์ผ ํ๋๋ฐ ์ด๋ ์ ๋ ๊ฐ์ ์ค์ผ ํ๋ ์ง ๋ชจ๋ฅผ๋๊ฐ ์์ต๋๋ค. ์ด๋ k6 ์ Load Test ๋ฅผ ์งํํ๋ฉด ๋ณด๋ค ์์ํ๊ฒ ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ k6 ๋ฅผ ์ง์ ๋ค๋ฃจ๊ธฐ ๋ณด๋จ, k6 ๋ฅผ ์์ํ๊ธฐ ์ ์ ์์๋๋ฉด ์ข์ ์ ์ ๋ํด ๋งํด๋ณด๊ณ ์ ํฉ๋๋ค.
๊ทธ๋ผ ๋ ์ธ ๋๋์ฝ๋~
์ฃผ์ ์ฑ๋ฅ ์งํ
ํผํฌ๋จผ์ค ํ ์คํธ์ ๊ฒฐ๊ณผ๋ฅผ ๋ถ์ ํ ๋, ๋ฐ๋์ ์์์ผ ํ ์ฃผ์ ์ฑ๋ฅ ์งํ๊ฐ ์์ต๋๋ค.
Latency(์ง์ฐ์๊ฐ), Throughput(์ฒ๋ฆฌ๋), Iterations(๋ฐ๋ณต) ์ ๋๋ค.
์ด 3๊ฐ์ง ์งํ๋ "์๋น"์ ๋น์ ํ๋ฉด ์ฝ๊ฒ ์ดํดํ ์ ์์ต๋๋ค.
Latency
๋จผ์ Latency(์ง์ฐ์๊ฐ) ์ ๋๋ค.
๊ณ ๊ฐ์ด ๋ฐฐ๋ฌ ์ฑ์ ํตํด ์๋น์ ์์์ ์ฃผ๋ฌธํ๊ณ ๋ฌธ ์๊น์ง ๋์ฐฉํ๋ ์๊ฐ์ ๋น์ ํ ์ ์์ต๋๋ค.
์ฃผ๋ฌธํ๋๋ฐ 1๋ถ์ด ๊ฑธ๋ ธ๊ณ , ์๋ฆฌํ๋๋ฐ 10๋ถ, ๋ฐฐ๋ฌ ์ค๋๋ฐ 10๋ถ ์ด 21 ๋ถ์ด ์์๋์์ต๋๋ค. ์ด๋๋ 21 ๋ถ์ ์ง์ฐ์๊ฐ์ด ๊ฑธ๋ ธ๋ค๊ณ ํ ์ ์์ต๋๋ค.
์ด๋ ๋ฏ ์ธํฐ๋ท์์ ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๋ฐ๊ธฐ ์ ๊น์ง๋ฅผ ์ธก์ ํ ์งํ๊ฐ Latency ์ ๋๋ค.
๋น์ฐํ ์๊ธฐ์ง๋ง, Latency ๊ฐ ๋ฎ์์ผ ๊ณ ๊ฐ์ด ๋ ๋นจ๋ฆฌ ์์์ ๋จน์ ์๊ฐ ์์ต๋๋ค. ์์ ์นํจ๋ณด๋ค ๋ฐ๋ปํ ์นํจ์ด ํจ์ฌ ๋ง์๋ ๋ฒ์ด์ฃ . Latency ๊ฐ ๋๋ค๋ฉด ๊ณ ๊ฐ์ ๊ธฐ๋ค๋ฆฌ๋๋ฐ ์ง์ณ๋ฒ๋ฆด ๊ฒ์ด๊ณ , ๊ฒฐ์ฝ ์ข์ ๊ธฐ์ต์ด ๋ ์ ์์ ๊ฒ์ ๋๋ค.
Throuput
Throuput(์ฒ๋ฆฌ๋) ์ ๋๋ค.
์ด๋ฒ์ ํ ์๋น์ 100 ๋ช ์ ๊ณ ๊ฐ์ด ์จ์ดํ ํ๊ณ ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค. Throuput ์ ์๋น์ด 1์๊ฐ ๋์ 100 ๋ช ์ ๊ณ ๊ฐ์๊ฒ ์์์ ๋์ ํ ์ ์๋์ง์ ๋น์ ํ ์ ์์ต๋๋ค.
์๋น์ด ๋์ Throuput ์ ๊ฐ์ก๋ค๋ฉด, 1์๊ฐ ๋์ 100 ๋ช ์ ๊ณ ๊ฐ์๊ฒ ๋ชจ๋ ์์์ ๋์ ํ ์ ์์ ๊ฒ์ด๊ณ , ๋ฎ์ Throuput ์ ๊ฐ์ก๋ค๋ฉด ๊ณ ๊ฐ๋ค์ ๋ ๋ง์ ์๊ฐ์ ๊ธฐ๋ค๋ ค์ผ ํ ๊ฒ์ ๋๋ค.
๋น์ฐํ ๋์ Throuput ์ ๊ฐ์ ธ์ผ ๊ณ ๊ฐ๋ค์๊ฒ ์ข์ ์ธ์์ ๋จ๊ฒจ์ค ์ ์์ฃ .
Iterations
Iterations(๋ฐ๋ณต) ์ ๋๋ค.
"A ๊ณ ๊ฐ์ด ์์์ ์ฃผ๋ฌธํ๊ณ , ์๋น์ ์์์ ์กฐ๋ฆฌํ๊ณ , ๊ณ ๊ฐ์๊ฒ ์์์ ์ ๊ณตํฉ๋๋ค."
"B ๊ณ ๊ฐ์ด ์์์ ์ฃผ๋ฌธํ๊ณ , ์๋น์ ์์์ ์กฐ๋ฆฌํ๊ณ , ๊ณ ๊ฐ์๊ฒ ์์์ ์ ๊ณตํฉ๋๋ค."
"C ๊ณ ๊ฐ์ด ์์์ ์ฃผ๋ฌธํ๊ณ , ์๋น์ ์์์ ์กฐ๋ฆฌํ๊ณ , ๊ณ ๊ฐ์๊ฒ ์์์ ์ ๊ณตํฉ๋๋ค."
์ด๋ ๋ฏ ๊ฐ์ ํ์๋ฅผ ์ผ๋ง๋งํผ ์์ ์ ์ผ๋ก ๋ฐ๋ณตํ ์ ์๋์ง๋ฅผ ํ ์คํธํ๋ ์งํ๊ฐ Iterations ์ ๋๋ค.
์ฃผ์ํ ์
k6 ๋ ๊ฐ์ ์ ์ ๋ฅผ ๋ง๋ค์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ ์์ฒญ์ ๋ฐ๋ณต์ ์ผ๋ก ๋ณด๋ด๊ฒ ๋ฉ๋๋ค.
์์์ ์ฌ์ฉํ ์ฝ๋๋ฅผ ๋ณด๋ฉด,
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 10,
duration: "10s",
}
export default function() {
http.get('http://test.k6.io');
sleep(1)
}
10๋ช ์ ๊ฐ์ ์ ์ ๊ฐ 10s ๋์ http://test.k6.io ์ ํธ์ถํฉ๋๋ค.
๋์ค์ ๋ค๋ฃจ๊ฒ ์ง๋ง, 1๋ช ์ ๊ฐ์ ์ ์ ๊ฐ ํ๋ฒ๋ง default function ์ ํธ์ถํ๋ ๊ฒ์ด ์๋, 10์ด ๋์ ํด๋น ํจ์๋ฅผ ๊ณ์ ํธ์ถํฉ๋๋ค.
์ฆ, default function ์ 1๋ช ์ฉ 1๋ฒ ํธ์ถํด์ ์ด 10๋ฒ ํธ์ถํ๋ ๊ฒ์ด ์๋, 1๋ช ์ ๊ฐ์์ ์ ๊ฐ 5~10๋ฒ ์ ๋ ํธ์ถํฉ๋๋ค.
k6 ๋ฅผ ์ฌ์ฉํ๋ค๋ ๊ฒ์ ์ง์์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ถํ๋ฅผ ์ฃผ๋ ๊ฒ์ด๋ ๋ง์๋๋ก ์๋ฌด ์ ํ๋ฆฌ์ผ์ด์ ์ ํธ์ถํ๋ค๊ฐ ๋์ฐ?ํ ์ผ์ด ๋ฐ์ํ ์๋ ์์ต๋๋ค.
๋ฐ๋ผ์ k6 ๋ฅผ ์ํํ๊ธฐ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ ์ฃผ์ํ ์ ์ด ์์ต๋๋ค.
- ๋ณธ์ธ ์์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ ๊ฒฝ์ฐ ํ ์คํธํ์ง ์๊ธฐ
- ๋ณธ์ธ ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ผ๋ ํ ์คํธ๋ฅผ ํด๋ ๋๋ ์ํฉ์ธ์ง ํ์ธํ๊ธฐ
- Production ํ๊ฒฝ์ด ์๋ Dev ๋๋ Staging ํ๊ฒฝ์์ ์งํํ๊ธฐ
- ์ฑ๋ฅ์ ๋ถ์ํ ๋, ์ ๋ ํ๊ท ๊ฐ์ผ๋ก ํ๋จํ์ง ์๊ธฐ (์ด์ ๋ ๋ฐ๋ก ๋ฐ์์ ๋ค๋ฃธ)
- ํด๋ผ์ฐ๋ ํ๊ฒฝ์ ์ด์ฉํ๋ค๋ฉด, k6 ๋ฅผ ํ ์คํธํ ๋ Scale Up, Out ์ ์ฃผ์ํ๊ธฐ
p(90) ๊ณผ p(95) ์ ์๋ฏธ
์๋ ์ด๋ฏธ์ง๋ k6 ๋ฅผ ์ฌ์ฉํด์ ํผํฌ๋จผ์ค ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ํ๋ฉด์ ๋๋ค.
avg, min, med, max ์ ํ๋์ ๋ฌด์จ ๊ฐ์ ์๋ฏธํ๋์ง ์ ์ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ p(90) ๊ณผ p(95) ๋ ๋ฌด์์ ์๋ฏธํ๋ ์ง ๋์ถฉ์ ์ ๊ฒ ๊ฐ์๋ฐ.. ์ ํํ ๊ฐ์ ์ค์ง ์์ต๋๋ค.
p ๋ percentile ์ ์๋ฏธํ๊ณ ๋ค์ 90, 95 ๋ ๊ฐ๊ฐ 90%, 95% ๋ฅผ ์๋ฏธํฉ๋๋ค.
์ฆ, p(90) ์ "90%์ ์์ฒญ์ด ์ฃผ์ด์ง ์ง์ฐ๋ณด๋ค ๋น ๋ฅด๊ฑฐ๋ ๋์ผํ ์๊ฐ ์์ ์๋ฃ๋๋ค๋ ๊ฒ์ ์๋ฏธ" ํ๊ณ , p(95) ๋ "95%์ ์์ฒญ์ด ์ฃผ์ด์ง ์ง์ฐ๋ณด๋ค ๋น ๋ฅด๊ฑฐ๋ ๋์ผํ ์๊ฐ ์์ ์๋ฃ๋๋ค๋ ๊ฒ์ ์๋ฏธ"ํฉ๋๋ค.
๋ณด๋ค ์ฌ์ด ์ดํด๋ฅผ ์ํด ์ฑ๋ฅ ์งํ์ ๋์จ ๊ฒ์ ๋ถ์ํด๋ณด์ฃ .
http_req_duration ์ ์์ฒญ -> ์๋ต ๊น์ง ์ผ๋ง๋ ๊ฑธ๋ ธ๋์ง๋ฅผ ๋ํ๋ด๋ ์งํ์ ๋๋ค.
์ฌ๊ธฐ์ p(90) = 439.21ms ๋ 90% ์ด์์ ์์ฒญ์ 439.21ms ๋ด์ ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ก๊ณ , p(95) = 783.98ms ๋ 95% ์ด์์ ์์ฒญ์ 783.98ms ๋ด์ ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด ์ง ๊ฒ์ผ๋ก ๋ณผ ์ ์์ต๋๋ค.
๊ทธ๋ผ ์ ์ด ์งํ๊ฐ ์ค์ํ๊ฑธ๊น์? ์ ํํ 90๊ณผ 95 ์ผ๊น์? 100์ ์๋๋ ๊ฑธ๊น์?
์๋น์์ 500 ๋ช ์ ๊ณ ๊ฐ๋ค์ด ํ๋ฒ๊ฑฐ๋ฅผ ์ฃผ๋ฌธํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
80% ์ธ 400 ๋ช ์ 20์ด ์์ ํ๋ฒ๊ฑฐ๋ฅผ ๋ฐ์๊ณ , 20% ์ธ 100 ๋ช ์ ํ๋ฒ๊ฑฐ๋ฅผ ๋ฐ๊ธฐ๊น์ง 10๋ถ ์ด์์ด ๊ฑธ๋ ธ์ต๋๋ค.
์ด๋ ํ๊ท ์ ์ผ๋ก ํ ๊ณ ๊ฐ์ด ํ๋ฒ๊ฑฐ๋ฅผ ๋ฐ๊ธฐ๊น์ง ์ฝ 4๋ถ์ด ์์๋ฉ๋๋ค.
๋๋ถ๋ถ์ ์ฌ๋๋ค์ด 20์ด ๋ด์ ํ๋ฒ๊ฑฐ๋ฅผ ๋ฐ์์์๋ ๋ถ๊ตฌํ๊ณ ํ๊ท ์๊ฐ์ 4๋ถ์ผ๋ก ์ธก์ ๋๊ธฐ ๋๋ฌธ์ ํ๋ฒ๊ฑฐ๋ฅผ ๋ฐ๊ธฐ๊น์ง์ ์๊ฐ์ด ์ค๋๊ฑธ๋ฆฐ๋ค๊ณ ์๊ฐํ ์ ์์ต๋๋ค.
์ด๋ ๋ฏ ํ๊ท ์ ์ค์ ๋ก ์ ์ฒด ์ฑ๋ฅ์ ๋งํด์ฃผ๊ธฐ์ ํจ์ ์ด ์์ต๋๋ค.
๋ฐ๋ผ์ ํผํฌ๋จผ์ค ์ธก์ ์ ์งํ ํ ๋๋ ํ๊ท ์ ๋ณด๋ ๊ฒ์ ์ฃผ์๋ฅผ ์ฃผ์ด์ผ ํ๋ฉฐ, ํ๊ท ๋ณด๋ค๋ p(90) ๊ณผ p(95) ๊ฐ ๋ ์ค์ํฉ๋๋ค.
์ด๋ฒ์ 100๋ง ๊ฑด์ ์์ฒญ์ ๋ณด๋์ ๋, ๋ชจ๋ ์์ฒญ์ 1์ด ๋ด์ ์ด๋ฃจ์ด์ ธ์ผ ํ๋๋ฐ, ๋ฑ ํ๋์ ์์ฒญ๋ง์ด 1๋ถ์ด ๊ฑธ๋ ธ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
๊ณผ์ฐ ์ด ํ์๋ ์คํจํ ๊ฒ์ผ๊น์? ์ฑ๊ณตํ ๊ฒ์ผ๊น์? ์ผ๋ฐ์ ์ธ ๊ด์ ์์๋ ์คํจ๋ก ๋ณผ ์ ์์ง๋ง, Service Level Objective(SLO) ๊ด์ ์์ ๋ฐ๋ผ๋ณด๋ฉด ์ฑ๊ณต์ ๋๋ค. ์๋ SLO ์์ 100% ๋ ์์ ์ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
AWS S3 ์๋น์ค๋ง ๋ด๋ 99.999999999%์ ๋ด๊ตฌ์ฑ๊ณผ 99.99%์ ๊ฐ์ฉ์ฑ์ ์ ๊ณตํ๋ค๊ณ ํฉ๋๋ค. 100% ๋ ์์ ์ ์์ฃ .
100% ๊ฐ์ฉ์ฑ์ ์ ๊ณตํด์ฃผ๋ ์๋น์ค๋ฅผ ๋ฐ๊ฒฌํ๋ค๋ฉด ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์!
๊ทธ๋์ ๋ณดํต "90%์ ์๋ต์ ์์ฒญ์ ๋ฐ์ ํ 0.5์ด ์ฌ์ด์ ์๋ค." ๋ผ๊ณ ๋งํฉ๋๋ค. ์ ๋นํ ํฉ์๋ฅผ ๋ณธ ๊ฒ์ด์ฃ .
์ฐ๋ฆฌ๊ฐ ์ ์ดํ ์ ์๋ ๋ช ๊ฐ์ง ์ผ์ ์ํด ๋ฐ์ํ๋ ์ฌ๊ฑด์ ๋ํด์๋ ์ ๊ฒฝ์ฐ์ง ์๋ ๊ฒ์ด ์ํธํฉ๋๋ค.
SLO ๊ด์ ์ผ๋ก ๋ณด์์ ๋ 90% ๊ณผ 95% ์ ์์น๊ฐ ๊ฐ์ฅ ๋ณดํธ์ ์ด๊ธฐ ๋๋ฌธ์ k6 ์์๋ p(90) ๊ณผ p(95) ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
์ค๋์ ์ด๋ ๊ฒ k6 ๋ฅผ ์์ํ๊ธฐ ์ ์์๋๋ฉด ์ข์ ์ ์ ์์๋ดค์ต๋๋ค. ๋ค์ ๊ธ์์๋ ๋ณธ๊ฒฉ์ ์ผ๋ก k6 ๋ฅผ ํตํด Smoke, Load, Stress Test ๋ฑ ๋ค์ํ ํผํฌ๋จผ์ค ํ ์คํธ๋ฅผ ์งํํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๊ทธ๋ผ ์ค๋์ ์ฌ๊ธฐ๊น์ง!