Envoy 내부 구조 · 누구를 고를 것인가 · 실습
같은 업스트림 셋으로 방식만 바꿔 센다
목표
부하 분산 방식을 하나씩 바꿔 가며 실제 분배를 세고, 해시 기반 방식의 두 가지 성질(같은 열쇠는 같은 곳으로 · 한 대를 빼도 그 대의 몫만 옮김)을 직접 확인한다.
왜 중요한가
부하 분산은 설정 한 줄이지만 그 한 줄이 캐시 적중률과 세션 유지, 그리고 서버를 뺄 때의 충격 크기를 모두 정한다. 문서로 읽으면 다 그럴듯해 보이는데, 숫자를 직접 세어 보면 '무작위는 작은 표본에서 이만큼 치우치는구나' 와 '한 대를 빼도 이 정도만 옮기는구나' 가 몸에 남는다. 특히 열쇠를 뽑지 못한 요청이 무작위로 흘러간다는 사실은 세션 고정 장애의 단골 원인인데, 설정만 봐서는 보이지 않는다.
단계
1. 업스트림 셋을 ok 로 띄우세요(8088·8089·8090). /root/envd-lb/lb-rr.yaml 에 lb_policy: ROUND_ROBIN 인 STATIC 클러스터 pool 과 / 라우트를 두고 --concurrency 1 로 띄우세요(관리 9951, 리스너 127.0.0.1:10051). 9번 요청해 /root/envd-lb/01-rr.txt 에 p8088=·p8089=·p8090=·total= 네 줄을 적으세요.
2. /root/envd-lb/lb-rr.yaml 을 /root/envd-lb/lb-weight.yaml 로 복사하고 엔드포인트마다 load_balancing_weight 를 주세요 — 8088 은 2, 나머지 둘은 1 입니다. 그 설정으로 다시 띄워 12번 요청하고 /root/envd-lb/02-weight.txt 에 p8088=·p8089=·p8090=·total= 네 줄을 적으세요.
3. /root/envd-lb/lb-random.yaml 을 만드세요 — 가중치는 두지 않고 lb_policy 만 RANDOM 으로 바꾼 설정입니다. 그 설정으로 띄워 40번 요청해 /root/envd-lb/03-random.txt 에 p8088=·p8089=·p8090=·total=·max_gap= 다섯 줄을 적으세요(max_gap 은 가장 많이 받은 수에서 가장 적게 받은 수를 뺀 값).
4. /root/envd-lb/lb-ring.yaml 을 만드세요 — lb_policy 는 RING_HASH, ring_hash_lb_config.minimum_ring_size 는 1024, 라우트의 hash_policy 는 헤더 x-user 입니다. 그 설정으로 띄운 뒤 u1 부터 u9 까지 아홉 사용자로 각각 한 번씩 요청해 /root/envd-lb/04-map.txt 에 사용자 포트 아홉 줄을 적으세요.
5. 사용자 u1 로 네 번, u2 로 네 번 요청해 /root/envd-lb/05-sticky.txt 에 u1_ports=(받은 포트 네 개를 공백으로), u1_distinct=(서로 다른 포트 수), u2_distinct= 세 줄을 적으세요.
6. /root/envd-lb/lb-ring2.yaml 을 만드세요 — 4단계 설정에서 엔드포인트 8090 만 뺀 것입니다. 그 설정으로 다시 띄운 뒤 같은 아홉 사용자로 다시 요청해 /root/envd-lb/06-remap.txt 에 사용자 포트 아홉 줄을 적으세요. 그다음 4단계의 표와 견주어 /root/envd-lb/06-moved.txt 에 moved=(자리가 바뀐 사용자 수), stayed=, total=9 세 줄을 적으세요.
7. /root/envd-lb/lb-query.yaml 을 만드세요 — 엔드포인트는 다시 셋이고, hash_policy 는 헤더 대신 질의 파라미터 uid 입니다. 그 설정으로 띄운 뒤 ?uid=u1 로 세 번, ?uid=u2 로 세 번 요청해 /root/envd-lb/07-key.txt 에 u1_distinct=, u2_distinct=, header_ignored=(헤더 x-user: u1 만 붙이고 질의는 없이 세 번 요청했을 때 서로 다른 포트 수) 세 줄을 적으세요.
8. /root/envd-lb/08-report.md 에 even_spread=(1단계의 세 값을 쉼표로), heavy_share=(2단계에서 가중치 2 를 준 엔드포인트가 받은 비율, 백분율 정수), sticky=(5단계에서 같은 사용자가 한 곳에 붙었으면 yes), moved_users=(6단계 값) 네 줄을 적고, 그 아래 배운 것을 네 줄 이상 적으세요.
참고
- 분배를 세는 모든 단계는
--concurrency 1로 띄워야 합니다. 워커가 여럿이면 차례가 워커마다 따로 놀아 숫자가 매번 달라집니다. - 업스트림은
python3 /opt/lab/envoy/upstream.py <포트> ok로 띄웁니다. 응답 본문이ok:<포트> <경로>라 어느 쪽이 받았는지 셀 수 있습니다. - Envoy 를 다시 띄우기 전에는
pkill -x envoy로 정리하고, 기동은/ready가 LIVE 를 돌려줄 때까지 도는 루프로 기다리세요. - 서로 다른 값의 개수는
sort -u | wc -l로 셉니다. - 흔한 실수 —
hash_policy를 라우트가 아니라 클러스터에 적는 것. 열쇠는 요청에서 뽑으므로 라우트의route아래에 적습니다.
단계 8개
- 고르게 나누는 것이 기본값이다
- 체급이 다른 서버를 한 묶음에 넣는다
- 고르게 보이지만 고르지 않다
- 같은 사용자는 늘 같은 서버로
- 같은 열쇠를 네 번 보내도 자리가 안 바뀐다
- 서버 한 대를 빼면 몇 명이 자리를 옮기나
- 열쇠를 헤더에서 질의 문자열로 바꾼다
- 방식별 성질 표로 정리한다