지난 시간에는 OSPF 망에서 Router-LSA를 통해 각 라우터가 Network Topology Map을 만들고 Link Cost 기반으로 Shortest Path Tree를 구성하는 절차에 대해 설명을 드렸습니다.
오늘은 위의 과정을 통해 생성된 OSPF Topology에 External Network이 연결되는 경우, 어떻게 OSPF 라우터들은 External Network의 라우팅 정보를 배우고, 그 Network으로 가는 Shortest Path를 알게 되는지 그 과정을 살펴 보도록 하겠습니다.
OSPF External Network
■ OSPF 관점에서 External Network이란?
External Network이란 OSPF로 구성된 하나의 네트워크(AS 혹은 Routing Domain이라 부름)과 연결된 "외부 네트워크"를 말합니다. 즉, OSPF가 enable된 라우터간에는 Router-LSA(지난 시간에 설명), Network-LSA등으로 서로간에 라우팅 정보를 주고 받게 되고, OSPF가 enable되지 않은 망의 라우팅 정보는 External Network으로 분류되어 AS-External-LSA를 통해 External Network의 라우팅 정보를 OSPF 망에서 알 수 있게 됩니다. External Network의 예는 아래와 같습니다.
BGP 망의 라우팅 정보
IS-IS 망의 라우팅 정보
Static route로 생성된 라우팅 엔트리 정보
라우터와 바로 직결된 Connected Network이지만 이 링크는 OSPF가 enable되지 않은 경우
이와 같이 External Network과 연결된 OSPF 라우터를 ASBR(Autonomous System Border Router)이라 부릅니다.
■ AS와 Routing Domain
보통 통신사업자는 망 내부 전체의 Intra-domain Routing 프로토콜로 OSPF나 IS-IS를 선택하여 운영하게 되는데, 이와 같이 동일 IGP 프로토콜로 운영되는 하나의 망을 AS 혹은 Routing Domain이라 부릅니다.
아래 내용에 따르면 AS 보다는 Routing Domain이란 표현이 더 일반적인 듯 합니다.
The IETF concept of autonomous system (AS) is, in ISO terms, a routing domain. I much prefer the second term. These days, an AS has a specific meaning in BGP networks, to differentiate one area of autonomous administrative control from another, and as entries interconnected by EBGP. Whthin a single AS, multiple IGPs can be running. In contrast, a routing domain is always the scope of a single set of routers speaking the same routing protocol to each other, unbroken by any other routing protocol
출처: Jeff Doyle, OSPF and IS-IS: Choosing an IGP for Large-Scale Networks, 2005, Addison-Wesley
OSPF Network Topology
그림 상에 5개의 OSPF 라우터(R1 ~ R5)가 존재하고, 라우터간 연결 링크에 대한 IP 주소와 OSPF Link Cost 및 각 라우터의 OSPF Router ID(RID)인 Loopback 주소(예. R1의 경우 10.1.0.1/32)가 표시되어 있습니다.
각 라우터간 파란색 링크가 OSPF가 enable되어 있음을 표시하고 있고,
회색 링크는 OSPF가 enable되어 있지 않음을 표시하고 있습니다.
즉, R1에 직결된(connected) 100.1.1.0/24는 External Network이고, R2에서 라우터(회색 라우터)를 거쳐 연결된(static route) 200.1.1.0/24도 External Network이 됩니다.
앞서 설명 드린바와 같이 External Network과 연결되는 OSPF 라우터를 "OSPF 망의 가장자리(Border)에 위치한 라우터"의 의미로 ASBR(Autonomous System Border Router)이라 부릅니다.
ASBR: External 라우팅 정보를 OSPF 내부 라우터들로 전파
1. R1이 External Network (Connected Network) 정보를 전파
R1의 설정(redistribute connected subnets)에 의해서 External Network 100.1.1.0/24 정보가 AS-External-LSA를 통해 R2, R3로 전파됩니다[t=1]. 그리고 이를 수신한 R2, R3는 본 AS-External-LSA가 수신된 핑크를 제외한 링크로 AS-External-LSA를 flooding 합니다. 그래서 R4, R5는 동일한 AS-External-LSA를 2개씩 수신하는데[t=2], 이 경우 LSA 식별자인 {LS Type, Link State ID, Advertising Router}가 동일한 경우 두번째 수신한 LSA를 폐기합니다.
LS Type: Router-LSA(1), Network-LSA(2), AS-External-LSA(5) 등의 LSA 타입을 구분
Link State ID: AS-External-LSA인 경우 External Network 주소의 Prefix (address prefix of the external route)
Advertising Router: AS-External-LSA를 생성한 라우터의 ID (R1 OSPF RID, 즉, R1의 Loopback 주소인 10.1.0.1)
Metric: External Network과 OSPF Network 사이의 Link Cost (35)
이와 같이 R1이 보낸 AS-External-LSA를 R2 ~ R5가 수신하게 되면 각 라우터는 그 정보를 OSPF LSDB(Link State DataBase)에 저장하고 OSPF Network Topology 상에 해당 External Network으로 가기 위한 Shortest Path Tree를 구성하게 됩니다 (맨 밑에 그림 참조).
2. R2가 External Network (Static Route) 정보를 전파
R2의 설정(200.1.1.0/24로 가기 위한 static route 및 redistribute static subnets)에 의해서 External Network 200.1.1.0/24 정보가 AS-External-LSA를 통해 R1, R4, R5로 전파됩니다[t=1]. 그리고 이를 수신한 R1, R4, R5는 본 AS-External-LSA가 수신된 링크를 제외한 링크로 AS-External-LSA를 flooding 합니다.
R1, R3, R4, R5는 이 정보(AS-External-LSA)를 LSDB에 저장하고, OSPF Network Topology 상에 해당 External Network으로 가기 위한 Shortest Path Tree를 구성하게 됩니다 (맨 밑에 그림 참조).
역자 주: External Route를 OSPF 망으로 전파할때 2가지 옵션(External Type 1 & External Type 2) 중에 하나를 선택할 수 있습니다. 위 그림의 설정은 External Type 1(CLI 상에 metric-type 1)으로 예를 든 것입니다. 이 2가지 옵션에 대해서는 다음 기회에 설명을 드리도록 하겠습니다.
R1 ~ R5: Shortest Path Tree 구성하기
위에서 설명한 2개의 External Network(100.1.1.0/24, 200.1.1.0/24)에 대해 각 라우터는 최단 경로 즉, Shortest Path Tree를 구성하고, 이렇게 만들어진 Shortest Path 정보 즉, External Network Prefix와 최단경로로 가기 위한 Next Hop 정보가 라우터의 RIB(Routing Information Base)와 FIB(Forwarding Information Base)에 인스톨 됩니다. (예. R5는 External Network 200.1.1.0/24로 가기 위한 최단경로상의 Next Hop은 R2(1.1.5.1)이고, 100.1.1.0/24로 가기 위한 최단경로상의 Next Hop도 R2(1.1.5.1)임)
지난 시간에 LTE over MPLS L3VPN 망을 위한 IP/MPLS 프로토콜을 설명 드리면서 "모든 IP 라우터는 OSPF나 IS-IS와 같은 IGP 프로토콜을 이용하여 IP 망 토폴로지 정보를 서로간에 주고 받고, Shotest Path Tree 토폴로지를 구성한다"라고 말씀을 드렸었는데요.
오늘은 OSPF 프로토콜을 통해 어떻게 라우터들이 OSPF 망(IP 망)의 전체 토폴로지를 알아내고, Shortest Path Tree를 구성하는지 살펴보도록 보겠습니다.
사실 OSPF와 같은 라우팅 프로토콜은 라우팅 비전문가들에게는 그 원리를 이해하기가 쉽지 않은 기술 분야입니다. Cisco나 Juniper 장비의 라우팅 설정(CLI)을 잘 하시는 분들은 많이 보았는데, 프로토콜 원리를 이해하고 계시는 분들은 그리 많지 않은 듯 합니다.
오늘 설명은 "라우팅 비전문가"도 쉽게 그 기술을 이해할 수 있도록 "그림"을 많이 넣어 보았습니다.
OSPF 네트워크 토폴로지
그림 상에 5개의 OSPF 라우터(R1 ~ R5)가 존재하고, 라우터간 연결 링크에 대한 IP 주소와 OSPF Cost 및 각 라우터의 Loopback 주소(예. R1의 경우 10.1.0.1)가 표시되어 있습니다. 그리고 파란색 줄(링크)가 OSPF가 enable되어 있음을 표시하고 있습니다.
OSPF에서 얘기하는 Cost란 각 링크로 패킷을 전달하는데 드는 "소요 비용"으로 OSPF는 Cost가 작은 경로를 최적의 경로(Shortest Path)로 인식합니다. 통상적으로 Link Cost는 링크 속도(bandwidth of a link)에 따라 그 값을 정의합니다. 그래서 예로 100Mbps 링크보다는 1GE 링크 Cost가 작을 것이고, 1GE 링크 보다는 10GE 링크가 Cost가 작을 것입니다. (Link Cost는 라우터의 각 Interface별로 운영자가 CLI를 통해 설정함)
라우터간에 OSPF 프로토콜 메시지를 주고 받기 위해서는 각 라우터를 식별할 수 있는 IP 주소(OSPF RID(Router ID))가 필요한데 이를 위해 보통 Loopback 주소를 사용합니다. Physical Link의 IP 주소를 사용해도 상관은 없지만 다음과 같은 차이로 인해 Loopback 주소를 선호하지요.
Physical Link IP 주소 사용의 경우: 해당 Physical Link가 down 되는 경우 그 IP 주소가 사라짐. 즉, 이 주소를 OSPF RID로 사용한 OSPF 라우터는 더 이상 OSPF neighbor(나와 연결되어 있는 라우터)와 통신이 불가함
Loopback IP 주소 사용의 경우: Loopback 주소는 어떤 특정 Physical Link와 바인딩되어 있지 않은 Logical한 주소이기 때문에, Physical Link가 down되더라도 Loopback 주소는 계속 살아 있음
각 라우터는 자신의 링크 IP 주소를 다른 라우터들로 전파
1. R1이 자신의 링크 정보를 다른 OSPF 라우터들로 전파
R1은 자신의 Link(Interface) 주소와 Loopback 주소를 Router-LSA에 실어 R2, R3로 전달합니다[t = 1]. 그리고 이를 수신한 R2, R3는 Router-LSA가 수신된 링크를 제외한 나머지 링크로 Router-LSA를 flooding 합니다. 그래서 R4와 R5는 동일한 Router-LSA를 2개씩 수신합니다[t = 2]. 이 경우, LSA 식별자에 해당하는 {LS Type, Link State ID, Advertising Router}가 동일한 경우 두번째 수신한 LSA를 폐기합니다.
LS Type: Router-LSA (1), Network-LSA (2), External-LSA (5) 등의 타입을 구분
Link State ID: Router-LSA인 경우 Advertising Router와 동일 값 (10.1.0.1)
Advertising Router: Router-LSA를 생성한 라우터의 ID (OSPF RID 즉, Loopback 주소 = 10.1.0.1)
R1이 보낸 Router-LSA에 포함되는 정보는 다음과 같습니다. (위 그림의 우측 상단을 보세요)
Link Type: 링크 타입을 가리키는 값으로 그 타입에 따라 Link ID와 Link Data에 들어가는 값이 달라짐
Link Type = 1: Point-to-point connection(그림상에서 라우터간 연결은 모두 여기에 해당)
Link Type = 3: Stub network(라우터의 loopback 주소)
Link ID: R1과 연결된 OSPF Neighbor의 Router ID(Link Type=1, OSPF Neighbor간에 Hello 메시지를 주고 받는 과정에서 Neighbor의 RID를 알게 됨) 혹은 R1의 Loopback 주소(Link Type=3)
Link Data: R1의 Link IP 주소(Link Type=1) 혹은 R1의 Loopback 주소에 대한 subnet mask (/32 = 255.255.255.255)
Metric: 해당 Link의 cost(CLI로 각 링크의 cost는 설정함). Loopback 주소(stub network)인 경우 cost는 0
이와 같이 R1이 보낸 Router-LSA를 R2 ~ R5가 수신 하게 되면 각 라우터는 그 정보를 OSPF LSDB(Link State DataBase)에 저장하고 그 정보를 바탕으로 OSPF Topology를 그리게 됩니다. 현재까지의 정보로 R1 ~ R5 라우터가 알 수 있는 Topology는 다음과 같습니다.
R1의 Loopback 주소 (10.1.0.1/32)
R1의 Link 주소 1.1.1.1은 R2(10.1.0.2)와 연결되어 있음
R1의 Link 주소 1.1.2.1은 R3(10.1.0.3)과 연결되어 있음
2. R2가 자신의 링크 정보를 다른 OSPF 라우터들로 전파
R2는 자신의 Link(Interface) 주소와 Loopback 주소를 Router-LSA에 실어 R1, R4, R5로 전달하고[t = 1], 이를 수신한 R1, R4, R5는 Router-LSA가 수신된 링크를 제외한 나머지 링크로 Router-LSA를 flooding 합니다[t = 2].
R1, R3, R4, R5는 이 정보(Router-LSA)를 LSDB에 저장하고, 이제 위 그림과 같은 "OSPF Network Topology"를 알게 됩니다.
3. R3가 자신의 링크 정보를 다른 OSPF 라우터들로 전파
R3는 자신의 Link(Interface) 주소와 Loopback 주소를 Router-LSA에 실어 R1, R4, R5로 전달하고[t = 1], 이를 수신한 R1, R4, R5는 Router-LSA가 수신된 링크를 제외한 나머지 링크로 Router-LSA를 flooding 합니다[t = 2].
R1, R2, R4, R5는 이 정보(Router-LSA)를 LSDB에 저장하고, 이제 위 그림과 같은 "OSPF Network Topology"를 알게 됩니다.
4. R4가 자신의 링크 정보를 다른 OSPF 라우터들로 전파
R4는 자신의 Link(Interface) 주소와 Loopback 주소를 Router-LSA에 실어 R2, R3로 전달하고[t = 1], 이를 수신한 R2, R3는 Router-LSA가 수신된 링크를 제외한 나머지 링크로 Router-LSA를 flooding 합니다[t = 2].
R1, R2, R3, R5는 이 정보(Router-LSA)를 LSDB에 저장하고, 이제 위 그림과 같은 "OSPF Network Topology"를 알게 됩니다.
5. R5가 자신의 링크 정보를 다른 OSPF 라우터들로 전파
R5는 자신의 Link(Interface) 주소와 Loopback 주소를 Router-LSA에 실어 R2, R3로 전달하고[t = 1], 이를 수신한 R2, R3는 Router-LSA가 수신된 링크를 제외한 나머지 링크로 Router-LSA를 flooding 합니다[t = 2].
R1 ~ R4는 이 정보(Router-LSA)를 LSDB에 저장하고, 이제 위 그림과 같은 "OSPF Network Topology"를 알게 됩니다.
역자 주 1: 실제로는 모든 라우터가 동시 다발적으로 자신의 Router-LSA를 OSPF neighbor들로 flooding 하지만, 본 설명에서는 이해를 돕고자 각 라우터가 순차적으로 Router-LSA를 보낸다고 하였습니다.
역자 주 2: 라우터의 링크 타입을 point-to-point로 설정(CLI)해야 Router-LSA가 나가게 되고, 그렇지 않은 경우(예. broadcast 타입) Network-LSA가 나가게 됩니다. 라우터간 링크 연결은 point-to-point가 일반적이므로 초보자님들께서는 Router-LSA만 생각하세요~*
각 라우터에서 OSPF Topology 그림 그리기
5개의 라우터들간에 Router-LSA를 주고 받게 되면, 모든 OSPF 라우터는 동일한 LSDB를 가지게 됩니다.
그리고 이 LSDB를 통해 위 그림과 같이 각 라우터는 모두 동일한 그림의 OSPF Topology Map을 완성합니다.
Shortest Path Tree 구성하기
위에서 생성한 OSPF Topology를 기반으로 각 라우터는 목적지(Destination Network)로 가는 최단 경로 즉, Shortest Path Tree를 구성합니다.
그리고 이렇게 만들어진 Shortest Path 정보가 라우터의 RIB(Routing Information Base)와 FIB(Forwarding Information Base)에 인스톨 됩니다. (참고: RIB는 OSPF와 같은 라우팅 프로토콜이 돌고 있는 Control Plane에서 관리하는 라우팅 테이블이고, FIB는 패킷을 포워딩(wire-speed packet forwarding by packet processor)하는 Data Plane에 위치한 라우팅 테이블입니다.)
OSPF에 대해 좀 더 자세히 알고 싶으신 분들을 위해 2권의 책을 추천드립니다.
John T. Moy, "OSPF: Anatomy of an Internet Routing Protocol", 1998, Addison-Wesley
OSPF 창시자의 저서이고, 프로토콜 규격에 충실
Jeff Doyle, "OSPF and IS-IS: Choosing an IGP for Large-Scale Networks", 2005, Addison-Wesley
OSPF와 IS-IS를 비교하였고, 또한 프로토콜 규격의 설명과 Cisco/Juniper 장비 설정도 함께 다루고 있음 (추천!)
예전에 IP 분야 경력자 면접을 볼 때 우측 그림상에서 패킷 흐름/테이블 변화(아래 설명할 내용)를 화이트보드에 한번 그려 보라 한 적이 있는데요. 웃는 얼굴로 설명을 시작했지만 끝은 별로 좋지 않았다는...
지난 시간과 마찬가지로 망 구성도를 잘 봐 주시기 바랍니다. MAC/IP 값은 아래 테이블과 같습니다.
Server/Router
Port
MAC 주소
IP 주소
SVR1
lan1
m1
1.1.1.10
SVR3
lan1
m3
2.1.1.30
R1
ge1/1
a1
1.1.1.1
ge2/1
a2
2.1.1.1
IP Routing
1. SVR1 sends ARP Request
IP 주소 1.1.1.10인 SVR1이 목적지 주소 2.1.1.30인 SVR3로 패킷을 전송하려 합니다.
SVR1은 목적지 주소 2.1.1.30에 대해 자신의 Routing Table을 참조(lookup)하고, 그 결과 default route(0.0.0.0/0)에 매칭되어 "목적지로 가기 위해서는 Gateway는 1.1.1.1이고 출력 포트(OIF: Outgoing Interface)는 lan1"임을 알게 되었습니다. 보통 일반 PC의 경우 DHCP를 통해 IP 주소를 할당(임대) 받으면서 DHCP Option 3을 통해 Gateway 주소를 받아오고, 서버의 경우 운영자가 직접 Gateway 주소를 설정 합니다. 그러면 그 주소가 Routing Table에 인스톨 됩니다.
Gateway(Default Gateway라고도 함)란 SVR1과 연결된(중간에 L2 스위치가 여러개 있던 없던 간에) 첫번째 라우터를 의미하며 이 Gateway는 나(SVR1)와 동일 네트워크에 존재합니다. (그림상에서 SVR1(1.1.1.10)과 연결된 첫번째 라우터 R1의 인터페이스 주소 1.1.1.1이 Gateway가 됨)
SVR1은 Gateway 주소 1.1.1.1에 대한 MAC 주소가 ARP Table에 없어(ARP Miss) ARP Request 패킷을 lan1 포트로 내보내며 패킷 구성은 아래와 같습니다.
Header
Fields
Ethernet Header
* Destination MAC = FF:FF:FF:FF:FF:FF(브로드캐스팅, 동일 LAN에 있는 모든 노드로 전달) * Source MAC = Sender(SVR1)의 MAC 주소 m1
ARP Header
* Sender MAC = ARP Request 패킷 송신자(sender), 즉 SVR1의 MAC 주소 m1 * Sender IP = ARP Request 패킷 송신자(sender), 즉 SVR1의 IP 주소 1.1.1.10 * Target MAC = 00:00:00:00:00:00임 (SVR1은 이 값을 알고 싶어 하는 것임) * Target IP = ARP Request 패킷 수신자(target), 즉 R1의 IP 주소 1.1.1.1
이제 이 패킷을 수신한 S1(스위치 1)은 Source MAC Learning을 수행(MAC 주소 m1은 fe1 포트에 연결되어 있음을 MAC Table에 저장)하고,
수신 패킷의 Destination MAC 주소를 참조하여 출력 포트를 정하게 되는데 이 경우는 브로드캐스팅 주소(FF:FF:FF:FF:FF:FF)입니다. 따라서 S1은 수신 포트를 제외한 나머지 포트로 Flooding 합니다. 따라서 이 패킷은 SVR2와 R1(라우터 1)이 수신합니다.
SVR2는 수신된 ARP Request 패킷의 Target IP 주소가 자신의 것이 아님을 확인 후 버립니다.
2. R1 responds with ARP Reply
ARP Request를 수신한 R1(라우터 1)은 Target IP 주소를 보고 자신의 MAC 주소를 물어 본 것임을 압니다. 따라서 R1은 1.1.1.1에 대한 MAC 주소를 Sender MAC 필드에 담아 ARP Reply 패킷을 ge1/1 포트로 내보내며, 그 패킷의 구성은 아래와 같습니다.
Header
Fields
Ethernet Header
* Destination MAC = ARP Reply를 수신할 SVR1의 MAC 주소 m1 *Source MAC = Sender(R1)의 MAC 주소 a1
ARP Header
* Sender MAC = ARP Reply 패킷 송신자(sender), 즉 R1의 MAC 주소 a1 * Sender IP = ARP Reply 패킷 송신자(sender), 즉 R1의 IP 주소 1.1.1.1 * Target MAC = ARP Reply 패킷 수신자(target), 즉 SVR1의 MAC 주소 m1 * Target IP = ARP Reply 패킷 수신자(target), 즉 SVR1의 IP 주소 1.1.1.10
이 패킷을 수신한 S1은 Source MAC Learning을 수행(MAC 주소 a1은 fe3 포트에 연결되어 있음을 MAC Table에 저장)하고,
수신 패킷의 Destination MAC 주소 m1에 대한 MAC Table을 참조하여 해당 패킷을 fe1 포트로 패킷을 전달(유니캐스팅)합니다.
그리고 이 패킷을 수신한 SVR1은 자신의 ARP Table에 그 값(1.1.1.1의 MAC 주소 a1)을 저장합니다.
3. SVR1 sends IP Packet to R1
이제 SVR1은 SVR3로 IP 패킷을 보낼 준비가 되었습니다. SVR1은 아래와 같이 패킷을 구성하여 lan1 포트로 내보냅니다.
Header
Fields
Ethernet Header
* Destination MAC = Receiver(R1)의 MAC 주소 a1 * Source MAC = Sender(SVR1)의 MAC 주소 m1
IP Header
* Destination IP = Receiver(SVR3)의 IP 주소 2.1.1.30 * Source IP = Sender(SVR1)의 IP 주소 1.1.1.10
이 패킷을 수신한 S1은 이미 Learning된 Source MAC 주소이므로 Source MAC Learning 과정은 생략하고, Destination MAC 주소 a1에 대한 MAC Table 참조를 통해 fe3 포트로 패킷을 보냅니다.
4. R1 sends ARP Request
패킷을 수신한 R1(라우터 1)은 자신의 FIB(Routing Table)를 참조하여 "목적지 주소 2.1.1.30은 나와 바로 붙어 있는 네트워크이고(Next Hop이 없으므로) 출력 포트는 ge2/1"라는 사실을 알게 되고,
이제 R1은 2.1.1.30에 대한 MAC 주소를 알기 위해 ARP Table을 참조합니다. 하지만 해당 엔트리가 없습니다(ARP Miss). 따라서 R1은 아래와 같이 ARP Request 패킷을 ge2/1 포트로 내보냅니다.
Header
Fields
Ethernet Header
* Destination MAC = FF:FF:FF:FF:FF:FF(브로드캐스팅, 동일 LAN에 있는 모든 노드로 전달) * Source MAC = Sender(R1)의 MAC 주소 a2
ARP Header
* Sender MAC = ARP Request 패킷 송신자(sender), 즉 R1의 MAC 주소 a2 * Sender IP = ARP Request 패킷 송신자(sender), 즉 R1의 IP 주소 2.1.1.1 * Target MAC = 00:00:00:00:00:00임 (R1은 이 값을 알고 싶어 하는 것임) * Target IP = ARP Request 패킷 수신자(target), 즉 SVR3의 IP 주소 2.1.1.30
이 패킷을 수신한 S2(스위치 2)는 Source MAC Learning을 수행(MAC 주소 a2는 fe3 포트에 연결되어 있음을 MAC Table에 저장)하고,
수신 패킷의 Destination MAC 주소를 참조하여 출력 포트를 결정하는데 이 경우는 브로드캐스팅 주소(FF:FF:FF:FF:FF:FF)입니다. 따라서 S2는 수신 포트를 제외한 나머지 포트로 Flooding 합니다. 따라서 이 패킷은 SVR3과 SVR4가 수신합니다.
SVR4는 수신된 ARP Request 패킷의 Target IP 주소가 자신의 것이 아니므로 버립니다.
5. SVR3 responds with ARP Reply
ARP Request를 수신한 SVR3은 Target IP 주소를 보고 자신의 것임을 압니다. 따라서 SVR3은 2.1.1.30에 대한 MAC 주소를 Sender MAC 필드에 담아 ARP Reply 패킷을 lan1 포트로 내보내며, 그 패킷의 구성은 아래와 같습니다.
Header
Fields
Ethernet Header
* Destination MAC = ARP Reply를 수신할 R1의 MAC 주소 a2 * Source MAC = Sender(SVR3)의 MAC 주소 m3
ARP Header
* Sender MAC = ARP Reply 패킷 송신자(sender), 즉 SVR3의 MAC 주소 m3 * Sender IP = ARP Reply 패킷 송신자(sender), 즉 SVR3의 IP 주소 2.1.1.30 * Target MAC = ARP Reply 패킷 수신자(target), 즉 R1의 MAC 주소 a2 * Target IP = ARP Reply 패킷 수신자(target), 즉 R1의 IP 주소 2.1.1.1
이 패킷을 수신한 S2는 Source MAC Learning을 수행(MAC 주소 m3는 fe1 포트에 연결되어 있음을 MAC Table에 저장)하고,
수신 패킷의 Destination MAC 주소 a2에 대한 MAC Table을 참조하여 해당 패킷을 fe3 포트로 패킷을 전달(유니캐스팅)합니다.
그리고 이 패킷을 수신한 R1은 자신의 ARP Table에 그 값(2.1.1.30의 MAC 주소 m3)을 저장합니다.
6. R1 sends IP Packet to SVR3
SVR3의 MAC 주소를 알았으므로, 이제 R1(라우터 1)은 SVR1에서 SVR3로 향하는 패킷을 IP 라우팅 할 수 있습니다. R1은 아래와 같은 구성으로 SVR1이 보낸 패킷을 SVR3로 라우팅 시켜 줍니다.
Header
Fields
Ethernet Header
* Destination MAC = Receiver(SVR3)의 MAC 주소 m3 * Source MAC = Sender(R1)의 MAC 주소 a2
IP Header
* Destination IP = Receiver(SVR3)의 IP 주소 2.1.1.30 * Source IP = Sender(SVR1)의 IP 주소 1.1.1.10
이 패킷을 수신한 S2(스위치 2)는 이미 Learning된 Source MAC 주소이므로 Source MAC Learning 과정은 건너뛰고, Destination MAC 주소 m3에 대한 MAC Table 참조를 통해 fe1 포트로 패킷을 전송하여 SVR3가 패킷을 수신합니다.
정리
모든 단말/서버(이하 서버로 부름)는 스위치와 라우터를 통해 다른 서버와 연결되어 있습니다.
서버에서 보낸 패킷이 Ethernet Switching 될 것이냐 IP Routing 될 것이냐는 결정은 패킷을 송신하는 서버에서 이미 결정이 됩니다.
지난 시간에 설명드린 바와 같이 패킷 송신 서버는 목적지 주소(1.1.1.20)가 나(1.1.1.10)와 동일 네트워크에 존재하면 해당 목적지 단말의 MAC 주소를 Destination MAC으로 하여 패킷을 전달하고 이 패킷은 스위치를 통해 Ethernet Switching 되어 수신 서버로 전달됩니다.
반면 오늘 설명과 같이 목적지 주소(2.1.1.30)가 나(1.1.1.10)와 다른 네트워크에 존재하는 경우 해당 목적지가 아닌 Gateway (1.1.1.1)의 MAC 주소를 Destination MAC으로 하여 패킷을 전달하는데, 이 때의 Gateway는 서버와 연결된 첫번째 L3 Hop, 즉 라우터(R1) 입니다. 따라서 이 패킷은 목적지 주소가 라우터 MAC 이므로 중간에 스위치가 있어도 Ethernet Switching 되어 라우터로 도착할 것이고, 라우터는 수신 패킷의 Destination MAC이 자신의 것임을 확인 한 후에 FIB lookup을 하여 IP Routing(혹은 Forwarding이라 부름) 하게 됩니다.
방금 중요한 포인트를 말씀드렸습니다.
"라우터는 수신 패킷의 Destination MAC 주소가 내 MAC이면 라우팅, 아니면 폐기합니다."
단, Destination MAC 주소가 FF:FF:FF:FF:FF:FF인 경우는 일단 라우터의 Control Plane이 받아 봅니다. 위에서 R1이 ARP Request 패킷을 수신하여 처리한 것과 같이요.
제목이 좀 유치하죠? ^^* 말랑 말랑한 블로그 공간에서의 표현이므로 너그럽게 봐 주시기 바랍니다.
오늘과 내일에 걸쳐 L2(Ethernet) 스위칭과 L3(IP) 라우팅 과정에서 살펴 보도록 하겠습니다. 본 글을 통해 다음과 같은 내용을 설명 드리도록 하겠습니다.
ARP와 IP 패킷
스위칭/라우팅 과정에서 Ethernet Header의 변화
스위칭/라우팅 과정 전후로 단말과 스위치, 라우터의 테이블(Routing, ARP, MAC Table) 엔트리 변화
Switching과 Routing
위 그림은 앞으로(오늘과 내일) 설명드릴 망 구성도이므로 잘 봐 주시기 바랍니다. (특히 서버/라우터의 MAC, IP 주소, 스위치/라우터의 포트(인터페이스) 번호)
좌측 그림과 같이 Sender(SVR1)와 Receiver(SVR2)가 동일 네트워크(LAN)에 위치해 있는 경우 라우터 R1을 거치지 않고 스위치 S1을 통해 바로 통신이 되며 이 때의 패킷 구성은 다음과 같습니다. (동일 네트워크인지 아닌지 어떻게 구분하는지 궁금하시면 여기를 클릭)
Header
Fields
Ethernet Header
* Destination MAC = Receiver(SVR2)의 MAC 주소 m2 * Source MAC = Sender(SVR1)의 MAC 주소 m1
IP Header
* Destination IP = Receiver(SVR2)의 IP 주소 1.1.1.20 * Source IP = Sender(SVR1)의 IP 주소 1.1.1.10
반면 우측 그림과 같이 Sender(SVR1)와 Receiver(SVR3)가 동일 네트워크(LAN)에 위치하지 않은 경우 라우터 R1을 거치게 되는데 이 때의 Ethernet Header 필드는 라우터를 사이에 두고 서로 값을 가지게 됩니다.
SVR1에서 R1으로 패킷 전송시
Header
Fields
Ethernet Header
* Destination MAC = Router(R1의 ge1/1)의 MAC 주소 a1 * Source MAC = Sender(SVR1)의 MAC 주소 m1
IP Header
* Destination IP = Receiver(SVR3)의 IP 주소 2.1.1.30 * Source IP = Sender(SVR1)의 IP 주소 1.1.1.10
R1에서 SVR3로 패킷 전송시
Header
Fields
Ethernet Header
* Destination MAC = Receiver(SVR3)의 MAC 주소 m3 * Source MAC = Router(R1의 ge2/1)의 MAC 주소 a2
IP Header
* Destination IP = Receiver(SVR3)의 IP 주소 2.1.1.30 * Source IP = Sender(SVR1)의 IP 주소 1.1.1.10
Ethernet Switching
그림을 그리다 보니 너무 길쭉해 졌습니다. (다음 시간 그림은 더 길어요~)
1. SVR1 sends ARP Request
IP 주소 1.1.1.10을 가진 SVR1이 목적지 주소 1.1.1.20인 SVR2로 패킷을 전송하려 합니다.
서버든 라우터든 패킷을 보내기 위해서는 일단 Routing Table을 참조합니다. Routing Table Lookup 결과 목적지 주소는 나(SVR1)와 동일 네트워크에 존재하고(라우팅 엔트리 1.1.1.0/24에 Gateway가 없음이 나와 동일 네트워크임을 나타냄), 출력 포트(OIF: Outgoing Interface)는 lan1입니다(그림에서 서버의 포트는 하나만 그렸으므로 다 lan1이죠).
이제 SVR1은 목적지 주소 1.1.1.20에 대한 MAC 주소를 알기 위해 자신의 ARP Table을 참조합니다. 그런데 테이블이 비어 있습니다. (해당 엔트리가 없으면 ARP Miss라 부름)
따라서 SVR1은 SVR2(1.1.1.20)의 MAC 주소를 알아내기 위해 lan1 포트로 ARP Request를 보냅니다. ARP Request 패킷은 아래와 같이 구성됩니다.
Header
Fields
Ethernet Header
* Destination MAC = FF:FF:FF:FF:FF:FF(브로드캐스팅, 동일 LAN에 있는 모든 단말로 전달) * Source MAC = Sender(SVR1)의 MAC 주소 m1
ARP Header
* Sender MAC = ARP Request 패킷 송신자(sender), 즉 SVR1의 MAC 주소 m1 * Sender IP = ARP Request 패킷 송신자(sender), 즉 SVR1의 IP 주소 1.1.1.10 * Target MAC = 00:00:00:00:00:00임 (SVR1은 이 값을 알고 싶어 하는 것임) * Target IP = ARP Request 패킷 수신자(target), 즉 SVR2의 IP 주소 1.1.1.20
이제 이 패킷은 S1(스위치 1)이 수신하고, 수신 패킷(스위치는 수신 패킷이 IP 패킷인지 ARP 패킷인지 관심 없음)의 Source MAC 주소를 배웁니다. 따라서 S1의 MAC Table에는 {MAC 주소 m1은 fe1 포트에 연결되어 있음}이 기록됩니다.
Source MAC Learning 직후 S1은 수신 패킷의 Destination MAC 주소를 봅니다. 브로드캐스팅 주소네요. 따라서 S1은 수신 포트를 제외한 나머지 모든 포트로(VLAN 설정이 있다면 동일 VLAN에 속한 모든 포트로) Flooding 합니다. 그래서 이 ARP Request 패킷은 SVR2와 라우터 R1이 수신을 합니다.
R1은 수신된 ARP Request 패킷의 Target IP 주소를 보고 이 주소가 내 것이 아님을 알고(R1이 소유한 주소는 1.1.1.1과 2.1.1.1) 버립니다.
2. SVR2 responds with ARP Reply
ARP Request를 수신한 SVR2도 Target IP 주소를 봅니다. 내 주소네요. 따라서 SVR2는 1.1.1.20에 대한 MAC 주소를 Sender MAC 필드에 담아 ARP Reply 패킷을 lan1 포트로 내보냅니다. ARP Reply 패킷은 아래와 같이 구성됩니다.
Header
Fields
Ethernet Header
* Destination MAC = ARP Reply를 수신할 SVR1의 MAC 주소 m1 * Source MAC = Sender(SVR2)의 MAC 주소 m2
ARP Header
* Sender MAC = ARP Reply 패킷 송신자(sender), 즉 SVR2의 MAC 주소 m2 * Sender IP = ARP Reply 패킷 송신자(sender), 즉 SVR2의 IP 주소 1.1.1.20 * Target MAC = ARP Reply 패킷 수신자(target), 즉 SVR1의 MAC 주소 m1 * Target IP = ARP Reply 패킷 수신자(target), 즉 SVR1의 IP 주소 1.1.1.10
이 패킷을 수신한 S1은 Source MAC Learning을 하여 MAC Table에 {MAC 주소 m2는 fe2 포트에 연결되어 있음}를 기록하고,
수신 패킷의 Destination MAC 주소 m1에 대해 MAC Table을 참조하여 fe1 포트로 패킷을 전달(유니캐스팅)합니다.
그리고 이를 수신한 SVR1은 자신의 ARP Table에 그 값(1.1.1.20의 MAC 주소 m2)을 기록합니다.
3. SVR1 sends IP Packet to SVR2
이제 SVR1은 SVR2로 IP 패킷을 보낼 준비가 되었습니다. 따라서 SVR1은 아래와 같은 구성의 IP 패킷을 lan1 포트로 내보냅니다.
Header
Fields
Ethernet Header
* Destination MAC = Receiver(SVR2)의 MAC 주소 m2 * Source MAC = Sender(SVR1)의 MAC 주소 m1
IP Header
* Destination IP = Receiver(SVR2)의 IP 주소 1.1.1.20 * Source IP = Sender(SVR1)의 IP 주소 1.1.1.10
이 패킷을 수신한 S1(스위치 1)은 Source MAC Learning을 하려 봤더니 Source MAC 주소 m1은 이미 배운 MAC 입니다. 따라서 MAC Learning은 필요 없구요. Destination MAC 주소 m2를 MAC Table에서 찾아 보았더니 fe2 포트로 내보내면 된다고 적혀 있습니다.
저장소로 디스크 대신 메인 메모리를 사용하는 것은 전혀 새로운 시도가 아니다. 디스크보더 더 빨리 수행 결과를 얻기 위해 MMDB(Main Memory DBMS)를 사용하는 사례는 일상에서도 찾을 수 있다. 대표적인 예는 휴대 전화를 사용할 때이다. SMS나 통화를 시도할 때 상대방 정보를 빠른 시간 안에 찾기 위해 대부분의 통신사는 MMDB를 사용하고 있다.
IMDG(In Memory Data Grid)는 메인 메모리에 데이터를 저장한다는 점에서 MMDB와 같지만 아키텍처가 매우 다르다. IMDG의 특징을 간단히 정리하면 다음과 같다.
데이터가 여러 서버에 분산돼서 저장된다.
각 서버는 active 모드로 동작한다.
데이터 모델은 보통 객체 지향형(serialize)이고 non-relational이다.
필요에 따라 서버를 추가하거나 줄일 수 있는 경우가 많다.
즉, IMDG는 데이터를 MM(Main Memory)에 저장하고 확장성(Scalability)을 보장하며, 객체 자체를 저장할 수 있도록 구현됐다. 오픈 소스와 상용 제품을 구별하지 않으면 다음과 같은 IMDG 제품이 있다.
이 글에서는 제품의 기능과 성능을 비교하지는 않고, IMDG의 아키텍처를 살펴보고 어떻게 활용할 수 있을지 검토해 볼 것이다.
왜 메모리?
2012년 6월 현재 SATA(Serial ATA) 인터페이스를 사용하는 SSD(Solid State Drive)의 성능은 약 500MB/s 정도이고, 고가의 PCI Express를 사용하는 SSD는 약 3,000MB/s에 이른다. 10,000 RPM SATA HDD의 성능이 약 150MB/s 정도니까 SSD가 HDD보다 4~20배 정도 빠르다고 할 수 있다. 하지만 이에 반해 DDR3-2500의 성능은 20,000MB/s에 이른다. 메인 메모리의 처리 성능은 HDD보다 800배, 일반적인 SSD보다 40배, 가장 빠른 SSD보다 약 7배 빠르다. 게다가 요즘의 x86 서버는 서버 하나당 수백 GB 용량의 메인 메모리를 지원한다.
Michael Stonebraker에 따르면 전형적인 OLTP(online transaction processing) 데이터 용량은 약 1TB 정도이고, OLTP 처리 데이터 용량은 잘 증가하지 않는다고 한다. 만약 1TB 이상의 메인 메모리를 사용하는 서버 사용이 보편화된다면, 적어도 OLTP 분야에서는 모든 데이터를 메인 메모리에 둔 채 연산을 하는 것이 가능해진다.
컴퓨팅 역사에서 '좀 더 빠르게'는 언제나 최고의 덕목으로 추구해야 할 가치였다. 이렇게 메인 메모리 용량이 증가하게 된 만큼 영구 저장소 대신 메인 메모리를 저장소로 사용하는 플랫폼이 등장할 수 밖에 없게 된 것이다.
IMDG 아키텍처
메인 메모리를 저장소로 사용하려면 극복해야 하는 약점 두 가지가 있다. 용량의 한계와 신뢰성이다. 서버의 메인 메모리의 최대 용량을 넘어서는 데이터를 처리할 수 있어야 하고, 장애 발생 시 데이터 손실이 없도록 해야 한다.
IMDG는 용량의 한계를 분산 아키텍처를 이용하여 극복한다. 여러 기기에 데이터를 나누어 저장하는 방식으로 전체 용량 증가를 꾀하는 Horizontal Scalability 방식을 사용한다. 또한 신뢰성은 복제 시스템을 구성해 해결한다.
제품마다 세세한 차이가 있지만 IMDG 아키텍처를 일반화하면 그림 1과 같이 나타낼 수 있다.
그림 1 IMDG 아키텍처
애플리케이션 서버(AS)에는 IMDG가 제공하는 클라이언트 라이브러리가 있고, 이 라이브러리를 이용해 IMDG에 접근한다.
많은 IMDG 제품이 데이터를 RDBMS 등에 동기화하는 기능을 제공한다. 그러나 이러한 별도의 영구 저장 시스템(RDBMS 등)을 반드시 구성해야 하는 것은 아니다. 일반적으로 IMDG에서는 직렬화를 통해 객체를 저장할 수 있도록 한다. Serializable 인터페이스를 구현한 객체를 저장할 수 있도록 한 제품도 있고, 독자적인 직렬화 방법을 제공하는 IMDG도 있다. 당연히 schemaless 구조라 사용 편의성이 매우 높다.
개념상 객체를 저장하고 조회할 수 있도록 한 In Memory Key-Value Database로 이해할 수 있다. IMDG에서 사용하는 데이터 모델은 Key-Value 모델이다. 그래서 이 키(key)를 이용해 데이터를 분산시켜 저장할 수 있다. NHN에서 사용하는 분산 메모리 캐싱 시스템인 Arcus와 같이 Consistency Hash 모델을 사용하는 것부터Hazelcast와 같이 단순한 modulo 방식을 사용하는 것까지 다양한 방식이 있다. 이렇게 저장할 때 반드시 하나 이상의 다른 노드를 복제 시스템으로 삼아서 장애 발생에 대처할 수 있도록 한다.
인터페이스는 제품별로 다양하다. 어떤 제품은 SQL-like한 형태의 문법을 제공하여 JDBC를 통해 접근하는 제품도 있고, Java의 Collection을 구현한 API를 제공하는 경우도 있다. 즉 여러 노드를 대상으로 하는 HashMap이나 HashSet을 사용할 수 있는 것이다.
IMDG는 Arcus와 같은 캐시 시스템과는 사용과 목적이 다르다. 그림 2는 Arcus의 아키텍처를 간단하게 표현한 것이다.
그림 2 캐시 시스템인 Arcus의 아키텍처
Arcus와 같은 캐시 시스템도 메인 메모리를 저장소로 사용하고 Horizontal Scalability를 확보했다는 점에서는 IMDG와 같다. 하지만 그림 1과 그림 2에서와 같이 사용 형태와 목적은 크게 다르다. 캐시 시스템에서 영구 저장소의 사용은 필수이지만, IMDG에서 영구 저장소의 사용은 선택이다.
표 1 캐시 시스템과 IMDG의 읽기, 쓰기 성능 비교
캐시 시스템
IMDG
읽기
캐시 안에 데이터가 있다면 데이터 베이스에서 읽어오지 않는다. 캐시 안에 데이터가 없을 때는 데이터베이스에서 읽어온다.
언제나 IMDG에서만 읽어온다. 항상 메인 메모리에서 읽어오기 때문에 빠르다.
쓰기
영구 저장소에 쓰기 때문에 캐시 시스템 적용과 쓰기 성능 향상은 관계 없다.
영구 저장소에 데이터를 동기화하도록 구성하더라도, 제품에 따라 비동기 쓰기를 지원하는 제품이 있다. 비동기 쓰기를 지원하는 경우에는 매우 높은 수준의 쓰기 성능을 기대할 수 있다.
이외에도 데이터를 마이그레이션할 수 있는지, 신뢰성을 보장하는지, 복제 기능을 제공하는지 등의 차이가 캐시 시스템과 IMDG의 차이다.
IMDG의 기능
다음은 IMDG 제품 가운데 하나인 Hazelcast의 기능이다. HazelCast는 더블 라이선스 정책을 취하고 있는 제품으로, ElasticMemory와 같은 기능을 사용하려면 상용 라이선스를 구입해야 한다. 그러나 많은 기능이 오픈소스라서 별도의 비용 없이 사용할 수 있으며, 사용 레퍼런스 정보를 찾아 보기가 매우 쉽다.
HazelCast의 기능이 다른 모든 IMDG에서 제공하는 일반적인 기능이라고 할 수는 없지만 IMDG의 기능을 살펴보기에는 매우 좋은 예라서 간단하게 소개하겠다.
DistributedMap & DistributedMultiMap
Map<?, ?>을 구현한 클래스다. 여러 IMDG 노드에 Map 데이터가 분산 배치된다.
RDBMS의 테이블(table)은 Map<Object key, List<Object>>로 표현할 수 있기 때문에, RDBMS를 샤딩해서 쓰는 것과 비슷한 데이터 분산 효과를 얻을 수 있다. 더구나 HazelCast는 DistributedMap에서 SQL-like한 기능을 사용할 수 있도록 했다. Map에 있는 value를 검사할 때 WHERE 구문이나 LIKE, IN, BETWEEN 같은 SQL-like 구문을 사용할 수 있다.
HazelCast는 모든 데이터를 메모리에 두는 것뿐만 아니라 영구 저장소에 저장하는 기능도 제공한다. 이렇게 영구 저장소에 데이터를 저장하면 캐시 시스템으로 사용하도록 구성할 수 있다. LRU(Least Recently Used) 알고리즘이나 LFU(Least Frequently Used) 알고리즘을 선택해, 꼭 필요한 데이터만 메모리에 두고 상대적으로 잘 찾지 않는 나머지 데이터는 영구 저장소에 두게 할 수도 있다.
또한 MultiMap을 분산 환경에서 사용할 수 있도록 했다. 어떤 key를 조회하면 Collection <Object> 형태의 value 목록을 얻을 수 있다.
Distributed Collections
DistributedSet이나 DistributedList, DistributedQueue 등을 사용할 수 있다. 이런 Distributed Collection 객체에 있는 데이터는 어느 하나의 IMDG 노드가 아니라 여러 노드가 분산 저장된다. 그렇기 때문에 여러 노드에 저장된 단 하나의 List 객체 또는 Set 객체 유지가 가능하다.
DistributedTopic & DistributedEvent
HazelCast는 publish 순서를 보장하는 Topic 읽기가 가능하다. 즉 분산 Message Queue 시스템으로 이용할 수 있다는 뜻이다.
DistributedLock
말 그대로 분산 Lock이다. 여러 분산 시스템에서 하나의 Lock을 사용해 동기화할 수 있다.
Transactions
DistributedMap, DistributedQueue 등에 대한 트랜잭션을 사용할 수 있다. 커밋/롤백을 할 수 있기 때문에 더 신중한 연산이 필요한 곳에서도 IMDG를 사용할 수 있다.
대용량 메모리 사용과 GC
앞에서 소개한 대부분의 제품은 구현 언어로 Java를 사용한다. 수십 GB 크기의 힙을 사용해야 하는 만큼 Full GC에 필요한 시간도 상당히 오래 걸릴 수 있다. 그렇기 때문에 IMDG에서는 이런 제약을 극복할 수 있는 방법을 마련해 적용하고 있다. 바로 Off-heap 메모리(Direct Buffer)를 사용하는 것이다.
JVM에 Direct Buffer 생성을 요청하면 JVM은 힙 바깥의 공간에서 메모리를 할당해 사용한다. 이렇게 할당한 공간에 객체를 저장하도록 하는 것이다. Direct Buffer는 GC 대상 공간이 아니기 때문에, Full GC 문제가 발생하지 않게 된다. 보통 Direct Buffer에 대한 접근은 Heap Buffer보다 느리다. 하지만 큰 공간을 할당할 수 있고 Full GC에 대한 부담을 줄일 수 있기 때문에 매우 큰 용량의 메모리 공간을 사용할 때 Full GC 시간을 없앨 수 있어 항상 일정한 처리 시간을 확보할 수 있다는 것이 장점이다.
그림 3 Heap Buffer와 Direct Buffer 디스크 비교(이미지 출처: Terracotta)
그러나 Direct Buffer를 이용해 객체를 저장하고 조회하는 데는, Memory Allocator를 만드는 것과 같은 매우 전문적인 기술이 필요하다. 그렇기 때문에 이러한 Off-heap 메모리를 사용해 객체를 저장하는 기능은 상용 IMDG에서만 제공하고 있다.
마치며
현재까지 IMDG를 주로 사용하는 곳은 캐시 시스템이다. 그러나 IMDG는 주저장소로 발전될 가능성이 매우 높은 플랫폼이다. 많은 경우 분산 Map은 충분히 RDBMS의 테이블을 대신할 수 있다. 제품에 따라 분산 Lock을 제공하는 제품이 있는데, 이런 분산 Lock을 바탕으로 정합성(Integrity Constraint) 기능을 제공할 수 있다면, 본격적으로 RDBMS를 대체할 수 있다.
이렇게 할 경우 백엔드 시스템으로 RDBMS를 사용해 통계 처리에 대응할 수 있을 것이다. 인터넷 서비스에서 RDBMS 사용이 보조 목적으로 바뀌는 것이다. 정합성 기능이 제공된다면 빠른 속도를 바탕으로 한 쾌적한 사용자 경험은 물론, 빠른 처리 속도를 바탕으로 그동안 제공하기 어려웠던 기능을 제공할 수 있는 기회가 생기는 것이다.
그림 4 정합성을 지원하는 IMDG 출처 - http://d2.naver.com/helloworld/106824
TCP의 가장 중요한 목적인 신뢰성 있는 전송이라는 측면에서 보면, TCP 패킷 헤더에서 가장 중요한 정보는 Sequence & Ack number이다. 그렇다면 TCP는 이 field에 무엇을 채우는가? 이것과 관련해서 TCP가 데이터를 어떻게 다루는지를 이해하는 것이 중요하다. TCP는 데이터를 바이트 단위로 다룬다. 즉 전송해야할 데이터를 순서대로 정렬된 바이트 스트림으로 취급한다는 이야기다. 따라서 모든 Sequence number와 Ack number는 바이트 단위로 표시된다.
설명을 하기 전에 새로운 용어에 대해서 말할 필요가 있을 것 같다. 바로 MSS (Max Segment Size)인데, 이것은 TCP가 한번에 보낼 수 있는 최대의 데이터 량을 의미한다. 또한 MSS를 직역하면 최대 세그먼트 크기인데 여기에서 TCP가 자신이 보내는 패킷의 기본 단위를 세그먼트라고 부른다는 것을 알 수 있다. 이제까지 설명을 할 때 좀 더 친숙한 용어인 패킷으로 설명했지만, 이제부터 TCP와 관련된 설명을 할 때에는 세그먼트라는 단어를 사용하도록 하겠다.
예를 들어 5000byte 짜리 파일을 전송하는 경우를 살펴보자. 이 때의 MSS가 100byte라고 생각하면 TCP는 5000 byte짜리 파일을 전송하기 위해 50개의 세그먼트를 생성하게 될 것이다. (5000 / 100 = 50). 이런 경우 TCP는 각 세그먼트의 Sequence Number Field에 Byte 기준 번호를 붙인다. 즉, 첫 번째 세그먼트의 Sequence number가 0이라 가정하면 두 번째 세그먼트는 100번, 세번째 세그먼트는 200번의 식으로 Sequence number가 설정된다.
그렇다면 Ack 번호는 어떠한가? Ack번호의 경우에는 Sequence number보다 약간 복잡한데, 그것은 말 그대로 받은 것에 대한 응답이기 때문이다. 기본적으로 Ack번호는 수신자의 입장에서 송신자로부터 앞으로 받아야할 다음 데이터의 Sequence number이다. 말이 복잡한데, 예를 들어보자. 위에서 든 예에서 만일 송신자가 첫 번째 세그먼트를 보냈다고 생각해보자. 수신자가 데이터를 받으면 그 데이터의 Sequence number는 0번일 것이고 MSS가 100 byte이기 때문에 0번째 byte부터 99번째 byte까지의 데이터가 도착했을 것이다. 그러면 수신자는 자신이 99번째 byte까지 잘 받았고, 앞으로 100번째 byte로 시작되는 세그먼트를 받기 원한다는 표시로 Ack번호를 100으로 붙여 응답하는 것이다.
이것은 송신자에게 있어서 수신자의 상태에 대해 부가적인 정보를 주는데, 이 정보는 자신이 어떤 데이터를 보내야할지, 즉 새로운 데이터 스트림을 줘야할지 아니면 이미 보낸 데이터를 재전송해야할지를 결정할 수 있는 중요한 것이다.
이 점을 이해하기 위해 또 다른 예를 들어보자. 위의 파일 전송에서 송신자가 순서대로 3개의 세그먼트를 보냈다고 생각해보자. 즉 Sequence number 0, 100, 200번의 3개의 세그먼트를 통해 300byte를 전송한 것이다. 그런데 첫번째 세그먼트와 세번째 세그먼트는 수신자에게 잘 도착했는데 두 번째 세그먼트가 네트웍에서 손실되었다고 생각했을 때 수신자는 송신자에게 어떻게 응답해야 하는가?
수신자의 입장에서 생각해 보면 현재 두 개의 세그먼트를 받았다. Sequence number 0번의 0~99번째까지의 100byte와 Sequence number 200번의 200 ~ 299번째까지의 100byte이다. 이 때 수신자는 중간의 100 ~ 199번째의 데이터를 기대한다는 의미로 Ack number 100으로 응답할 수 있다. 그러면 송신자는 수신자가 두 번째 세그먼트를 못받았다는 것을 알고 다시 재전송할 수 있다.
Reference : Computer Networking (A top down approach featuring the internet), James F. Kurose, Keith W. Ross 저.
300(여러 선택항목): 서버가 요청에 따라 여러 조치를 선택할 수 있다. 서버가 사용자 에이전트에 따라 수행할 작업을 선택하거나, 요청자가 선택할 수 있는 작업 목록을 제공한다.
301(영구 이동): 요청한 페이지를 새 위치로 영구적으로 이동했다. GET 또는 HEAD 요청에 대한 응답으로 이 응답을 표시하면 요청자가 자동으로 새 위치로 전달된다.
302(임시 이동): 현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.
303(기타 위치 보기): 요청자가 다른 위치에 별도의 GET 요청을 하여 응답을 검색할 경우 서버는 이 코드를 표시한다. HEAD 요청 이외의 모든 요청을 다른 위치로 자동으로 전달한다.
304(수정되지 않음): 마지막 요청 이후 요청한 페이지는 수정되지 않았다. 서버가 이 응답을 표시하면 페이지의 콘텐츠를 표시하지 않는다. 요청자가 마지막으로 페이지를 요청한 후 페이지가 변경되지 않으면 이 응답(If-Modified-Since HTTP 헤더라고 함)을 표시하도록 서버를 구성해야 한다.
305(프록시 사용): 요청자는 프록시를 사용하여 요청한 페이지만 액세스할 수 있다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 하다.
307(임시 리다이렉션): 현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.
404(찾을 수 없음): 서버가 요청한 페이지를 찾을 수 없다. 예를 들어 서버에 존재하지 않는 페이지에 대한 요청이 있을 경우 서버는 이 코드를 제공한다.
405(허용되지 않는 방법): 요청에 지정된 방법을 사용할 수 없다.
406(허용되지 않음): 요청한 페이지가 요청한 콘텐츠 특성으로 응답할 수 없다.
407(프록시 인증 필요): 이 상태 코드는 401(권한 없음)과 비슷하지만 요청자가 프록시를 사용하여 인증해야 한다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 한다.
408(요청 시간초과): 서버의 요청 대기가 시간을 초과하였다.
409(충돌): 서버가 요청을 수행하는 중에 충돌이 발생했다. 서버는 응답할 때 충돌에 대한 정보를 포함해야 한다. 서버는 PUT 요청과 충돌하는 PUT 요청에 대한 응답으로 이 코드를 요청 간 차이점 목록과 함께 표시해야 한다.
410(사라짐): 서버는 요청한 리소스가 영구적으로 삭제되었을 때 이 응답을 표시한다. 404(찾을 수 없음) 코드와 비슷하며 이전에 있었지만 더 이상 존재하지 않는 리소스에 대해 404 대신 사용하기도 한다. 리소스가 영구적으로 이동된 경우 301을 사용하여 리소스의 새 위치를 지정해야 한다.
411(길이 필요): 서버는 유효한 콘텐츠 길이 헤더 입력란 없이는 요청을 수락하지 않는다.
412(사전조건 실패): 서버가 요청자가 요청 시 부과한 사전조건을 만족하지 않는다.
413(요청 속성이 너무 큼): 요청이 너무 커서 서버가 처리할 수 없다.
414(요청 URI가 너무 김): 요청 URI(일반적으로 URL)가 너무 길어 서버가 처리할 수 없다.
415(지원되지 않는 미디어 유형): 요청이 요청한 페이지에서 지원하지 않는 형식으로 되어 있다.
416(처리할 수 없는 요청범위): 요청이 페이지에서 처리할 수 없는 범위에 해당되는 경우 서버는 이 상태 코드를 표시한다.
Multicast is useful when you have to transmit the SAME message to more than one host.
Usually the client that send multicast does not know how many servers will really receive his packets. When talking about client-server in network, the client sends the request, the server receives the request and might send back an answer.
Since multicast is based UDP, the transmission is by default not reliable.
The advantage of using multicast instead of broadcast is that only interested hosts will get the message, and the message should be transmitted only once for many clients (saves a lot of bandwith). Another advantage is the possibility of sending packets larger than interface MTU
Multicast on LAN
This is topic is quite complex, but we can for simplicity devide LANs in 3 kind:
LAN with hubs only
LAN with switches without IGMP support
LAN with switches with IGMP support
The first 2 types of LANs are the easiest to explain, since the behaviour for multicast is exactly the same; multicast is transmitted over all network segments.
In the third case where the LAN has IGMP aware switches, and IGMP support is enabled, multicast packets will be transmitted only on segments where hosts have requested it. Other segments will not see this kind of traffice until one of the hosts requests it. Of course packets sent to 224.0.0.1/224.0.0.2 could be observed on all segments, since these addresses have a special meaning ( Reserved Multicast IP addresses)
Multicast on WAN
... Still Working ....
What is multicast
Multicast is a kind of UDP traffic similar to BROADCAST, but only hosts that have explicitly requested to receive this kind of traffic will get it. This means that you have to JOIN a multicast group if you want to receive traffic that belongs to that group.
IP addresses in the range 224.0.0.0 to 239.255.255.255 ( Class D addresses) belongs to multicast. No host can have this as IP address, but every machine can join a multicast address group.
Before you begin
Multicast traffic is only UDP (not reliable)
Multicast migth be 1 to many or 1 to none
Not all networks are multicast enabled (Some routers do not forward Multicast)