LoadBalancer

Sonar0·2022년 12월 22일
0

기본 개념

LoadBalancing 이란?

CS에서 로드밸런싱이란 어떤 작업을 컴퓨팅 리소스 단위로 분산해서 처리하는 것을 로드밸런싱이라고 한다. 부하가 한 곳에서 처리할 수 있는 용량을 넘으면 처리를 하지 못하거나, 처리가 기대보다 늦어지기 때문에 이것을 방지하기 위해서 부하를 분산하는 방법을 찾는다.

LoadBalancer란?

서버 엔지니어링에서 LoadBalancer 라고 하면 일반적으로 트래픽을 분산해주는 중앙 처리 장치를 의미한다.

LoadBalancer가 필요한 이유

API서버를 하나 만들었다고 하자. 트래픽 요청량이 많아서 클라이언트의 요청이 지연되거나 응답하지 못하는 경우가 발생하기 시작했다.

  • 해결 방안 1 : 더 많은 요청을 받아들일 수 있도록 서버의 용량과 스펙을 업그레이드(scale-up)
서버 전원을 끄고 고성능의 하드웨어 설치후 다시 실행
새로운 서버를 장만해서 프로그램을 설치하고 실행한 뒤에 client의 요청을 이 새로운 서버로 옮김
  • 방안 1의 단점
다운타임(서버가 작동하지 못하는 시간)이 발생
클라이언트가 바라보는 서버의 IP를 변경해주어야 함 (DNS 등 ..)
업그레이드한 용량으로 감당할 수 없는 더 많은 요청이 들어온다면 똑같은 과정을 반복해야 함

위 경우 기껏 용량을 올렸는데 사용량이 줄어들어 자원이 낭비되는 경우에는 같은 방식으로 용량을 줄이던가, 계속 낭비하는 수 밖에 없다.

  • 해결방안 2 : API 서버 앞에 부하를 분산해주는 LoadBalancer를 추가

기존의 서버는 그대로 두고 새로운 서버를 증설해서 LoadBalancer에게 연결해주는 방법(scale-out)

  • 방안 2의 장점
클라이언트는 LoadBalancer의 IP주소만 바라보면 되므로 대상을 바꾸지 않아도 됨
수평적으로 확장(scale-out)으로 유연하게 늘어나는 트래픽에 대응할 수 있음
수평적 축소(scale-in)로 줄어드는 트래픽에도 대응할 수 있음

LoadBalancing 방법

Round-Robin

라운드로빈은 말 그대로 순서대로 하나씩 돌아가면서 나눠주는 것이다. 사전 지식이 없더라도 누구나 가장 먼저 생각해볼만한 개념이다. 가장 기초적이기 떄문에 라운드로빈 방식은 로드밸런싱 뿐만 아니라 CS 전반에서 많이 사용하는 개념이다.

IP Hashing

같은 IP의 요청을 같은 서버로 연결하고 싶은 use-case

만약 서버에서 고객정보에 대해서 cache가 되어있어서 같은 유저가 여러가지 요청을 했을 때 Cache hit를 통해서 빠르게 응답할 수 있도록 서버 어플리케이션을 구현했다면, 로드벨런서는 어떻게 요청을 연결해야할까? 이 경우, 같은 유저에게 온 요청은 최대한 같은 서버로 연결해줄수록 Cache Hit 를 높일 수 있다. Cache Hit가 높아지면 빠른 응답을 통해서 고객 경험도 좋게 하고, 응답시간이 빠를수록 서버는 같은 자원으로 더 많은 요청을 처리할 수는 부가가치 또한 있다.

같은 유저에게 들어온 요청이란 것을 어떻게 알 수 있을까? payload를 파싱해보면 알 수 있지만, 이것을 로드벨런서에서 하기에는 비용이 많이 드는 작업이다. 로드벨런서는 요청을 분산하는 역할이기 때문에 가장 빠르게 분산할 수 있는 방법을 찾고 역할을 줄여야 안정적으로 사용할 수 있다.

로드벨런서에서 비용이 많이 드는 이유

Application Layer (OSI7에서 5~7영역) 까지 열어봐야하기 때문이다.
Source IP가 같으면 같은 유저에게서 온 것이라고 추정하면
비교적 적은 비용(OSI 3,4 layer만 보고 판단)으로 알 수 있다.

Hashing

