[Data] 분산시스템에 대한 이해

Posted by 김성철

Data - 분산 시스템에 대한 이해

분산시스템이란

- 분산되어 있는 여러 서버를 하나의 서버처럼 다루는 시스템  
- 고가용성 : 서버와 네트워크, 프로그램등의 정보 시스템이 상당히 오랜 기간 동안 지속적으로 정상 운영이 가능한 정싱  
- 한 서버는 장애가 날 것이라고 가정, 장애가 없는 서버는 없다  
- 장애에 대한 대응 시스템, 장애를 방어할 수 있는 시스템이 바로 분산 시스템  
- 한 서버가 고장나면 다른 서버에서 처리 할 수 있도록 함  
- 대표방식은 복제  

복제의 용도

- 고가용성  
	한서버 또는 여러 장비나 전체 데이터센터가 다운될 때도 시스템이 계속 동작되게 함  
- 지연시간  
	지리적으로 사용자에게 가까이 데이터를 배치해 사용자가 더 빠르게 작업할 수 있게 함  
- 확장성  
	복제본에서 읽기를 수행해 단일 장비에서 다룰 수 있는 양보다 많은 양의 읽기 작업을 처리할 수 있음  

복제

- 복제란 네트워크로 연결된 여러 장비에 동일한 데이터의 복사본을 유지한다는 의미  
- 리더 팔로워 방식을 사용  
	복제 서버 중 한대를 리더로 사용하고 나머지 서버를 팔로워 서버로 사용  
- 복제된 서버에도 같은 데이터가 있어야 같은 처리를 할 수 있음  
- 클라이언트가 쓰기를 원할 때는 리더에게 요청을 해야 함  
- 요청을 받은 리더가 다른 팔로워들에게 동일한 요청을 보냄  
- 리더 서버에 장애가 발생하면 팔로워 서버중 하나를 리더로 선출  
- 읽을 때는 리더 혹은 팔로워에게 질의 가능, 쓰기는 리더만 가능  

리더의 장애 상황 (Fail Over 과정)

- 팔로워중 하나를 리더로 승격해야함  
- 클라이언트에도 새 리더로 쓰기를 요청하기 위한 재처리가 필요  
- 다른 팔로워들은 새 리더로부터 달라진 데이터를 읽어야 함  
  
1. 리더가 장애 상황인지 확인함 (health check)  
	- 대부분 타임아웃을 사용  
2. 선출과정을 통해 새로운 리더를 선택  
	- 가장 적합한 후보는 가장 최신의 데이터를 갖고 있는 팔로워  
3. 새로운 리더를 위한 시스템 설정  
	- 이전 리더가 팔로워가 되었음을 알림  

팔로워의 장애상황 (따라잡기)

- 팔로워가 죽더라도 리더를 통해 매우 쉽게 복구할 수 있음  
- 마지막 트랜잭션을 확인  
- 리더에 연결하고 연결이 끊어진 동안의 데이터 변경을 모두 요청할 수 있음  
- 스레드 읽는 처리량은 고정이라 큰 장애는 없음  
- 변경된 데이터의 보관 기간이 넘어가면 로그가 사라져서 연결 안 될 수 있음  
	하둡의 SNN 장애의 경우 Airflow DAG가 실패한지 오래됐다가 한번에 실행됐을 때  
- 리더의 데이터 상황을 다 따라잡으면 장애 상황 종료  

변경 데이터란

- MySQL에서는 Binary Log  
- PostgreSQL에서는 LogSequence Number  
  
- CREATE , DROP , ALTER 와 같은 DDL과 DML을 통해 DB에 변경사항이 생길 때 그 변화된 이벤트를 기록  
- SELECT 등 조회 문법은 제외됨  
- 리더의 복제 로그의 정확한 위치를 알려주는 파일  
- 서버 내에서 발생되는 모든 변경내역이 기록되는 파일  

분산 시스템의 문제점

