아키텍처 패턴 시리즈 6: 피어 투 피어 패턴 (Peer-to-Peer Pattern)
피어 투 피어(Peer-to-Peer, P2P) 패턴은 각 노드가 서로 대등한 지위에서 통신하고 자원을 공유하는 네트워크 구조를 말한다.
각 피어가 동시에 클라이언트와 서버의 역할을 수행하며, 중앙 서버 없이 직접적인 데이터 교환이 이루어진다.
피어 투 피어 패턴의 필요성
P2P 패턴은 여러 노드가 독립적으로 서로 데이터를 교환할 때 유용하며, 중앙 서버가 필요 없는 구조적 장점을 제공한다.
- 분산 처리: 각 노드가 직접 데이터를 제공하고, 받아오며, 처리할 수 있다.
- 중앙 서버 의존성 제거: 서버에 대한 의존성을 줄이고 네트워크 부하를 분산할 수 있다.
- 확장성: 새로운 피어를 추가하는 것만으로 네트워크 확장이 가능하다.
P2P 패턴은 파일 공유 시스템, 메시징 서비스, 분산 컴퓨팅 시스템에서 널리 사용된다.
예시: 파일 공유 시스템
P2P 패턴을 이용하면 파일을 저장하고 있는 피어들 간에 데이터를 직접 주고받으면서 파일을 공유할 수 있다.
피어 투 피어 패턴의 구조
- Peer (피어): 데이터를 요청하고 동시에 제공하는 노드로, 클라이언트와 서버의 역할을 모두 수행한다.
- Request & Response (요청 및 응답): 피어가 요청하는 데이터와 응답 데이터.
- P2P Network (네트워크): 각 피어가 연결되어 있는 네트워크로, 데이터를 공유하는 매개체이다.
구조 다이어그램
Peer <-----> Peer
^ |
| v
Peer <-----> Peer
피어 투 피어 패턴 동작 순서
- 피어는 네트워크 상의 다른 피어에게 필요한 데이터를 요청한다.
- 요청받은 피어는 자신의 데이터를 조회하여 요청한 데이터를 전달한다.
- 각 피어는 다른 피어에게 데이터 요청을 보낼 수도, 받을 수도 있다.
피어 투 피어 패턴 예시
파일 공유 시스템에서 각 피어가 직접 데이터를 요청하고 전달하는 방식으로 P2P 패턴을 구현할 수 있다.
Java로 피어 투 피어 패턴 구현하기
// Peer 클래스: 다른 피어에게 데이터를 요청하고 응답을 받을 수 있는 클래스
import java.util.HashMap;
import java.util.Map;
public class Peer {
private String name;
private Map<String, String> dataStore = new HashMap<>();
public Peer(String name) {
this.name = name;
}
public void storeData(String key, String data) {
dataStore.put(key, data);
}
public String requestData(String key, Peer targetPeer) {
return targetPeer.respondToRequest(key);
}
private String respondToRequest(String key) {
return dataStore.getOrDefault(key, "데이터를 찾을 수 없습니다.");
}
public String getName() {
return name;
}
}
// Main 클래스: 피어들이 데이터를 저장하고 요청을 처리하는 시스템을 시연
public class Main {
public static void main(String[] args) {
Peer peer1 = new Peer("Peer1");
Peer peer2 = new Peer("Peer2");
peer1.storeData("file1", "Peer1의 파일 데이터");
peer2.storeData("file2", "Peer2의 파일 데이터");
String response1 = peer1.requestData("file2", peer2);
String response2 = peer2.requestData("file1", peer1);
System.out.println(peer1.getName() + "가 요청한 데이터: " + response1); // 출력: Peer2의 파일 데이터
System.out.println(peer2.getName() + "가 요청한 데이터: " + response2); // 출력: Peer1의 파일 데이터
}
}
코드 설명
- Peer:
Peer
클래스는 데이터를 저장하고 다른 피어에게 요청을 보낼 수 있는 기능을 제공한다. - storeData: 피어가 특정 데이터를 저장한다.
- requestData: 피어가 다른 피어에게 데이터를 요청한다.
- respondToRequest: 요청받은 피어가 데이터를 반환하거나, 데이터를 찾을 수 없다는 메시지를 반환한다.
출력 결과
Peer1가 요청한 데이터: Peer2의 파일 데이터
Peer2가 요청한 데이터: Peer1의 파일 데이터
피어 투 피어 패턴 활용
- 파일 공유 시스템: P2P 네트워크를 통해 피어들 간의 파일을 직접 공유할 수 있다.
- 메시징 시스템: 피어들이 서로 메시지를 주고받으며 통신할 수 있다.
- 분산 컴퓨팅: 피어들 간의 작업을 분산하여 처리하는 분산 컴퓨팅 환경에서 활용 가능하다.
피어 투 피어 패턴의 장점
- 확장성: 피어를 쉽게 추가할 수 있으며, 네트워크 확장이 용이하다.
- 중앙 서버의 부재: 중앙 서버가 필요 없어, 서버 비용과 관리가 줄어든다.
- 효율적인 자원 분배: 피어들이 직접 데이터를 주고받으며 네트워크 부하를 분산할 수 있다.
피어 투 피어 패턴의 단점
- 데이터 관리의 어려움: 데이터가 분산되어 있어 일관성 유지와 관리가 어렵다.
- 신뢰성 문제: 신뢰할 수 없는 피어의 참여로 인해 데이터 무결성과 보안이 위협받을 수 있다.
- 복잡성: 피어들 간의 연결과 통신이 복잡해질 수 있다.
마무리
피어 투 피어 패턴은 시스템 확장성과 자원 분배의 효율성을 제공하는 패턴으로, 중앙 서버가 필요 없는 네트워크 환경에서 유용하게 활용된다.
분산된 데이터 교환이 필요할 때 적합한 구조이다.
아래 글에서 다른 아키텍쳐 패턴들을 확인할 수 있다.
아키텍처 패턴 모음