Hashing 은 어떤 입력 값을 바탕으로 랜덤한 결과(문자, 숫자, 바이트)를 출력하지만, 같은 입력에 대해서는 항상 같은 값이 나오도록 보장하는 방법을 말한다.

IP Range 기반 분산의 단점

Hashing을 왜 사용할까?
먼저 IP만을 가지고 다음과 같이 분산한다고 생각해보자.
1.1.x.x 은 1번 서버에 연결
1.2.x.x 은 2번 서버에 연결

이렇게 분산을 하면 발생하는 부작용
10.1.x.x 를 가진 요청이 특정시간에 몰릴 가능성이 있다. Range를 더 나눠서 규칙을 세분화하는 방법으로 트래픽을 분산시킬 수 있지만 트래픽의 경우 어떤 패턴이 발생하기도 하지만 시시각각 바뀌는 특징이 있기 때문에, 인프라의 특징을 가지는 LoadBalancer에서 매번 이것을 수정하도록 하는 것도 어려운 일이다.

IP Hashing을 사용하는 이유

그래서 사용하는 것이 IP값을 그대로 사용해서 범위를 나누어 분산하는 것이 아니라,
hashing을 통해서 나온 랜덤한 결과에 범위를 나누어 분산을 하는 것이다. 이 경우 hasing 함수가 IP의 특정 패턴에 종속되지 않게 고르게 random한 결과를 주는 것이 보장만 된다면, 그냥 IP를 사용해서 범위를 주는 것보다는 고르게 분산할 수 있다. 로드벨런서에 연결된 대상이 많아지더라도 같은 규칙(mod 연산등)으로 동일한 비율로 분배해줄 수 있다. 다만, 이 경우에도 실제로 발생하는 트래픽은 예측할수 없고 사용자 요청의 특정한 패턴은 여전히 존재하기 떄문에 Hashing을 했더라도 어느 정도의 편차나 편향이 있을수는 있다.

Hashing

IP Hashing 과 같은 방식이지만, Hash의 기준이 되는 값이 다른 대상(들) 이고 이것을 설정할 수 있다. Hashing의 대상이 payload에 있다면 L4까지만 보고 분산할 수 있는 LB(Network Loadbalancer)로는 불가능하고, L7까지 보는 LB(Application Loadbalancer)에서 할 수 있다. L7까지 봐야한다면, L4기반 LB보다는 지연이 조금 더(a few micro seconds or nano seconds) 생길 수 있다. 단, 대상이되는 payload가 크다면 사용하지 않는 것이 좋다.

Least Connections

Client의 요청을 받은 시점에 가장 연결이 적은 서버로 보내준다.
요청을 처리하기 위해서 Connection을 오래 유지하는 서버 어플리케이션인 경우(CPU 사용 작업이 많은 경우 등)에 이 방법이 적합하다.

Least Time

가장 빨리 응답을 줄 것으로 기대되는 서버로 연결한다. 그동안의 response time의 평균 또는 추정치와 현재 연결된 connection 갯수가 얼마나 적은지 값을 조합해서 계산한다. 공식은 구현체에 따라서 다르다.

Random

Random 하게 대상에게 연결한다. Least Connections 또는 Least Time 알고리즘과 함께 사용되기도 한다.

LoadBalancer(LB) 동작원리와 설계

LoadBalancer의 동작 원리

현대 LoadBalancer는 그 자체가 하나의 시스템이다. 외부적으로는 하나의 IP만 존재하기 때문에 하나의 서버같지만, 하나의 IP만으로도 수년동안 안정적인 운영이 가능하도록 한다. DNS형태로 서비스를 제공하는 LB도 있다.

LoadBalancer 사용을 위해 세팅해야할 것

LoadBalancer가 연결을 전달하기 위해서는 대상 서버가 이용가능한 상태여야 한다.
이용 가능한 상태가 아니라면, 대상 서버에서 제외된다.

  • 이용가능 상태를 판별하는 방법
1. 연결이 된다면 정상이다.(TCP, UDP 등)
2. 응답 한다면 정상이다.(특정 PATH로의 HTTP Connection 요청에 200응답)
3. 기대한 응답 값이 나온다면 정상이다.
(HTTP Response Body를 파싱해서 기대한 값, OK, UP 등이 존재하면 정상)

1 → 3으로 갈수록 health check 비용이 크고 확인 방법이 구체적이다.

신뢰성 있는 LoadBalancing 설계

LoadBalancer를 통해서 몇몇 서버에 장애가 생겨도 여분의 서버로 응답이 가능하므로 서비스의 가용성을 높였다 → LoadBalancer 서버에 장애가 난다면?