- 분산 시스템은 완전하지 않음  
- 결함이 발견됐을 때 시스템이 이를 견딜 수 있게 만들기도 쉽지 않음  
- 한 노드에서 다른 노드로 정보가 흐르 수 있는 유일한 방법은 신뢰성이 없는 네트워크로 보내는 것  
- 시스템이 커질 수록 구성요소 하나가 고장 날 가능성이 높아짐  
- 결함이 생겼다면, 잘못된 결과보다는 동작하지 않는게 나음  
- 예측할 수 없는 방식으로 고장나는 것 -> 부분장애  
- 어떨 때는 동작하지만 어떨 때는 예측이 되지 않는 방식으로 실패 -> 비결정성  

해결법 예시

- 결함이 있더라도 서비스는 올바르게 동작하게 만들기  
- 부분에 장애가 발생하였다면 전체를 kill  
- 보장을 해주는 범용적인 추상화를 찾아 구현  
	- 애플리케이션단에서 이 보장에 의존함 (ex, 데이터베이스의 트랜잭션)  
- 신뢰성 없는 구성 요소를 사용해 신뢰성 있는 시스템 구축  
- 그 외 선형성 보장, 순서화 보장등등  
- Zookeeper  

파티셔닝

- 파티셔닝과 샤딩은 사실 상 같은 용어  
- 파티션은 MongoDB , ElasticSearch , SolR의 샤드와 같음  
- 데이터셋이 매우 클 때 또는 쿼리 처리량이 매우 높을 때 데이터를 파티셔닝  
- 데이터 파티셔닝을 하는 주된 이유는 확장성  
- 대용량 데이터셋이 여러 디스크에 분산될 수 있고, 쿼리에 대한 부하를 여러 프로세서에 분산시킬 수 있음  
- 노드 사이에 쿼리 부하를 고르게 분산시키는 것이 중요  
- 고르게 분산이 되지 않아 한쪽으로 쏠린 것을 Skewed 되었다고 부름  
- 불균형하게 높은 쿼리 부하가 걸리는 파티션을 핫스팟이라고 함  
	노드를 무작위로 고르면 해소가 되지만, 어느 노드에 저장돼었는지 알 수 없으므로 모든 노드에 병렬적 쿼리를 실행함  

key-value 데이터 파티셔닝

- 키 범위 파티셔닝, 연속된 범위(최소값~최대값)의 키를 할당  
	* 데이터셋이 매우 클 때 또는 쿼리 처리량이 매우 높을 때 데이터를 파티셔닝  
	* 파티션 경계는 수동으로 선택 OR 데이터베이스에서 자동으로 선택  
	* 각 파티션 내에서는 키를 정렬된 순서로 저장할 수 있음  
		+ : 범위 스캔이 쉬워짐  
		- : 자주 사용하는 특정한 접근 패턴이 핫스팟을 유발  
  
- 키의 해시값 기준 파티셔닝  
	* 쏠림과 핫스팟의 위험 때문  
	* Cassandra와 MongoDB는 MD5 , Voldemort는 Fowler-Noll-Vo를 사용  
	* 키에 적합한 해시 함수를 구하고 각 파티션에 해시값 범위를 할당함  
	* 해시값이 파티션의 범위에 속하는 모든 키를 그 파티션에 할당함  
	* 키를 파티션 사이에 균일하게 분산시키는데 좋음  
	* 파티션 경계는 크기가 동일하도록 나누거나 Random하게 선택 가능  
	* 해당 기법을 일관성 해싱이라고 함  
	* 키 범위 파티셔닝의 좋은 속성을 잃어 버리는 단점이 있음  
	* 범위 질의를 효율적으로 실행 할 수 없고 모든 파티션의 정렬 순서가 유지되지 않음  

파이션 리밸런싱

- 추가 리소스가 필요해서 노드를 추가한 경우 클러스터에서 한 노드가 담당하던 부하를 다른 노드를 옮기는 과정이 Rebalancing