여러개의 LB서버를 두고 DNS에서 LoadBalancer에 대한 health check 기반의 이중화를 세팅해야한다.

  • AWS에서는 failover, weighted 등의 routing policy

AWS Elastic LoadBalancer 사용하기

LoadBalancer Type

AWS에는 3가지 타입의 LoadBalancer가 있다.

Network Load Balancer

  • L4 레이어의 정보로 트래픽을 분산해주는 LoadBalancer.

  • L4 레이어의 정보로 트래픽을 분산하는 것으로 충분한 경우에 사용한다. 분산규칙이 정해져 있다.

  • L4 레이어만 확인하므로 Application LoadBalancer 보다 빠르다.

Application Load Balancer

  • L7 레이어의 정보로 트래픽을 분산해주는 LoadBalancer.

  • 트래픽 분산 규칙을 직접 정하고 싶은 경우에 사용한다.

  • L7 레이어까지 확인하므로 Network LoadBalancer 보다는 느리다.

Gateway Load Balancer

  • GENEVE (Generic Network Virtualization Encapsulation) 프로토콜로 된 서비스로 연결 할 때 사용한다.

  • 주로 third party SaaS 업체들이 서비스 형태로 인프라를 제공할 때, 인프라는 해당 업체가 직접 관리하도록 감추고(encapsulation) Client가 안전하고 편리하게 protocol 기반으로 연결할 수 있도록 제공하기 위해서 사용한다.

Network LoadBalancer로 부하 분산하기

Network Load Balancer의 부하 분산 방법

Target Group에서 Flow hash algorithm의 기본 규칙을 따라서 대상을 선택한다. 알고리즘은 다음을 기반으로 한다.

  • 프로토콜
  • 소스 IP 주소 및 소스 포트
  • 대상 IP 주소 및 대상 포트
  • TCP 시퀀스 번호

알고리즘에 따라 Client로부터의 연결은 다음과 같은 특징을 따른다.

  • 각 개별 TCP 연결은 연결 수명 동안 하나의 대상에 라우팅 된다.

  • 하나의 클라이언트로부터 요청된 TCP 연결들은 소스 포트와 시퀀스 번호가 서로 다르므로 다른 대상에 라우팅될 수 있다.

서버 세팅하기

두 개의 EC2 인스턴스에 다음 명령어로 간단한 서버를 띄운다.

index.html

응답에 사용할 index.html 파일을 만든다. Body의 내용을 바꿔서 어떤 서버인지 구분!

<!DOCTYPE html>
<html>
	<head>
		<!-- head definitions go here -->
		Hellow World
	</head>
	<body>
		<!-- the content goes here -->
		Server 1 or 2
	</body>
</html>

두 개의 서버 각각에 다음 명령어로 echo server 를 띄운다.

while true; do { \
	echo -ne "HTTP/1.0 200 OK\r\nContent-Length: $(wc -c <index.html)\r\n\r\n";\
	cat index.html; } | nc -l -p 8080 ; \
done

Target Group 생성하기

Network Load Balancer 는 연결할 대상을 Target Group 이라는 추상화된 대상으로 지정한다.

EC2 대시보드에서 Target Group(대상 그룹)을 선택

1. Create target group
2. instances 선택
3. Target group name: free(lb-tcp)
4. Protocol: TCP
5. Port : 8080
6. VPC: 자신의 VPC 선택
7. Health Check
a. protocol: TCP
8. Advanced: 테스트를 위해서 작게 세팅
	a. Port: Traffic port
    // 몇번을 실패해야 healthy로 변경할지, unHealthy threshold 는 반대
	b. Healthy threshold: 2
    // 몇초동안 응답이 없으면 unhealthy로 변경할지
    c. Timeout : 10s
    // interval 이 짧을 수록 부하와 신뢰성이 커진다. default 30s
	d. Interval: 10s
9. Next를 누르고
10. EC2 인스턴스를 선택한다.
11. include as pending below 클릭
	a. 아래 review targets 에서 확인

Network LoadBalancer 생성하기

EC2 대시보드에서 Load Balancers를 선택

1. Create Load Balancer
2. Network Load Balancer 선택
3. Load balancer name: free(network-lb)
4. Schema: internet-facing
5. IP address type: IPv4
6. Network mapping
	a. 자신의 VCP 선택
	b. 모든 AZ 선택
7. Listeners and routing
	a. Listener
		i. Protocol: TCP
		ii. Port: 8080
		iii. Default action: target group 선택
8. Create 버튼
	a. LoadBalancer 대시보드에서 State 가 
    Provisioning > Active 로 바뀌어야 이용가능하다.

결과 확인

  • curl 또는 웹브라우저로 해당 curl {DNSname}:{$port} 로 응답 확인
    a. 반복 요청해서 두 개의 서버에서 응답하는지 확인
    → 두개의 서버에 트래픽을 분산하는 것을 확인할 수 있다.

Cross-zone load balancing

장애 방지를 위해 Availability zone 별로 서비스가 가용하도록 구성한 경우, 다음 옵션으로 Cross-zone load balancing 을 선택하면, 가능한 availability zone들에게 고르게 트래픽을 분배할 수 있다.

1. Load Balancer 선택
2. Attributes
3. Edit Attributes
4. Cross-zone loadbalancing : enable 선택
5. Save

Application LoadBalancer로 부하 분산하기

Application Load Balancer의 부하 분산 방법

다음 과정으로 부하 분산 방법을 결정한다.

1. Priority Order(우선순위)로 Lister Rule 들 중 어떤 규칙을 적용할지를 평가한다.
2. Rule 에 해당하는 target group을 선택한다.
	a. Default 는 Round Robin이다.
	b. Routing은 Target Group과 독립적이다. 예를 들어서 하나의 ec2 인스턴스가 두 개의 target group에 속해도 상관이 없다.

서버 세팅하기

Network LoadBalancer로 부하 분산하기 와 동일하다.

Target Group 생성하기

Application Load Balancer 는 연결할 대상을 Target Group 이라는 추상화된 대상으로 지정한다.
실습을 위해서 준비한 2개의 EC2인스턴스를 대상으로 각각 별도의 Target Group으로 만들어준다.

1. Create target group
2. instances 선택
3. Target group name: lb-app-1 , lb-app-2
4. Protocol: HTTP
5. Port : 8080
6. VPC: 자신의 VPC 선택
7. Protocol version: HTTP1
8. Health Check
	a. protocol: HTTP
	b. path: /
9. Advanced: 해당 설정은 실습의 용이를 위해서 작게 세팅
	a. Healthy threshold: 2
	b. Unhealthy threshold: 2
	c. Timeout: 2
	d. Interval: 5
10. Next를 누르고
11. EC2 인스턴스를 선택한다.
	a. de-lb-app-1 이면 1번 instance를 선태한다.
	b. de-lb-app-2 이면 2번 instance를 선택한다.

Application LoadBalancer 생성하기

EC2 → Load Balancers

1. Create Load Balancer
2. Application Load Balancer 선택
3. Load balancer name: de-application-lb
4. Schema: internet-facing
5. IP address type: IPv4
6. Network mapping
	a. 자신의 VCP 선택
	b. 모든 AZ 선택
7. Security groups
	a. security 그룹을 선택하고, inbound/outbound network ACL을 security group을 통해서 운영중에 제어할 수 있다.
	b. 실습을 위해서 모든 트래픽을 허용하는 security group을 만들고 그것을 선택한다.
8. Listeners and routing
	a. Listener
		i. Protocol: HTTP
		ii. Port: 8080
		iii. Default action: de-lb-app-1 , de-lb-app-2 중 하나를 선택한다.
9. Create 버튼
	a. LoadBalancer 대시보드에서 State 가 Provisioning > Active 로 바뀌어야 이용가능하다.
10. 생성된 후에 Listeners 탭에서 생성된 Listeners 선택하고, edit 버튼을 눌러서 기본 규칙을 수정한다.
	a. Forward to
		i. Target group
		ii. de-lb-app-1 선택, weight 1
		iii. de-lb-app-2 선택, weight 2
	b. Save changes

Network LoadBalancer 로 트래픽 연결하기

EC2 → LoadBalancing → LoadBalancers

1. 생성한 LoadBalancer 선택
2. 아래 Description 에서 DNS name copy
3. curl 또는 웹브라우저로 해당 $DNSname:$port 로 응답 확인
	a. 반복 요청해서 두 개의 서버에서 응답하는지 확인

테스트 중에 Security Group에 모든 트래픽을 허용한 그룹으로 설정하고 테스트를 진행해야 한다. Security Group을 추가해주지 않으면 503 오류가 뜬다.

profile
초보 개발자

0개의 댓글