<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>The Boxer</title>
    <link>https://the-boxer.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 8 Jul 2026 08:53:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Prower</managingEditor>
    <item>
      <title>카프카 구성 요소</title>
      <link>https://the-boxer.tistory.com/95</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 구조&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5416&quot; data-origin-height=&quot;2060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SJHND/btsGMMGQzxh/4Y6w9C6bYgplLZlI4KLQc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SJHND/btsGMMGQzxh/4Y6w9C6bYgplLZlI4KLQc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SJHND/btsGMMGQzxh/4Y6w9C6bYgplLZlI4KLQc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSJHND%2FbtsGMMGQzxh%2F4Y6w9C6bYgplLZlI4KLQc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5416&quot; height=&quot;2060&quot; data-origin-width=&quot;5416&quot; data-origin-height=&quot;2060&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;거대한 양의 데이터 처리가 가능한 분산 스트리밍 플랫폼
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;높은 스루풋, 확장성, 장애 내성 제공&lt;/li&gt;
&lt;li&gt;데이터를 실시간으로 처리, 저장 하도록 하는 플랫폼&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;저장소가 아니다. 메세지 플랫폼&lt;/li&gt;
&lt;li&gt;producer(sender, publisher): 메세지를 카프카에 기록하는 역할&lt;/li&gt;
&lt;li&gt;consumer(receiver, subscriber): 카프카로부터 메세지를 소비하는 역할&lt;/li&gt;
&lt;li&gt;broker: 데이터 저장, 관리, 중개 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;이벤트&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kafka에서 데이터로 취급 되는 것&lt;/li&gt;
&lt;li&gt;event = record = message&lt;/li&gt;
&lt;li&gt;kafka에 기록되는 모든 데이터는 다음의 메세지 형식을 따른다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;key&lt;/li&gt;
&lt;li&gt;value&lt;/li&gt;
&lt;li&gt;timestamp&lt;/li&gt;
&lt;li&gt;(optional) metadata header&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이벤트는 소비되지 않는다. 읽음 행위로 인해 삭제되지 않음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;토픽당 이벤트를 어느 기간 만큼, 유지할건지 설정 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;토픽에 데이터가 기록되면 토픽의 파티션중 하나에 이벤트가 이어 붙여짐&lt;/li&gt;
&lt;li&gt;한 이벤트와 동일한 이벤트 키를 가진 이벤트는 같은 파티션에 기록됨&lt;/li&gt;
&lt;li&gt;카프카는 모든 consumer가 해당 파티션의 기록된 순서대로 읽는 것을 보장함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOHgPq/btsGLFO5a1M/vpGJhmYvKLt1viiPk9AjG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOHgPq/btsGLFO5a1M/vpGJhmYvKLt1viiPk9AjG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOHgPq/btsGLFO5a1M/vpGJhmYvKLt1viiPk9AjG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOHgPq%2FbtsGLFO5a1M%2FvpGJhmYvKLt1viiPk9AjG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;323&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;토픽&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연관된 이벤트가 저장된 집합&lt;/li&gt;
&lt;li&gt;파일 시스템의 폴더와 유사한 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;파티션&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;토픽은 분산되어 있다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산? 토픽이 다른 카프카 브로커에 퍼져있다는 의미&lt;/li&gt;
&lt;li&gt;scalability를 유지하는데 핵심적인 컨셉
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;토픽의 데이터가 브로커에 퍼져있기 때문에 다수의 클라이언트가 다수의 브로커에 동시에 읽기/쓰기가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각 파티션은 순서가있는 레코드들의 집합&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Producer&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;sender, publisher&lt;/li&gt;
&lt;li&gt;카프카의 토픽에 데이터를 기록하는 역할&lt;/li&gt;
&lt;li&gt;동기, 비동기 방식으로 append-only로 데이터를 기록한다&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Consumer&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카프카에 기록된 데이터를 읽는 역할&lt;/li&gt;
&lt;li&gt;카프카의 토픽을 구독(publish) 하고 있다가, 해당 토픽의 데이터를 받는다.&lt;/li&gt;
&lt;li&gt;데이터는 스트리밍 방식으로 읽어 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;producer와 consumer는 서로 의존하지 않는다. 즉, producer, consumer가 하는 일이 서로에 엮여 있지 않음&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Broker&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;producer와 consumer 사이에서 데이터를 저장, 관리하는 중개 역할&lt;/li&gt;
&lt;li&gt;카프카 클러스터는 다수의 broker로 구성되어 있다&lt;/li&gt;
&lt;li&gt;카프카의 장애 내성, 데이터 복제, 고가용성 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Offset&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 파티션의 레코드에 부여된 유일한 식별자&lt;/li&gt;
&lt;li&gt;카프카 토픽에서 해당 레코드의 위치를 표현&lt;/li&gt;
&lt;li&gt;offset은 consumer에 장애가 발생한 경우 데이터를 이어서 읽을 수 있도록 포인트 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Replication&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카프카는 고가용성을 위해 토픽의 파티션을 다수의 broker에 복제한다&lt;/li&gt;
&lt;li&gt;하나의 borker가 다운되더라도 해당 broker의 복제본을 갖고 있는 broker에서 역할 수행 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/kafka-key-concepts-ecosystem-use-case-syed-ashfaq-hussain/?trackingId=PHo9WQF3T9OIqXegWZDLng%3D%3D&quot;&gt;https://www.linkedin.com/pulse/kafka-key-concepts-ecosystem-use-case-syed-ashfaq-hussain/?trackingId=PHo9WQF3T9OIqXegWZDLng%3D%3D&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kafka.apache.org/intro&quot;&gt;https://kafka.apache.org/intro&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Development</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/95</guid>
      <comments>https://the-boxer.tistory.com/95#entry95comment</comments>
      <pubDate>Fri, 19 Apr 2024 22:02:34 +0900</pubDate>
    </item>
    <item>
      <title>비대칭키 알고리즘, RSA</title>
      <link>https://the-boxer.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발 과정에서 RSA 암호화 방식이 자주 등장하는데, 원리에 대한 이해를 하고 사용하고자 공부한 내용을 적습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;비대칭키&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;암호화에 사용하는 키와 복호화에 사용하는 키가 다른 암호화 방식&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대칭키 암호화 방식은 암호화에 사용하는 키와 복호화에 사용하는 키가 동일합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;공개키 암호화(public key cryptography)&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;비대칭키 기반의 암호화 방식으로, 암호화키와 복호화키가 분리된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;원칙&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;암호화키, 복호화키는 같은 사람의 키쌍이어야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;키는 암호화 복호화 중 한 번만 사용해야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;암호화 복호화에 다른 사람의 개인키는 사용할 수 없다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;송신자 암호화&lt;/span&gt;&lt;span&gt;수신자 복호화&lt;/span&gt;&lt;span&gt;사용&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;송신자의 개인키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;송신자의 공개키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;인증, 부인방지(전자 서명)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;송신자의 개인키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;송신자의 개인키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;X - 3원칙 위배&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;수신자의 개인키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;수신자의 공개키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;X - 3원칙 위배&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;수신자의 공개키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;수신자의 개인키&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;기밀성(email)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;구조&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5072&quot; data-origin-height=&quot;1724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wuLUa/btsnSZFd4WT/K5mi9FqVvglqbw2k02nG6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wuLUa/btsnSZFd4WT/K5mi9FqVvglqbw2k02nG6k/img.png&quot; data-alt=&quot;수신자의 키쌍으로 암/복호화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wuLUa/btsnSZFd4WT/K5mi9FqVvglqbw2k02nG6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwuLUa%2FbtsnSZFd4WT%2FK5mi9FqVvglqbw2k02nG6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;218&quot; data-origin-width=&quot;5072&quot; data-origin-height=&quot;1724&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;수신자의 키쌍으로 암/복호화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;암호화에 public key(공개키)를 복호화에 private key(개인키)를 사용&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;누구나 공개키를 통해 암호화를 할 수 있지만, 개인키를 가진 수신자만이 문서를 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;bob측에서 public/private key(키쌍) 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;public key는 키 분배 채널을 통해 분배&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;alice측에서 public key로 평문을 암호문으로 암호화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;암호문을 bob측에 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;bob측에서 private key로 암호문을 평문으로 복호화&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;RSA&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;공개키 암호화 알고리즘의 한 종류&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;공개키 암호화는 하나의 추상화된 개념이며, RSA는 추상화된 개념을 구현한 알고리즘&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;키 생성 알고리즘&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;서로 다른 두 소수 p, g를 선택한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;N=p*q&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;K=(p-1)*(q-1)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;K와 최대공약수가 1인 수(서로소인 수) e(1 &amp;lt; e &amp;lt; K)를 찾는다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;e*d를 K로 나눈 나머지가 1이 되는 d를 찾는다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;N과 e를 공개한다(공개키)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;d는 키 생성자가 보관한다(개인키)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예시&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;p = 7, q = 13&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;N = 7 * 13 = 91&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;K = (7-1) * (13-1) = 72&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;K와 서로소인 수 e = 5, 7, 11... 11 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;11*d % 72 = 1인 d = 57, 131... 57 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;공개키: [ N, e ] = [ 91, 11 ]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;개인키: [ N, d] = [ 91, 57 ]&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;암/복호화&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;평문: P&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;암호문: C&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;공개키: [ N, e ]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;개인키: [ N, d ]&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;암호문 생성: C = P^e mod N&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;평문 생성: P = C^d mod N&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;안전성&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;RSA 암호화는 일정한 수의 소인수분해 수를 알기 어렵다는 것에 기반한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;공개키 [ N, d ]로 부터 비밀키 d를 알아내면 RSA는 뚫린다. 다만 여기서 N으로 부터 K를 구하면 d를 쉽게 알 수 있다. 따라서, RSA 암호화의 안전성은 p, q를 선택하는 것에 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;안전을 위해 소수 p, q의 크기는 512비트의 수로 권장한다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Computer Science</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/93</guid>
      <comments>https://the-boxer.tistory.com/93#entry93comment</comments>
      <pubDate>Tue, 25 Jul 2023 23:49:38 +0900</pubDate>
    </item>
    <item>
      <title>인코딩과 코드표</title>
      <link>https://the-boxer.tistory.com/90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인코딩&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 입력한 문자, 숫자, 특문 등의 데이터를 컴퓨터에 저장할 수 있는 이해하는 이진 데이터로 변환하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자, 숫자, 특문 등은 사람이 이해할 수 있지만, 이진 체계 저장소에 이를 저장하기 위해서는 0,1의 이진 데이터로 변환해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 이 글도 문자로 출력되고 있지만, 저장소에 저장된 데이터 자체는 결국 0,1의 이진 데이터이며, 이를 OS가 읽어 문자로 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 이진 데이터를 사람이 읽을 수 있는 데이터로 변환하는 것을 디코딩이라고 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드표&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자 데이터를 이진 데이터로 변환하기 위해서는 서로 합의된 약속이 필요하다. 여기서 사용하는 것이 코드표이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터에서 문자를 표현하기 위해 문자 - 코드가 1:1로 매핑된 표&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드표에는 우리가 사용하는 문자와 그에 해당하는 코드(숫자)가 매핑된 정보가 저장되어있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자를 4 비트로 저장하는 예시&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;문자&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;10진&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;2진&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;a&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;1010&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자 a가 10이라는 10진수에 매핑되어 있다면 이는 2진수로 1010이고 컴퓨터에 1010이 저장된다.&lt;/li&gt;
&lt;li&gt;문자를 출력할 때는 1010이 a에 매핑되어 있으므로 이를 a로 변환하여 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 코드표는 문자 - 이진 데이터간 변환을 위해 사용하는 약속이며, 여러가지 코드표가 존재한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ASCII&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1byte 체계. 문자 하나를 저장하는데 1byte를 사용한다.&lt;/li&gt;
&lt;li&gt;10진수 0 ~ 127에 128개의 문자(영 대/소문자, 숫자, 일부 특문)가 매핑됨&lt;/li&gt;
&lt;li&gt;1byte(8bit) 중 맨 앞자리 1bit는 에러 검출에 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Unicode&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영미권이 아닌 다른 국가에서 컴퓨터를 사용하면서 각 국가의 문자를 저장하기 위한 여러 코드표가 사용되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 네트워크가 발전하면서 각기 다른 국가의 데이터를 출력하는 과정에서 코드표 통일되지 않아 문자가 깨지는 현상이 발생했다. 우리나라에서는 0000 0001을 'ㄱ'으로 저장/출력하지만 다른 코드표를 사용하는 국가에서는 0000 0001을 'a'나 다른 문자로 출력하는 상황이 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 상황을 해결하기 위해 국제적으로 모든 문자를 출력할 수 있는 공통된 표준 코드표가 만들어 졌으며 이를 유니코드라 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;UTF-8(Unicode Transformation Format-8bit)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 인코딩은 문자 데이터를 컴퓨터가 이해하는 이진 데이터로 변환하는 것이고, 코드표는 그 변환을 위한 약속된 매핑표라 했다. UTF-8은 유니코드라는 매핑표를 참조하여 문자를 이진 데이터로 변환하는 인코딩 방식의 하나이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UTF-8: 유니코드 기반의 인코딩 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니코드만으로는 문자를 이진 데이터로 변환할 수 없다. 코드표는 말 그대로 문자를 코드로 변환하기 위한 참조용일 뿐이며, 인코딩 과정에서 이를 사용한다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;인코딩 방식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UTF-8은 가변 길이 인코딩 방식이다. 문자 데이터를 저장하기 위해 사용하는 데이터 크기가 문자 마다 다르다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최대 저장 가능한 데이터 크기는 6byte
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 인코딩과의 호환을 위해 4byte 까지만 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;문자와 매핑되 코드표에 따라 1 ~ 4byte를 할당하여 데이터를 저장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1btye인 경우(ASCII 코드)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 bit에 0을 할당하고 나머지에 ASCII 코드에 따라 데이터 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2byte 이상인 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 byte에 얼마 만큼의 byte를 사용할지 지정&lt;/li&gt;
&lt;li&gt;나머지 byte에 연결된 byte임을 표시하기 위해 첫 bit 자리에 ㅇㄹ
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2byte: 110, 3byte: 1110, 4byte: 11110&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;문자&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;16진수&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;10진수&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;2진수&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;UTF-8 변환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;a&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;0x0061&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;91&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1100001&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;01100001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;가&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;0xAC00&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;767&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1010110000000000&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;&lt;b&gt;1110&lt;/b&gt;1010 &lt;b&gt;10&lt;/b&gt;110000 &lt;b&gt;10&lt;/b&gt;000000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자 'a'는 유니코드표 상에서 0x0061(16진수), 91(10진수), 1100001(2진수) 라는 코드로 변환된다. 이는 ASCII 코드표를 참조해도 동일하다.&lt;/li&gt;
&lt;li&gt;저장소에 저장하기 위한 형태인 2진수를 UTF-8을 통해 인코딩하면 1byte만 사용하기 때문에 그대로 01100001를 저장하게 된다.&lt;/li&gt;
&lt;li&gt;문자 '가'는 유니코드표 상에서 0xAC00(16진수), 767(10진수), 1010110000000000(2진수) 라는 코드로 변환된다&lt;/li&gt;
&lt;li&gt;2진수를 UTF-8을 통해 인코딩하면 3byte를 사용하기 때문에 첫 byte에 &lt;b&gt;1110&lt;/b&gt; 이 첫 bit 자리에 추가되고, 나머지 byte에 &lt;b&gt;10&lt;/b&gt;이 첫 bit 자리에 추가된다. 나머지 bit 자리에는 2진수 데이터가 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/90</guid>
      <comments>https://the-boxer.tistory.com/90#entry90comment</comments>
      <pubDate>Sun, 23 Jul 2023 19:11:27 +0900</pubDate>
    </item>
    <item>
      <title>AWS IAM</title>
      <link>https://the-boxer.tistory.com/87</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AWS IAM은 AWS의 리소스에 대한 접근 권한을 설정할 수 있는 서비스입니다. IAM은 다음의 세가지 요소를 통해 접근 권한을 설정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;접근 주체: AWS의 리소스에 접근하고자 하는 주체(유저, AWS 리소스, 그룹 등...)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;AWS 리소스: EC2, storage, secret manager, 사용자 등의 접근 주체가 접근하고자 하는 AWS 서비스&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;접근 권한: AWS 리소스에 대한 조회, 추가, 수정.. 등의 접근 주체가 수행하고자 하는 권한&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 새로 생성한 유저가 EC2 인스턴스에 대한 연결 권한이 없는 경우 연결 권한을 부여하여 연결이 될 수 있도록 해야 합니다. 여기서 새로 생성한 유저가 접근 주체에 해당하고, EC2 인스턴스가 AWS 리소스가 되며, 연결 행위 가 접근 권한이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;IAM이 필요한 이유&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AWS의 리소스를 사용하는 접근 주체가 모든 접근 권한을 가지고 있다면 보안상 심각한 위험이 발생할 수 있습니다. 예를 들어 개발용으로 생성한 유저가 EC2 인스턴스에 대한 삭제 혹은 변경 권한을 갖고 있다면 실수로 EC2 인스턴스를 종료하거나 변경시킬 수도 있습니다. 또한, 외부로 노출이 되선 안되는 중요 킷값들의 경우 모든 접근 주체에서 접근이 가능하다면 외부로 유출될 가능성도 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AWS에서는 AWS리소스를 안전하게 관리하기 위해 위해 접근 주체가 AWS를 사용하려는 경우 필요한 만큼의 권한을 설정하도록 IAM을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h1 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;span&gt;IAM에서 제공하는 서비스&lt;/span&gt;&lt;/h1&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;정책(Policy)&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정책은 여러개의 AWS 리소스에 대한 여러개의 접근 권한 설정이 가능한 서비스입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음의 예시는 &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt; 라는 S3 버킷의 오브젝트를 조회하는 행위를 허용하는 예시입니다. &lt;/span&gt;&lt;span&gt;Action&lt;/span&gt;&lt;span&gt; 에 허용하고자 하는 접근 권한이 명시되며, &lt;/span&gt;&lt;span&gt;Resource&lt;/span&gt;&lt;span&gt; 에 접근을 허용하고자 하는 AWS 리소스를 명시합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;{
 &amp;nbsp; &amp;nbsp;&quot;Version&quot;: &quot;2012-10-17&quot;,
 &amp;nbsp; &amp;nbsp;&quot;Statement&quot;: [
 &amp;nbsp; &amp;nbsp; &amp;nbsp;  {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Effect&quot;: &quot;Allow&quot;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Action&quot;: [
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;s3:GetObject&quot;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  ],
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Resource&quot;: [
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;arn:aws:s3:::test&quot;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  ]
 &amp;nbsp; &amp;nbsp; &amp;nbsp;  },
 &amp;nbsp;  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;IAM에서는 AWS 리소스에 대한 접근 권한을 미리 설정해둔 여러가지 기본 정책을 제공하며, 위 예시처럼 관리자가 직접 정책을 생성할 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정책은 접근 주체에 대해서 명시하지 않으며, 여러개의 AWS 리소스와 접근 권한을 미리 설정하여 여러 접근 주체에 부여할 수 있도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;사용자(User)&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자는 접근 주체에 해당하는 개념으로 AWS 리소스에 대한 접근 권한을 허용하는 접근 주체를 생성할 때 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대부분의 조직에서는 업무를 위한 여러 사용자가 필요하며, 각 사용자가 업무상 접근할 수 있는 AWS 리소스는 제한되어야 합니다. AWS에서는 하나의 루트 계정에 AWS 콘솔에 로그인 할 수 있는 여러개의 사용자를 생성할 수 있도록 하여 이러한 조직 내 업무가 가능하도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자는 다음과 같은 2가지 행위가 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;인증을 통한 AWS 콘솔에 로그인&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;부여된 정책에 따란 AWS 리소스에 접근&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자는 AWS 인증을 통해 AWS 콘솔에 로그인하고, 허용된 접근 권한 하에서 업무를 수행하도록 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음 예시는 사용자를 생성하는 과정에서 정책을 설정하는 페이지입니다. 미리 &lt;/span&gt;&lt;span&gt;test_s3&lt;/span&gt;&lt;span&gt; 라는 S3 오브젝트를 읽을 수 있는 정책을 생성했으며, 사용자에게 해당 권한을 부여합니다. 해당 사용자는 인증을 통해 AWS 콘솔에 로그인하여 S3 오브젝트를 읽을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8azcp/btscYNuP2K7/5jE5fNlQkA83kTOoTluEDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8azcp/btscYNuP2K7/5jE5fNlQkA83kTOoTluEDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8azcp/btscYNuP2K7/5jE5fNlQkA83kTOoTluEDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8azcp%2FbtscYNuP2K7%2F5jE5fNlQkA83kTOoTluEDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;190&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;사용자 그룹(User Group)&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여러 사용자를 모아 관리하는 사용자 집단입니다. 사용자와 마찬가지로 사용자 그룹에도 정책을 설정할 수 있습니다. 사용자는 사용자 그룹에 할당 될 수 있으며, 사용자 그룹에 할당된 사용자는 사용자 그룹에 설정된 모든 정책을 부여받습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 사용자 그룹에 EC2에 대한 연결 권한을 부여하고 위 예시의 사용자를 할당한 경우 해당 사용자 또한 EC2에 대한 연결 권한을 부여받게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자와 사용자 그룹은 N:M 관계로 하나의 사용자 그룹에 여러 사용자를 할당할 수 있으며, 하나의 사용자에 여러 사용자 그룹을 설정하여 한번에 권한 부여가 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;역할(role)&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;접근 주체에 정책을 부여하는 서비스입니다. 접근 주체에 접근 권한을 부여한다는 점에서 사용자와 유사해 보이지만 다음과 같은 차이점이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;접근 주체를 생성하지 않음: 사용자는 접근 권한을 부여함과 동시에 접근 주체를 생성합니다. 역할은 접근 주체를 생성하지 않으며, 이미 생성된 접근 주체에게 접근 권한을 부여한다는 것만 명시합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;접근 주체가 인증을 하지 않음: 사용자는 생성된 접근 주체가 서비스를 사용하기 위해 인증을 수행해야 하지만, 역할에서 지정된 접근 주체는 추가적인 인증 없이 부여된 접근 권한에 따라 서비스를 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;역할은 주로 AWS 서비스간 접근 권한을 부여하기 위해 사용합니다. 예를 들어 codebuild의 빌드 결과물로 생성된 아티팩트를 S3에 저장해야 하는 경우 S3에 대한 저장 권한이 codebuild에 필요합니다. 다음은 codebuild에서 S3에 대한 write 권한을 부여하는 역할 생성 예시입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;접근 주체 설정&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcT0mp/btscY4puZbt/N4dgHKzd84vpKP3NjF72X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcT0mp/btscY4puZbt/N4dgHKzd84vpKP3NjF72X0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcT0mp/btscY4puZbt/N4dgHKzd84vpKP3NjF72X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcT0mp%2FbtscY4puZbt%2FN4dgHKzd84vpKP3NjF72X0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;280&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;591&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정책 설정&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cmh90/btscZsw295n/2WQx0MQcm0snVwCt3ihtB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cmh90/btscZsw295n/2WQx0MQcm0snVwCt3ihtB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cmh90/btscZsw295n/2WQx0MQcm0snVwCt3ihtB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCmh90%2FbtscZsw295n%2F2WQx0MQcm0snVwCt3ihtB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;212&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위 예시에서 s3_read_write는 미리 생성해 놓은 S3에 대한 읽기, 쓰기가 가능한 정책입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;역할을 생성한 후 생성된 역할 -&amp;gt; 신뢰 관계 탭에서 확인한 결과입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;설정된 접근 주체&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;json&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;{
 &amp;nbsp; &amp;nbsp;&quot;Version&quot;: &quot;2012-10-17&quot;,
 &amp;nbsp; &amp;nbsp;&quot;Statement&quot;: [
 &amp;nbsp; &amp;nbsp; &amp;nbsp;  {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Effect&quot;: &quot;Allow&quot;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Principal&quot;: {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Service&quot;: &quot;codebuild.amazonaws.com&quot;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  },
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;Action&quot;: &quot;sts:AssumeRole&quot;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;  }
 &amp;nbsp;  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;부여된 권한은 s3_read_write 이며, Principal에 정책을 부여받을 주체가 설정됩니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Devops</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/87</guid>
      <comments>https://the-boxer.tistory.com/87#entry87comment</comments>
      <pubDate>Thu, 27 Apr 2023 19:58:29 +0900</pubDate>
    </item>
    <item>
      <title>AWS EC2 볼륨 연결</title>
      <link>https://the-boxer.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ec2 인스턴스에 볼륨을 추가하는 방법을 공유합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h1 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;span&gt;볼륨 추가 방법&lt;/span&gt;&lt;/h1&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. 볼륨 생성&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;EC2 메뉴 -&amp;gt; EBS -&amp;gt; 볼륨 추가&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;생성하고자 하는 볼륨의 크기와 유형 등 기본 설정을 입력하여 추가하고자 하는 볼륨을 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yfXSm/btscPesJriS/ksZctKvLLVlWhoLk9G8h4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yfXSm/btscPesJriS/ksZctKvLLVlWhoLk9G8h4K/img.png&quot; data-alt=&quot; 연결할 볼륨 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yfXSm/btscPesJriS/ksZctKvLLVlWhoLk9G8h4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyfXSm%2FbtscPesJriS%2FksZctKvLLVlWhoLk9G8h4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;638&quot; height=&quot;580&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1164&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; 연결할 볼륨 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. 볼륨 연결&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;EBS -&amp;gt; 연결하고자 하는 볼륨 선택 -&amp;gt; 작업 -&amp;gt; 볼륨 연결&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;생성된 볼륨을 EC2에 연결합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;913&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xP9SS/btscP9LkU90/gq9ZSwCGsVNeMIvbay9e7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xP9SS/btscP9LkU90/gq9ZSwCGsVNeMIvbay9e7k/img.png&quot; data-alt=&quot;볼륨을 EC2에 연결&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xP9SS/btscP9LkU90/gq9ZSwCGsVNeMIvbay9e7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxP9SS%2FbtscP9LkU90%2Fgq9ZSwCGsVNeMIvbay9e7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;637&quot; height=&quot;454&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;913&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;볼륨을 EC2에 연결&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디바이스 이름은 기본 루트 볼륨의 이름을 피해 지정하여 입력합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;3. 볼륨 마운트&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;볼륨은 EC2인스턴스에 연결(매핑) 되었지만, 시스템에 마운트 되지는 않은 상태이므로 추가적으로 마운트 하는 과정이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;마운트: 물리적인 디바이스를 특정 디렉토리에 연결하는 작업&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉 디바이스(물리 장비) 자체는 EC2에 연결이 되었지만, OS에서 접근은 불가능한 상태입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;lsblk: 연결된 스토리지 디바이스 정보 확인&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;NAME &amp;nbsp;  MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda &amp;nbsp;  202:0 &amp;nbsp;  0  30G  0 disk
└─xvda1 202:1 &amp;nbsp;  0  30G  0 part /
xvdf &amp;nbsp;  202:80 &amp;nbsp; 0  10G  0 disk&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;명령어를 통해 확인한 결과입니다. xvda는 기존에 연결된 루트 볼륨이며, xvdf는 새로 연결된 볼륨입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;MOUNTPOINT를 보면 새로 연결된 볼륨은 아직 마운트 되지 않은 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;df -hT: 마운트된 디스크의 여유 공간 확인&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;Filesystem &amp;nbsp; &amp;nbsp; Type &amp;nbsp; &amp;nbsp;  Size  Used Avail Use% Mounted on
devtmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; devtmpfs  474M &amp;nbsp; &amp;nbsp; 0  474M &amp;nbsp; 0% /dev
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M &amp;nbsp; &amp;nbsp; 0  483M &amp;nbsp; 0% /dev/shm
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M  480K  482M &amp;nbsp; 1% /run
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M &amp;nbsp; &amp;nbsp; 0  483M &amp;nbsp; 0% /sys/fs/cgroup
/dev/xvda1 &amp;nbsp; &amp;nbsp; xfs &amp;nbsp; &amp;nbsp; &amp;nbsp;  30G  7.4G &amp;nbsp; 23G  25% /
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp;  97M &amp;nbsp; &amp;nbsp; 0 &amp;nbsp; 97M &amp;nbsp; 0% /run/user/0
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp;  97M &amp;nbsp; &amp;nbsp; 0 &amp;nbsp; 97M &amp;nbsp; 0% /run/user/1000&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디스크의 여유 공간을 확인해보면 루트 볼륨은 마운트 되어 사용 가능하지만, 새로 연결한 볼륨은 아직 접근이 불가능한 상황입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디스크를 연결하기 위해서는 다음과 같은 과정이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;디스크에 파일 시스템 생성(포맷)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;디렉토리 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;디렉토리와 디바이스 연결&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;파일 시스템 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;볼륨에 파일 시스템을 생성합니다. 디스크로만 존재하던 볼륨에 파일시스템을 지정하여 OS에서 사용할 수 있도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존 루트 볼륨의 파일 시스템이 xfs 이므로 동일하게 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;awk&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;mkfs -t xfs /dev/xvdf&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;디렉토리 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;생성된 볼륨이 탑재될 디렉토리를 생성합니다. 볼륨에 파일 시스템을 지정한 이후, 접근할 디스크를 생성하여 연결합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;haskell&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;mkdir /data&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;디렉토리와 디바이스 연결&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;생성된 볼륨과 디렉토리를 연결하여 OS에서 디스크에 접근할 수 있도록 합니다. &lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;haskell&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;mount /dev/xvdf /data&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;lsblk로 연결 확인&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;NAME &amp;nbsp;  MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda &amp;nbsp;  202:0 &amp;nbsp;  0  30G  0 disk
└─xvda1 202:1 &amp;nbsp;  0  30G  0 part /
xvdf &amp;nbsp;  202:80 &amp;nbsp; 0  10G  0 disk /data&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;확인 결과 MOUNTPOINT가 /data로 지정되어 마운트가 된 것을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디스크의 여유 공간 확인&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;Filesystem &amp;nbsp; &amp;nbsp; Type &amp;nbsp; &amp;nbsp;  Size  Used Avail Use% Mounted on
devtmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; devtmpfs  474M &amp;nbsp; &amp;nbsp; 0  474M &amp;nbsp; 0% /dev
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M &amp;nbsp; &amp;nbsp; 0  483M &amp;nbsp; 0% /dev/shm
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M  480K  482M &amp;nbsp; 1% /run
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M &amp;nbsp; &amp;nbsp; 0  483M &amp;nbsp; 0% /sys/fs/cgroup
/dev/xvda1 &amp;nbsp; &amp;nbsp; xfs &amp;nbsp; &amp;nbsp; &amp;nbsp;  30G  7.4G &amp;nbsp; 23G  25% /
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp;  97M &amp;nbsp; &amp;nbsp; 0 &amp;nbsp; 97M &amp;nbsp; 0% /run/user/0
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp;  97M &amp;nbsp; &amp;nbsp; 0 &amp;nbsp; 97M &amp;nbsp; 0% /run/user/1000
/dev/xvdf &amp;nbsp; &amp;nbsp;  xfs &amp;nbsp; &amp;nbsp; &amp;nbsp;  10G &amp;nbsp; 43M &amp;nbsp; 10G &amp;nbsp; 1% /data&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;파티션을 생성하여 마운트&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;파티션: 논리적으로 디스크 공간을 분할하는 것&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디스크를 파티션으로 나눠 관리하면 각 디스크 공간을 침범하지 않으며 데이터를 저장할 수 있으며, 종류별로 데이터를 구분하여 저장할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞서, 디스크 연결을 위해 3단계를 언급했는데 그 이전에 파티션을 생성하여 마운트 하는 과정을 알아봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저 연결했던 디스크를 마운트 해제합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;awk&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;umount /dev/xvdf&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;파티션 생성&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예시로 파티션을 2개 생성하여 연결합니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파티션 생성 모드 진입&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;awk&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;fdisk /dev/xvdf&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해당 명령어로 파티션 생성 모드에 진입합니다. 대화형으로 파티션 생성, 확인 등을 진행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;명령어 예시&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;p: 파티션 상태 출력&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;n: 파티션 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;d: 파티션 삭제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;w: 저장 후 종료&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;q: 취소 후 종료&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파티션 생성 진입&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;Command (m for help): n
Partition type
 &amp;nbsp; p &amp;nbsp; primary (0 primary, 0 extended, 4 free)
 &amp;nbsp; e &amp;nbsp; extended (container for logical partitions)
Select (default p): p&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파티션 생성을 선택하여 진입한 상태입니다. 파티션 유형을 선택 p를 선택하여 주 파티션 생성, e를 선택하여 확장 파티션 영역을 t생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파티션 생성 및 사이즈 지정&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048): 2048
Last sector, +sectors or +size{K,M,G,T,P} (2048-20971519, default 20971519): 10485760
​
Created a new partition 1 of type 'Linux' and of size 5 GiB.
​
Command (m for help):  n
Partition type
 &amp;nbsp; p &amp;nbsp; primary (1 primary, 0 extended, 3 free)
 &amp;nbsp; e &amp;nbsp; extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (10485761-20971519, default 10487808): 10487808
Last sector, +sectors or +size{K,M,G,T,P} (10487808-20971519, default 20971519): 20971519
​
Created a new partition 2 of type 'Linux' and of size 5 GiB. &lt;/code&gt;&lt;/pre&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파티션 생성 확인&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;NAME &amp;nbsp;  MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda &amp;nbsp;  202:0 &amp;nbsp;  0  30G  0 disk
└─xvda1 202:1 &amp;nbsp;  0  30G  0 part /
xvdf &amp;nbsp;  202:80 &amp;nbsp; 0  10G  0 disk
├─xvdf1 202:81 &amp;nbsp; 0 &amp;nbsp; 5G  0 part
└─xvdf2 202:82 &amp;nbsp; 0 &amp;nbsp; 5G  0 part&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;마운트&lt;/span&gt;&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파일 시스템 생성&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;awk&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;mkfs -t xfs /dev/xvdf1
mkfs -t xfs /dev/xvdf2&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디렉토리 생성 및 마운트&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;mount /dev/xvdf1 /data
mount /dev/xvdf2 /data2&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #777777; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;마운트 확인&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #333333; text-align: left;&quot;&gt;&lt;code&gt;Filesystem &amp;nbsp; &amp;nbsp; Type &amp;nbsp; &amp;nbsp;  Size  Used Avail Use% Mounted on
devtmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; devtmpfs  474M &amp;nbsp; &amp;nbsp; 0  474M &amp;nbsp; 0% /dev
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M &amp;nbsp; &amp;nbsp; 0  483M &amp;nbsp; 0% /dev/shm
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M  488K  482M &amp;nbsp; 1% /run
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp; 483M &amp;nbsp; &amp;nbsp; 0  483M &amp;nbsp; 0% /sys/fs/cgroup
/dev/xvda1 &amp;nbsp; &amp;nbsp; xfs &amp;nbsp; &amp;nbsp; &amp;nbsp;  30G  7.4G &amp;nbsp; 23G  25% /
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp;  97M &amp;nbsp; &amp;nbsp; 0 &amp;nbsp; 97M &amp;nbsp; 0% /run/user/0
tmpfs &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  tmpfs &amp;nbsp; &amp;nbsp;  97M &amp;nbsp; &amp;nbsp; 0 &amp;nbsp; 97M &amp;nbsp; 0% /run/user/1000
/dev/xvdf1 &amp;nbsp; &amp;nbsp; xfs &amp;nbsp; &amp;nbsp; &amp;nbsp; 5.0G &amp;nbsp; 38M  5.0G &amp;nbsp; 1% /data
/dev/xvdf2 &amp;nbsp; &amp;nbsp; xfs &amp;nbsp; &amp;nbsp; &amp;nbsp; 5.0G &amp;nbsp; 38M  5.0G &amp;nbsp; 1% /data2&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Devops</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/86</guid>
      <comments>https://the-boxer.tistory.com/86#entry86comment</comments>
      <pubDate>Wed, 26 Apr 2023 19:13:16 +0900</pubDate>
    </item>
    <item>
      <title>transport layer(2)</title>
      <link>https://the-boxer.tistory.com/81</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;4. TCP&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;특징&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;point to point&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;소켓 한 쌍 끼리의 통신만 책임짐&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;reliable, in order byte steam&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;full deplex: 데이터가 양방향으로 이동함&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;각 point가 sender buffer, receiver buffer를 소유함&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;connection oriented&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;flow control: receiver의 buffer가 넘치지 않는 수준으로만 데이터 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;congestion control: 내부 네트워크가 받아들일 수 있는 수준으로만 데이터 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;계층간 이동 단위&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;application: message - 실제 전송하고자 하는 데이터&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;transport: segment - message(DATA) + Header(부가 정보)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;network: packet - segment(DATA) + Header&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;link: frame - package(DATA) + Header&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;TCP segment 구조&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwJyQa/btrXK62thyY/Mi4lTULBVhqetKXxiPiq41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwJyQa/btrXK62thyY/Mi4lTULBVhqetKXxiPiq41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwJyQa/btrXK62thyY/Mi4lTULBVhqetKXxiPiq41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwJyQa%2FbtrXK62thyY%2FMi4lTULBVhqetKXxiPiq41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;538&quot; height=&quot;530&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;source/destination port: 출발지/목적지 port&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receive window: 현재 receiver의 가용 buffer 크기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sequence number: data의 맨 처음 byte의 인덱스 번호&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;100 bytes 짜리 데이터를 10개의 chunk로 나눠서 보내면 0, 10, 20 ... 이 사용됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender가 보내는 데이터 순서에 따라 생성되는 번호&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;acknowledge number: receiver가 다음으로 받아야 하는 기다리는 seq num&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;sequence number&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;TCP는 양방향 데이터를 전달하는 프로토콜이기 때문에, 통신에 참여하는 양 측 모두 sender와 receiver가 될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 노드가 sender와 receiver를 겸하면서 서로의 seq num를 공유하게됨&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;A: 자신이 보내는 데이터의 seq num을 sequence number에 담아 보냄&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;B: 이를 수신하고 자신이 보내는 데이터의 seq num을 sequence number에 담아 보내면서, ACK값을 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;A: B로 부터 받은 ACK를 참조하여 다음 seq num에 해당하는 데이터 전송하면서 ACK값 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;TCP의 패킷마다 timeout을 설정하는데 이를 어떻게 설정할 것인가?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;timeout이 너무 길면? timeout은 확실하게 식별할 수 있으나, 복구 시간이 느림. 짧으면? 복구는 빠르나 쓸데 없는 중복 전송이 발생함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제로 데이터가 전송되고 돌아오는 시간을 참조하여 설정한다. 즉, RTT 를 참조한다. 그러나, RTT는 가변적이다. (segment의 이동 경로(router)가 다름, queueing delay.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서, 실제 RTT를 측정하고 이에 보정된 값을 사용. 여기에 확실한 timeout을 보장하기 위해 margin을 추가&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;fast retransmit&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그러나 timeout을 기다려서 패킷 loss를 판별하기에는 너무 시간이 오래걸리기 때문에 fast retransmit 기법을 사용하기도 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 seq num에 대한 ack를 중복해서 3개를 받으면 패킷 loss로 판별한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;5. Flow Control&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;receiver 입장에서 가용 가능한 만큼만 데이터를 전송하는 방법&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;receiver의 버퍼가 가득 차 데이터를 수용할 수 없는 상황이 되면 데이터가 유실될 수 있다. receiver의 버퍼는 소켓 API의 &lt;/span&gt;&lt;span&gt;read()&lt;/span&gt;&lt;span&gt; 에 의해 비워지는데, receiver의 버퍼가 비워질 때 까지 대기한 후 데이터를 전송&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;특징&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receive buffer가 받을 수 있는(가용 만큼만) 만큼만 보내야 함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 segment header(receiver window)에 가용 버퍼 크기를 보냄&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;가용 버퍼 확인&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;receiver의 버퍼가 가득 차 sender가 데이터를 전송하지 않는 경우 sender는 receiver의 버퍼가 언제 비워질 지 모른다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receiver가 receiver window에 0을 보낸다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 receiver window를 확인하고 대기 -&amp;gt; 이후 receiver의 버퍼가 비워짐&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 receiver의 버퍼가 비워졌는지 알 수 없음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이런 경우 sender는 data가 빈 segment를 주기적으로 전송하여 receiver에 가용 버퍼가 있는지 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;6. connection management&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;TCP 통신시, sender와 receiver는 데이터를 교환하기 전 connection을 맺는 과정이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;필요한 이유&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;통신에 참여하는 sender/receiver의 버퍼 상황 공유&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender/receiver의 seq num 공유&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;7. 3-way handshake(connection establishment)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;데이터 교환 전 sender와 receiver가 connection을 맺는 과정&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;client: 연결을 요청하는 노드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;server: 연결을 수락하는 노드&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;1620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B5Nln/btrXJrsuJcD/dA3LdG2VZQeyFibkV7vCIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B5Nln/btrXJrsuJcD/dA3LdG2VZQeyFibkV7vCIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B5Nln/btrXJrsuJcD/dA3LdG2VZQeyFibkV7vCIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB5Nln%2FbtrXJrsuJcD%2FdA3LdG2VZQeyFibkV7vCIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;425&quot; height=&quot;572&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;1620&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;연결을 맺고자 하는 client가 SYN bit=1로, 자신의 seq num를 전송&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;SYN bit: 1bit 짜리 플래그 값으로, handshake를 하는 동안 1로 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;server가 SYN, ACK bit=1, ACK num, 자신의 seq num을 전송&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;통신을 위한 버퍼 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;SYN bit: 연결을 맺는 과정이므로 1로 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ACK bit: acknowledge number가 유효함을 설정하는 값&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ACK num: client가 보낸 seq num에 1을 추가한 값을 보내 seq num을 정상 수신했음을 알림&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;seq num: 자신의 seq num을 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;client가 ACK로 server의 seq num + 1을 보내며, 이 때 부터 데이터를 전송&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;SYN bit: 0으로 설정하여 보냄. 연결을 맺은 이후에는 0으로 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ACK num: server의 seq num을 정상 수신했음을 알림&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;왜 이런 과정이 필요한가&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3 way handshake는 client와 server가 통신하기 전 서로 통신이 가능한 지에 대한 대한 확답을 받고, 통신에 필요한 정보(seq num, 버퍼 상황)을 공유하는 과정이다. 이 과정에서, client와 server는 서로 보낸 정보가 정상적으로 도착했는지 확인이 필요하며, 전송 이후 응답 과정을 통해 이를 알린다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;만약 2 way handshake를 사용하면 server는 자신이 보낸 seq num을 client가 정상적으로 수신했는지 알 방법이 없다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;connection closing&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zVXkT/btrXHWGMDRY/14InwI8Q4V4fnlqbOOC1o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zVXkT/btrXHWGMDRY/14InwI8Q4V4fnlqbOOC1o0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zVXkT/btrXHWGMDRY/14InwI8Q4V4fnlqbOOC1o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzVXkT%2FbtrXHWGMDRY%2F14InwI8Q4V4fnlqbOOC1o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;428&quot; height=&quot;540&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;client가 더이상 전송할 데이터가 없어 FIN bit=1인 segment 전송&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;데이터는 비어있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;server는 client가 보낸 FIN에 대한 ACK bit=1 을 전송하며, 추가적으로 보낼 데이터가 있다면 보낸다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;이후 server도 더이상 전송할 데이터가 없으면 FIN bit=1을 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;client는 server의 FIN에 대한 ACK bit=1을 전송하고 대기한다. &lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;대기하는 이유? corner case에 대한 대비&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;ACK가 유실되면? server는 connection close를 하지 못한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;만약 client가 연결을 바로 닫아버리면, server는 FIN을 계속 보내지만, client는 받을 수 없는 상황 발생&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;server는 이를 수신하고 connection close&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;8. Congestion control&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender가 보내는 속도는 network, receiver의 데이터 처리 상황에 따라 결정된다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receiver -&amp;gt; flow control&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;network -&amp;gt; congestion control&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TCP 특성상 network에 부하가 있으면 더욱 성능이 악화됨&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;재전송으로 인해 network 부하가 더 커짐&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;network 상황에 따라 데이터 전송 속도를 늘리거나 줄인다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;네트워크 상황을 판단하는 방법&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;network assisted congestion control: 네트워크가 상황을 알려주는 방법&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;proposal일 뿐이고 구현 안됨. 불가능함&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;end to end: ack 오는게 느리거나 안오면 network에 이상이 있다고 유추&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;네트워크 상황 파악을 위한 데이터 전송 phase&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;slow start: 네트워크 상황 파악을 위해 처음에는 데이터를 조금씩 보내면서 feedback 확인&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;보내는 데이터는 exponential하게 증가시킴&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;additive increase: threshold를 지나서 부터는 보내는 데이터를 linear하게 증가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;multiplicative decrease: 패킷 loss가 발생하면 해당 시점의 threshold를 반으로 줄임. 이후 linear하게 증가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m4aS6/btrXIj9znXT/PUE3HBL9Yl6MoKMUkSQ5f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m4aS6/btrXIj9znXT/PUE3HBL9Yl6MoKMUkSQ5f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m4aS6/btrXIj9znXT/PUE3HBL9Yl6MoKMUkSQ5f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm4aS6%2FbtrXIj9znXT%2FPUE3HBL9Yl6MoKMUkSQ5f1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;296&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;mss(miximum segment size)&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;처음에는 segment 1개를 보냄. 그 크기가 1mss&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;최초로 window 사이즈가 1mss로 설정됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ack가 오면 2배씩 증가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;결국 네트워크 상황이 window size를 결정함&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;패킷 loss 탐지&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음 두 가지 상황에 따라 네트워크 상황이 다름&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;timeout: 전체 네트워크에 이상이 있을 수 있는 상황이므로, 안전하게 데이터 전송을 처음부터 시작. tahoe 방법&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;3 duplicated ack: 하나의 패킷만 중복이 되었을 수 있는 상황이므로, 조금 도전적으로 패킷 증가를 감소된 threshold부터 시작. reno 방법&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 가지 패킷 loss 상황에 따라 다르게 행동함&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;최초의 threshold&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;설정에 따라 다름&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;TCP의 공정성&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;참여자가 균일하게 자원을 사용하는가?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;결국 균일하도록 수렴한다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Network</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/81</guid>
      <comments>https://the-boxer.tistory.com/81#entry81comment</comments>
      <pubDate>Wed, 1 Feb 2023 11:03:16 +0900</pubDate>
    </item>
    <item>
      <title>transport layer (1)</title>
      <link>https://the-boxer.tistory.com/76</link>
      <description>&lt;h1&gt;&lt;span&gt;1. multiplexing, demultiplexing&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;tansport layer에서 multiplexing, demultiplexing을 수행한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;multiplexing: application layer의 소켓에서 요청한 여러 데이터를 감싸, 헤더를 포함하여 segment로 만들고 network layer로 내림&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;demultiplexing: segment를 풀어 데이터를 목적지 process에 데이터를 전달함. input(segment)은 하나 output(process)은 여러개&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;segment는 data부 header부로 구성된다. header부의 destination port를 확인하여 목적지 process(소켓)에 데이터를 전달한다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Connection oriented demultiplexing&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;udp의 demultiplexing&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;destination IP, port만 가지고 데이터를 어떤 소켓으로 올릴지 결정한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;비연결 지향: 일방적으로 데이터를 보내는 방식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;connection이 맺어지는 개념이 아니므로 출발지와 상관 없이 destination port는 같음&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;서로 다른 클라이언트가 하나의 서버로 요청을 보내도 destination port는 같음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;TCP의 demultiplexing&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;source IP, port / destination IP, port 를 가지고 어떤 소켓으로 올릴지 결정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TCP의 connection oriented(연결 지향): 양방향으로 데이터를 보내는 방식이므로 두 노드 간 연결이 필요함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;클라이언트와 connection이 되어야 하므로 하나의 thread 마다 연결을 담당하기 위한 port가 할당됨&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;지정된 thread로 데이터를 전송해야 하므로 source IP와 port를 활용하여 목적지 thread로 데이터를 전달&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 thread 마다 port가 할당되어야 하므로 자원을 많이 소모함&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span&gt;2. UDP&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;UDP는 기본적인 기능만 제공한다. 전송 실패, 전송 순서 등에 대한 제어는 제공하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;UDP가 제공하는 기본적인 기능: &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;데이터 전송 및 에러 체크&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;왜 사용 하는가?&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;연결 과정이 필요 없음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;빠르게 데이터 전달 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;연결에 필요한 데이터가 없어 경량화 된 헤더 부&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;segment&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;UDP의 segment를 구성하는 필드.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각 필드당 16 bit를 차지함. 한 컴퓨터에서 2^16개의 포트 할당 가능&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;source port: (de)multiplexing에 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;dest port: (de)multiplexing에 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;length: 헤더를 포함한 udp segment 데이터 길이&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;checksum: 전송 과정에서 에러가 발생했는지 판단&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;error checking: 에러가 발생한 데이터는 위로(application layer) 올려보내지 않음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span&gt;3. Reliable Data Transfer&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제 데이터 전송 과정에서 패킷 error, loss 발생 가능하다. (전송 채널상의 문제, 네트워크상 에러 등...)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;불안정한 전송 채널 위에서 신뢰성 있는 통신을 하기 위한 매커니즘이 필요하다. 신뢰성 있는 통신을 위해 패킷에 error, loss에 대한 제어 필요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;제어를 위해서는 상대방이 데이터를 정상적으로 받았는지 확인 여부가 필요하므로, &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;한번에 하나씩 순차적으로&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt; 보내면서 데이터 정상 수신 여부를 체크한다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Error Check&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;데이터에 checksum을 추가해서 sender가 전송. receiver는 checksum을 통해 에러가 발생했는지 판별.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender는 checksum을 추가하여 데이터 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 checksum을 확인&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;데이터에 에러가 발생했으면 negative acknowledgement를 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;에러가 발생하지 않으면 acknowledgement 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 receiver로 부터 온 feedback을 확인&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;NAK를 수신하면 다음 패킷을 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ACK를 수신하면 패킷을 재전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;feedback에서 에러가 발생하면?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sender에서 ACK인지 NAK인지 판별이 안되므로 sender는 패킷을 다시 전송한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;receiver 입장에서는 중복된 패킷을 수신하게 되는데, 중복된 패킷을 수신할 경우 정상적으로 전송되어야 하는 데이터인지, 아니면 중복으로 전송된 데이터인지 판별할 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따러서 데이터 마다 고유한 sequence number를 붙여 중복된 패킷을 구분하고, 중복된 패킷인 경우 receiver가 폐기하도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;seq num의 크기&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;seq num은 데이터 크기에 따라 무한대로 커질 수 있는데, seq num은 header에 포함되므로 크기가 최소화 되어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;seq num은 0, 1로 구분한다. 그 이유는, 데이터를 순차적으로 전송하여, 매번 전송 여부를 판단하기 때문에 0, 1을 번갈아 가며 사용해도 충분하다. (0 -&amp;gt; 1 -&amp;gt; 0 ...)&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;NAK free&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NAK을 사용하지 않는 방법. 에러가 발생할 경우 NAK을 보내지 않고, &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;가장 마지막으로 정상적으로 받은 데이터의 seq num&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 담아서 ACK를 전송&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender가 (1) 전송. receiver 정상 수신 후 ACK(1) 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender가 (0) 전송. 에러 발생 receiver가 ACK(1) 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender가 (0) 재전송&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NAK free가 반영된 케이스별 흐름&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL5PdH/btrVecdnQMe/K3Pg1rZtoZk4GUjBrmBDPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL5PdH/btrVecdnQMe/K3Pg1rZtoZk4GUjBrmBDPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL5PdH/btrVecdnQMe/K3Pg1rZtoZk4GUjBrmBDPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL5PdH%2FbtrVecdnQMe%2FK3Pg1rZtoZk4GUjBrmBDPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;440&quot; height=&quot;527&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1534&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Loss Check&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;패킷이 유실되는 경우는 각 패킷 마다 timer를 설정하여 감지한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sender 입장에서 패킷 전송 이후 일정 시간 동안 receiver로 부터 feedback이 오지 않으면 유실된 것으로 판단하고 패킷을 재전송&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sender는 패킷 전송과 동시에 timer를 실행하여 time out을 측정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;재전송을 하여 패킷이 중복되어도 seq num으로 중복 방지는 가능&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;적절한 time out 시간&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오버헤드와 recovery 속도 사이에서 합의점을 찾느다&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;너무 짧으면: time out 감지가 빨라 recovery가 빠르나, 네트워크에 중복된 데이터가 많이 보내짐(오버헤드)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;너무 길면: recovery는 느리고 오버헤드는 적음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sender 전송에서 time out 발생&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uLV8j/btrU9djNIUB/NpUbAAiNYBSJhFucrqwfz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uLV8j/btrU9djNIUB/NpUbAAiNYBSJhFucrqwfz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uLV8j/btrU9djNIUB/NpUbAAiNYBSJhFucrqwfz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuLV8j%2FbtrU9djNIUB%2FNpUbAAiNYBSJhFucrqwfz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;404&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;receiver feedback에서 에러가 발생한 경우&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjvD0R/btrU6Ym1CcZ/gWNc16BlmalhkLKvX4NvLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjvD0R/btrU6Ym1CcZ/gWNc16BlmalhkLKvX4NvLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjvD0R/btrU6Ym1CcZ/gWNc16BlmalhkLKvX4NvLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjvD0R%2FbtrU6Ym1CcZ%2FgWNc16BlmalhkLKvX4NvLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;415&quot; height=&quot;477&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sender 패킷이 지연 전송 되는 경우&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xJCtG/btrU7HZLrXW/PbIXf2F5Z1zq0srDvG6rT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xJCtG/btrU7HZLrXW/PbIXf2F5Z1zq0srDvG6rT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xJCtG/btrU7HZLrXW/PbIXf2F5Z1zq0srDvG6rT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxJCtG%2FbtrU7HZLrXW%2FPbIXf2F5Z1zq0srDvG6rT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;489&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;정리&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;실제 네트워크 환경에서 패킷 error와 loss가 발생할 수 있으므로 제어를 위한 매커니즘이 필요하다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;error가 발생하면&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;checksum을 통한 error 감지, feedback, 재전송, seq num을 사용하여 제어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;loss가 발생하면&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;timer를 통한 time out 감지를 통해 재전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;성능&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;RDT는 신뢰성 있는 통신을 제공하지만 비효율적이다&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;효율성 계산&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;695&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uYBtW/btrVcMs0r1u/mkQ4PG6do3dqYmFA2OfiI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uYBtW/btrVcMs0r1u/mkQ4PG6do3dqYmFA2OfiI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uYBtW/btrVcMs0r1u/mkQ4PG6do3dqYmFA2OfiI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuYBtW%2FbtrVcMs0r1u%2FmkQ4PG6do3dqYmFA2OfiI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;696&quot; height=&quot;378&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;695&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Ttransmit: 실제 네트워크를 사용하는 시간&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Usender: sender 입장에서 전체 패킷이 전달되고 반환되는 시간 대비 네트워크를 사용하는 시간&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Usender를 보면 전체 시간 대비 네트워크를 사용하는 시간이 적다. 즉 sender 입장에서 RTT 만큼의 시간 동안 아무것도 안한다는 의미가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;만약 위 상황에서 3개의 패킷을 한번에 전송할 경우 Ttransmit이 3배가 되므로 효율은 0.00081이 될 것이다. 따라서, 여러 패킷을 한번에 보내고 한번에 결과를 받는 것이 효율적이다. &lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Pipelined protocols&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sender가 동시에 여러 패킷을 전송하고, 결과를 수신하도록 하는 접근 방법&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Go-Back-N&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;N개 만큼의 패킷을 한번에 전송하고, 실패하는 경우 해당 N개를 모두 재전송 하는 방식&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender는 window size 만큼의 패킷을 한번에 전송한다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;window size: feedback 받지 않고 한번에 보내는 패킷 갯수.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 패킷마다 seq num을 부여하여 중복 수신되는 패킷을 구분한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;seq num 순서에 따라서만 수신&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하고, &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;마지막으로 정상적으로 수신한 seq num을 ACK로 보낸다&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 feedback을 정상 수신하면, window s를 전진한다. 이미 성공한 패킷에 대해서는 신경쓰지 않음&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2, 1, 0 순으로 도착 -&amp;gt; receiver는 0번만 수신하고 1, 2는 drop -&amp;gt; sender는 1, 2를 다시 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;window size는 receiver가 반환하는 seq num에 따라 전진함(0번은 제대로 받았으므로 window 1칸 전진)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 패킷에 timer가 달려 있어 하나의 패킷이라도 time out 되는 경우 해당 window의 패킷을 전부 재전송한다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receiver는 순차적으로만 데이터를 수신한다. window size의 처음 번호에 위치한 패킷은 receiver가 다음으로 받아야 될 패킷이므로 window size 내 모든 패킷을 재전송한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;window size = 4 에서 에러가 발생하는 경우&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EGnMz/btrVh64QKXp/vw5q1ZNd7hub4g3U3SfB20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EGnMz/btrVh64QKXp/vw5q1ZNd7hub4g3U3SfB20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EGnMz/btrVh64QKXp/vw5q1ZNd7hub4g3U3SfB20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEGnMz%2FbtrVh64QKXp%2Fvw5q1ZNd7hub4g3U3SfB20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;160&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender는 0, 1, 2, 3 번 패킷을 전송합니다. receiver는 0, 1, 2, 3을 순차적으로 받아야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coX7nh/btrVcl3hPcY/Y2KfVWkUQ3oio4kkGmQ4u0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coX7nh/btrVcl3hPcY/Y2KfVWkUQ3oio4kkGmQ4u0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coX7nh/btrVcl3hPcY/Y2KfVWkUQ3oio4kkGmQ4u0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoX7nh%2FbtrVcl3hPcY%2FY2KfVWkUQ3oio4kkGmQ4u0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;166&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2번이 유실된 경우를 가정합니다. 2번이 유실되었으므로 receiver는 0, 1에 대해 ACK를 보냅니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 3번에 대해서는 수신은 했지만, 2번 부터 순차적으로 받아야 하므로 3번은 drop하고 마지막으로 정상 수신한 ACK 1를 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 0, 1 ACK를 수신하고, window를 전진시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zmSs5/btrVeb7dCRf/p6d6Sai8XV1NzFR3c5dguK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zmSs5/btrVeb7dCRf/p6d6Sai8XV1NzFR3c5dguK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zmSs5/btrVeb7dCRf/p6d6Sai8XV1NzFR3c5dguK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzmSs5%2FbtrVeb7dCRf%2Fp6d6Sai8XV1NzFR3c5dguK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;167&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender는 window를 전진시켰으므로 4, 5번을 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 2번을 받아야 하므로 4, 5 번을 drop하고 ACK 1을 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/34fMg/btrVak4CV7e/FCMMjpbJJ1rxChNqaukvo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/34fMg/btrVak4CV7e/FCMMjpbJJ1rxChNqaukvo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/34fMg/btrVak4CV7e/FCMMjpbJJ1rxChNqaukvo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F34fMg%2FbtrVak4CV7e%2FFCMMjpbJJ1rxChNqaukvo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;172&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2번 패킷이 유실되어 time out이 발생하면, sender가 이를 인지하고 window 사이즈 내 모든 패킷을 재전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 2, 3, 4, 5를 순차적으로 수신하고, ACK를 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;selective repeat&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Go Back N은 window size 내 하나의 패킷이라도 유실될 경우 전체를 재전송 하기 때문에 비효율 적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;selective repeat은 유실된 것이 확실한 패킷만 재전송하는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receiver에도 sender 처럼 window(버퍼)가 존재함&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receiver는 순차적으로 받아야 하는 패킷을 수신하면 application layer로 올리고 해당 패킷의 seq num에 대한 ACK 전송. 이후 window 전진&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;순서에 맞지 않더라도 패킷을 정상 수신하면 버퍼에 저장&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;버퍼가 모두 차면 해당 버퍼의 패킷을 모두 application layer로 올리고 window 전진&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 ACK를 수신한 패킷은 정상 수신된 패킷으로 간주하며, time out이 된 패킷만 재전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예시&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;227&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfwzke/btrVf7JJKxo/WMZdayGIa8KKy4SZ00ufT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfwzke/btrVf7JJKxo/WMZdayGIa8KKy4SZ00ufT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfwzke/btrVf7JJKxo/WMZdayGIa8KKy4SZ00ufT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbfwzke%2FbtrVf7JJKxo%2FWMZdayGIa8KKy4SZ00ufT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;227&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;227&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender는 window size 만큼의 패킷을 전달합니다. receiver는 sender와 동일한 크기의 window size 만큼의 버퍼를 두고 대기합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwVbYq/btrVeWWevcI/xzHwbXupkRKO1HxdUKRdW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwVbYq/btrVeWWevcI/xzHwbXupkRKO1HxdUKRdW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwVbYq/btrVeWWevcI/xzHwbXupkRKO1HxdUKRdW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwVbYq%2FbtrVeWWevcI%2FxzHwbXupkRKO1HxdUKRdW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;230&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2번이 유실된 경우를 가정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 0, 1, 3을 수신합니다. 0, 1번에 대해서는 application layer로 올리고, ACK를 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;3번에 대해서는 바로 올리지 않고 버퍼에 저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 0, 1, 3번에 대한 ACK를 수신하고 window를 전진시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BCtll/btrVeygXM5t/QusieQKLfFFGTVqL8hd4c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BCtll/btrVeygXM5t/QusieQKLfFFGTVqL8hd4c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BCtll/btrVeygXM5t/QusieQKLfFFGTVqL8hd4c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBCtll%2FbtrVeygXM5t%2FQusieQKLfFFGTVqL8hd4c0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;230&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;sender는 4, 5번 패킷을 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;receiver는 4,5번 패킷을 버퍼에 저장하고, ACK를 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b88F8s/btrVjml4cPG/SL11dK9TjtN8xjbjixBzgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b88F8s/btrVjml4cPG/SL11dK9TjtN8xjbjixBzgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b88F8s/btrVjml4cPG/SL11dK9TjtN8xjbjixBzgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb88F8s%2FbtrVjml4cPG%2FSL11dK9TjtN8xjbjixBzgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;230&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2번 패킷이 유실되어 time out이 발생합니다. sender는 2번 패킷을 재전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;227&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mQrsq/btrU9ejhJUC/KXPkuuLRfys0GzpX5pcZw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mQrsq/btrU9ejhJUC/KXPkuuLRfys0GzpX5pcZw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mQrsq/btrU9ejhJUC/KXPkuuLRfys0GzpX5pcZw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmQrsq%2FbtrU9ejhJUC%2FKXPkuuLRfys0GzpX5pcZw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;227&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;227&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;receiver는 2번 패킷을 수신하고, 2번에 대한 ACK를 전송합니다. 버퍼가 꽉 찼으므로 해당 패킷들을 application layer로 올리고 window를 전진합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender는 2, 4, 5번에 대한 ACK를 수신하고, window를 전진시킵니다. 이후, 다음으로 전송해야 하는 패킷을 전송합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문제: 최소 seq num의 범위&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;window size가 n일때 seq num을 n + 1까지 사용하면 패킷 구분이 안된다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;window size = 3, seq num = 0, 1, 2, 3 인 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;sender가 0, 1, 2를 전송 -&amp;gt; receiver가 0, 1, 2 수신 후 ACK 전송 -&amp;gt; 0, 1, 2 ACK가 누락됨 -&amp;gt; sender가 ACK를 다시 전송 -&amp;gt; receiver 입장에서 window가 전진된 새로운 seq num에 대한 패킷인지 아니면 재전송된 패킷인지 구분 불가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;대략적으로 seq num은 window size의 2배 만큼의 범위를 사용한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Network</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/76</guid>
      <comments>https://the-boxer.tistory.com/76#entry76comment</comments>
      <pubDate>Mon, 2 Jan 2023 16:56:23 +0900</pubDate>
    </item>
    <item>
      <title>application layer</title>
      <link>https://the-boxer.tistory.com/75</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. application layer&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;실제 컴퓨터에서 작동하는 프로세스가 속한 계층&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;네트워크는 다른 컴퓨터의 프로세스간 통신&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;클라이언트 - 서버의 프로세스간 통신&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;socket: 통신을 위한 interface. 프로세스가 OS에 네트워크 통신을 요청할 때 사용하는 interface&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;IP: 네트워크상 host 연결을 위한 주소. host를 식별하는데 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;port: 프로세스의 socket 연결을 위한 주소. host의 프로세스를 식별하는데 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;socket&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프로세스는 소켓을 통해 통신한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;application layer에서 transport layer에서 제공하는 소켓에 의존한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;소켓은 process에서 전달하는, process로 전달되는 데이터 제어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;transport layer에 대한 요구&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;application layer는 transport layer에서 제공하는 기능, 서비스를 사용함&lt;br /&gt;&lt;/span&gt;&lt;span&gt;제공하는 기능에 대한 요구는 다음과 같을 수 있으나 실제로 application layer는 데이터 안정성만 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;데이터 안정성: 데이터가 유실되지 않고 목적지에 도달함 -&amp;gt; TCP가 제공&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;시간 제약 -&amp;gt; 제공 X&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;스루풋 -&amp;gt; 제공 X&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;보안 -&amp;gt; 제공 X&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. client - server 구조&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;server&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;고정된 IP와 port를 가진다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;고정된 포트를 사용 이유(e.g http는 80번 사용)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;일종의 약속이나, 일정한 IP를 유지하는 이유와 같음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;서버 프로세스의 포트가 변경되면 클라이언트가 서버의 프로세스를 찾아갈 수 없다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;host의 요청을 기다림&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;client&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;서버와 통신&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;변경이 가능한 IP, port를 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;3. HyperText Transfer Protocol&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;hypertext를 전달하는 프로토콜&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;클라이언트가 요청하고자 하는 url로 리소스를 요청&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;웹 서비스가 http 위에서 동작하는 구조&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;client: send HTTP request&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;server: send HTTP response&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;transport layer&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;TCP를 사용하기 때문에 request, response 이전에 TCP connection 필요&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;연결 단계&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;서버가 TCP 소켓 개방&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;클라이언트가 TCP 연결 요청&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;서버가 클라이언트의 TCP 연결 요청 accept&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;HTTP 메세지 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TCP 연결 close&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;stateless&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;서버에서 client의 상태를 기록하지 않음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;persistent vs non-persistent&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;HTTP 통신은 한번의 TCP 연결에 하나의 object(hypertext, jpg...)를 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;여러 object를 받기 위해서 여러번의 TCP 연결이 필요하며 이는 비효율적&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;persistent: 한번의 TCP 연결로 여러 객체를 전달하는 방식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;non-persistent: 한번의 TCP 연결 마다 하나의 object 전송&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;동작 방식&lt;/span&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;try TCP connection&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;http request, response&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;close TCP connection&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;client parses hypertext&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;need more hypertext&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;start from 1. ...&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;그러나 이는 비효율적이므로 HTTP/1.1 에서는 pipelining 방식을 통해 response를 기다리지 않고 여러개의 request를 보내고 many response를 받는 방식으로 작동한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;response time&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;RTT: 클라이언트에서 전송된 패킷이 서버에 도달하여 다시 돌아오기 까지의 시간&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;non-persistent 연결 구조&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AcW0P/btrUlSAJgUL/WbVfzhWQky0GAbyNeKWmNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AcW0P/btrUlSAJgUL/WbVfzhWQky0GAbyNeKWmNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AcW0P/btrUlSAJgUL/WbVfzhWQky0GAbyNeKWmNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAcW0P%2FbtrUlSAJgUL%2FWbVfzhWQky0GAbyNeKWmNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;516&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(non-) persistent 모두 요청을 위한 RTT가 한 번 필요하고, 이후 object를 전달받는데 RTT + file transmission time이 소요된다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;non-persistent의 경우 n개의 object를 받는데: (2 * RTT + file transmission time) * object 수 가 소요된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;persistent의 경우 한번의 n개의 object를 받는데: RTT + (RTT + file transmission time) * object 수 가 소요된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;4. socket&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;네트워크를 위해 OS에서 제공하는 interface&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;application layer는 transport layer에서 제공하는 interface 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;어플리케이션은 네트워크 통신을 위해 &lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;TCP, UDP에 맞는 소켓을 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;소켓을 통해 데이터를 전송하고 받는다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;종류: TCP(SOCK_STREAM), UDP(SOCK_DGRAM) 소켓&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;API&lt;/span&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작 구조&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;3847&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0EpB9/btrUnXHwbgZ/AAzN3oHbCnR5FfAf8liCN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0EpB9/btrUnXHwbgZ/AAzN3oHbCnR5FfAf8liCN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0EpB9/btrUnXHwbgZ/AAzN3oHbCnR5FfAf8liCN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0EpB9%2FbtrUnXHwbgZ%2FAAzN3oHbCnR5FfAf8liCN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;369&quot; height=&quot;1109&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;3847&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;연결 준비&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;server&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;socket(): 소켓 생성&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;domain(IP), type(TCP, UDP), protocol을 인자로 받음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;생성된 소켓 번호(file descriptor) 반환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;bind(): 소켓을 특정 port에 바인딩&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;socket()에서 생성된 file descriptor, 서버의 IP/port, 주소 길이를 인자로 받음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;listen(): 클라이언트의 요청을 대기&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;file descriptor, backlog(connection queue 길이)를 인자로 받음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;accept(): 연결을 받을 준비 완료&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;file descriptor, 요청으로 들어온 클라이언트의 IP/port, 주소 길이를 인자로 받음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;클라이언트의 연결이 들어올 때 까지 blocking&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;client&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;connect(): 서버에 연결&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;클라이언트의 소켓 번호, 서버의 IP/port, 주소 길이를 인자로 받음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;데이터 전달&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;read(), write(): 연결 이후 데이터를 주고 받기 위한 API&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;연결 종료&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;close(): 연결이 끝난 뒤 소켓을 닫고, 점유했던 port를 반납한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 코드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
void cleanExit(){exit(0);}
​
#define PORT 7777
#define BACKLOG 10
​
int main(void) {
 &amp;nbsp; &amp;nbsp;signal(SIGTERM, cleanExit);
 &amp;nbsp; &amp;nbsp;signal(SIGINT, cleanExit);
​
 &amp;nbsp; &amp;nbsp;int sockfd, new_fd;
 &amp;nbsp; &amp;nbsp;struct sockaddr_in source_ip;
 &amp;nbsp; &amp;nbsp;struct sockaddr_in dest_ip;
 &amp;nbsp; &amp;nbsp;int sin_size;
​
 &amp;nbsp; &amp;nbsp;if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;perror(&quot;socket&quot;);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;exit(1);
 &amp;nbsp;  }
​
 &amp;nbsp; &amp;nbsp;source_ip.sin_family = AF_INET;
 &amp;nbsp; &amp;nbsp;source_ip.sin_port = htons(PORT);
 &amp;nbsp; &amp;nbsp;source_ip.sin_addr.s_addr = htonl(INADDR_ANY);
​
 &amp;nbsp; &amp;nbsp;if (bind(sockfd, (struct sockaddr *) &amp;amp;source_ip, sizeof(struct sockaddr)) == -1) {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;perror(&quot;bind&quot;);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;exit(1);
 &amp;nbsp;  }
​
 &amp;nbsp; &amp;nbsp;if (listen(sockfd, BACKLOG) == -1) {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;perror(&quot;listen&quot;);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;exit(1);
 &amp;nbsp;  }
​
 &amp;nbsp; &amp;nbsp;while(1) {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sin_size = sizeof(struct sockaddr_in);
​
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if ((new_fd = accept(sockfd, (struct sockaddr*) &amp;amp;dest_ip, (socklen_t*)&amp;amp;sin_size)) == -1) {
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;perror(&quot;accept&quot;);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;  }
​
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;printf(&quot;server: got conection from %s\n&quot;, inet_ntoa(dest_ip.sin_addr));
​
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;char result[] = &quot;hello world\n&quot;;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;write(new_fd, result, sizeof(result));
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;close(new_fd);
 &amp;nbsp;  }
}
​&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해당 서버를 실행하고 netcat을 통해 localhost:9898(IP:port) 로 요청하면 리턴값을 받을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반환&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;&amp;gt; nc localhost 9898
&amp;gt; hello world&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Computer Science/Network</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/75</guid>
      <comments>https://the-boxer.tistory.com/75#entry75comment</comments>
      <pubDate>Thu, 22 Dec 2022 17:53:06 +0900</pubDate>
    </item>
    <item>
      <title>통신 서비스와 라우터</title>
      <link>https://the-boxer.tistory.com/74</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. 통신 서비스&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;컴퓨터 네트워크를 위한 약속&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 통신은 프로토콜에 의해 제어됨&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;TCP&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;연결지향&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;신뢰성있는(reliable), 바이트 순서를 지켜서 전달되는 스트림 데이터 전달&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;흐름 제어: 수신자 송신자 사이에서 흐름 제어&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;송신측에서 수신측의 허용 데이터 처리량 보다 많은 데이터를 보내는 경우 TCP가 제어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;혼잡 제어: 네트워크 회선에 따라 제어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;UDP&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;어떠한 제어 없이 데이터 전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;데이터 유실 가능성 발생&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. 라우터&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;라우터의 데이터 전달 방식&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;circuit switching: 목적지 까지의 회선을 미리 연결해서 유저에게 제공&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;e.g 유선 전화망&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;packet switching: 패킷 단위의 데이터를 네트워크 링크를 통해 목적지로 전송&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;인터넷에서 사용하는 방법&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;packet delay&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;패킷: bit 단위로 이루어진 데이터를 모아놓은 데이터 전달 단위&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;네트워크 링크를 통해 라우터간 패킷 데이터를 전달하는 과정에서 다음과 같은 이유로 전달 시간에 지연이 발생함&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;nodal processing: 라우터에서 패킷 검사(비트 에러 검사, 목적지 라우터 선정)에 걸리는 시간&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;queueing: 라우터의 전송 대역보다 많은 데이터가 들어올 경우 링크를 타기 위해 queue에서 대기하는 시간&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;라우터의 전송 대역이 x Mbps 일 때 여러 클라이언트의 요청이 들어올 경우 허용된 라우터 전송 대역을 초과한 요청은 queue에서 대기함&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;transmission delay: 첫번째 bit ~ 마지막 bit 까지 나갈 때 까지 시간. 패킷 크기 / 대역폭 (bits / bps)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;propagation delay: 마지막 비트가 다음 라우터 까지 도달할 때 까지 시간. 물리적 링크의 길이 / 빛의 속도&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;delay를 줄이는 방법&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;nodal processing: 처리 성능이 좋은 라우터 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;queueing: 유저의 사용 패턴에 따른 요인이므로 통제 불간&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;transmission delay: 대역폭이 큰 회선 설치&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;propagation delay: 빛의 속도에 종속적이므로 통제 불가&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;queue 보다 많은 요청이 들어오면?&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;방법 없음. 라우터가 못받으므로 패킷 유실&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TCP는 신뢰성 있다 했는데?&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;유실된 패킷에 대해 재전송 한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;누가?&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;호스트(클라이언트)에서 재전송&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TCP는 클라이언트와 서버에 위치하여 작동 및 제어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;라우터는 전달만 한다 -&amp;gt; 전송만 신경쓴다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;패킷의 전달&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;하나의 비트가 라우터를 통과해도 모든 비트가 통과된 후 하나의 패킷 단위로 이동&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정리&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;653&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/45Iqb/btrTEzao039/ri4N9oanphRLJbVwJ3OcUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/45Iqb/btrTEzao039/ri4N9oanphRLJbVwJ3OcUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/45Iqb/btrTEzao039/ri4N9oanphRLJbVwJ3OcUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F45Iqb%2FbtrTEzao039%2Fri4N9oanphRLJbVwJ3OcUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;653&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;653&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Network</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/74</guid>
      <comments>https://the-boxer.tistory.com/74#entry74comment</comments>
      <pubDate>Wed, 14 Dec 2022 15:28:51 +0900</pubDate>
    </item>
    <item>
      <title>B tree, B+ tree</title>
      <link>https://the-boxer.tistory.com/73</link>
      <description>&lt;h1&gt;&lt;span&gt;B tree&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B tree는 root에서 leaft 노드 까지 모든 path의 길이가 동일한 tree 이며, Balanced 의 약자를 사용하여 B tree라 합니다. 인덱스를 조직하는 용도로 사용되며, m-원 탐색 트리로 키 값을 효율적으로 탐색할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;m-way search tree&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m-원 탐색 트리(m-way search tree) 혹은 다원 탐색 트리(multi search tree)라고도 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;다원 탐색 트리는 하나의 노드가 최대 m개의 서브 트리를 가질 수 있습니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;이진 탐색 트리는 m=2인 m-원 탐색 트리로 볼 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;특징&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B tree는 탐색을 효율적으로 하기 위한 몇 가지 특징이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;높이가 h인 m-원 트리는 최대 m^h - 1 개의 키 값을 저장할 수 있습니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;이진 탐색 트리의 경우 m=2를 만족하며, h=3인 경우 최대 7개의 키 값을 저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;m=4 이고, h=3인 경우 최대 63개의 키 값을 저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;한 노드가 갖고 있는 키 값 갯수가 k인 경우 1 &amp;lt;= k &amp;lt;= m 를 만족합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 노드의 키 값은 왼쪽부터 정렬된 상태를 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;k개의 키 값을 갖는 노드의 경우 k+1 개의 서브 트리를 갖습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 노드의 i번째에 저장된 저장된 키(Ki) 값보다 왼쪽에 위치하는 서브 트리의 모든 키 값들은 Ki 보다 작으며 오른쪽에 위치하는 모든 키 값들은 Ki보다 큽니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;root와 leaf 노드를 제외한 모든 모드는 내부 노드(internal node)라 합니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;내부 노드는 최소 m/2 최대 m개의 서브 트리를 가지며, m/2 - 1 개의 노드를 갖습니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m/2 인 이유? 트리 전체의 노드 갯수가 많아져 트리의 높이가 높아지는 경우 탐색 속도가 저하 될 수 있습니다. 이를 방지하기 위해 최소 서브 트리 갯수를 지정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;root가 그 자체로 leaf가 아니라면 최소 2개 이상의 자식 노드를 갖습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 leaf 노드는 같은 레벨이어야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;m = 4, h = 3인 경우&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;331&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs4DF5/btrRjpWDZ40/kkOn7ppVHKgqyH5yu229hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs4DF5/btrRjpWDZ40/kkOn7ppVHKgqyH5yu229hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs4DF5/btrRjpWDZ40/kkOn7ppVHKgqyH5yu229hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs4DF5%2FbtrRjpWDZ40%2FkkOn7ppVHKgqyH5yu229hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;331&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;331&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m = 4, h = 3인 m원 트리 예시를 봅시다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 leaf 노드는 같은 레벨에 위치하며, 총 leaf 노드 갯수는 16개 입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 노드에 저장할 수 있는 키 값은 총 3개이며, 총 노드 갯수는 21개 이므로 총 63개의 키 값을 저장할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;한 노드에서 3개의 키 값을 저장할 수 있으며, 총 4개의 자식 노드를 가질 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;노드 구조&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2964&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EChDO/btrRn7zRtQH/K9GeVUIfWQycjcJlkwMMO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EChDO/btrRn7zRtQH/K9GeVUIfWQycjcJlkwMMO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EChDO/btrRn7zRtQH/K9GeVUIfWQycjcJlkwMMO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEChDO%2FbtrRn7zRtQH%2FK9GeVUIfWQycjcJlkwMMO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2964&quot; height=&quot;284&quot; data-origin-width=&quot;2964&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하나의 노드는 다음과 같은 구조를 갖습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m: Btree의 차수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Pi: 자식 노드에 대한 포인터&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Ki: 하나의 노드의 i번째 키 값&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;노드의 키 값과 포인터 관계에 대해&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;i번째 키 값인 Ki의 왼편에 위치한 포인터 Pi 가 가리키는 서브 트리의 키 값은 모두 Ki 보다 작으며, 오른쪽에 위치한 서브 트리의 모든 값은 Ki 보다 큽니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;m=4 인 경우&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2964&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcKgrn/btrRiZKy9kf/1nKIGKNGUycgtjUKZVbf90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcKgrn/btrRiZKy9kf/1nKIGKNGUycgtjUKZVbf90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcKgrn/btrRiZKy9kf/1nKIGKNGUycgtjUKZVbf90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcKgrn%2FbtrRiZKy9kf%2F1nKIGKNGUycgtjUKZVbf90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2964&quot; height=&quot;284&quot; data-origin-width=&quot;2964&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;P1, P2, P3, P4: 자식 노드의 포인터가 저장됩니다. m=4인 경우 m개의 자식 노드를 갖습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;K1, K2, K3: m=4인 경우 최대 3개의 키 값을 저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;탐색&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;n개의 데이터가 저장된 B tree의 경우 하나의 키 값을 탐색하는데 총 O(log(n))의 시간이 소요됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;탐색은&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;root에서 찾고자 하는 키 값이 위치한 노드의 높이까지 내려가는 로직&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;노드에서 키 값을 찾는 로직&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두가지로 구성됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;최악의 경우를 가정하여 키 값이 leaf노드에 있다고 가정합니다. B tree의 높이는 log(n) 이고, 각 노드에 m개의 데이터가 있다고 가정하면, 1. 에 대해 log(n), 2. 에 대해 log(m) 만큼의 시간이 소요되어 총 log(n) * log(m) 의 시간이 소요됩니다. 일반적으로 n &amp;gt;&amp;gt; m 이므로 탐색에 대한 시간복잡도는 O(log(n))이 소요됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2. 가 O(log(n))이 소요되는 이유&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;노드에서 데이터를 탐색하므로 선형 시간(n)이 걸릴 것이라고 생각할 수 있지만, B tree는 한 노드의 키 값 들이 정렬된 상태를 유지하므로 이진 탐색을 통해 키 값을 탐색할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;삽입&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;btree는 위에서 설명한 특징(정렬된 상태, leaf 노드 동일 레벨)을 유지해야 되므로 삽입 과정이 조금 복잡합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;삽입 과정&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;삽입 위치: leaf 노드. leaf 노드에 키 값이 들어갈 만한 적절한 위치를 탐색하고 삽입합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;overflow가 발생시: 노드를 2개로 나누고 m/2 번째 인덱스의 키 값을 상위 노드로 올립니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;상위 노드로 올리는 프로세스가 계속되어 root에서 overflow가 발생하면, root 노드를 둘로 나누고 tree의 높이를 증가시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWz9Zw/btrRnOgdkw1/U7TdK1bqTrPEYPNmkqP02k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWz9Zw/btrRnOgdkw1/U7TdK1bqTrPEYPNmkqP02k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWz9Zw/btrRnOgdkw1/U7TdK1bqTrPEYPNmkqP02k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWz9Zw%2FbtrRnOgdkw1%2FU7TdK1bqTrPEYPNmkqP02k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;344&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m=4 인 btree를 예시로 봅시다. 위 그림에서 15라는 키 값이 추가되는 상황입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caOEXz/btrRoqTwXGo/66KyEFj3VV5JZSxUN1TfJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caOEXz/btrRoqTwXGo/66KyEFj3VV5JZSxUN1TfJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caOEXz/btrRoqTwXGo/66KyEFj3VV5JZSxUN1TfJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaOEXz%2FbtrRoqTwXGo%2F66KyEFj3VV5JZSxUN1TfJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;338&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;btree는 정렬된 상태를 유지해야 하므로 leaf 노드에서 들어갈 만한 자리는 4번째 노드입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;4번째 노드에 삽입한 경우 overflow가 발생합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;243&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UqnTv/btrRnp2jCfA/aYyOIQEaeg8D0mK2mLYZk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UqnTv/btrRnp2jCfA/aYyOIQEaeg8D0mK2mLYZk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UqnTv/btrRnp2jCfA/aYyOIQEaeg8D0mK2mLYZk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUqnTv%2FbtrRnp2jCfA%2FaYyOIQEaeg8D0mK2mLYZk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;243&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;243&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;overflow가 발생하여 노드를 둘로 나눕니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;m/2 = 2번 인덱스에 위치한 13을 상위 노드(root)로 올립니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2EAug/btrRnJ68CZc/uqFOVoLJG2uWxRg9deP1vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2EAug/btrRnJ68CZc/uqFOVoLJG2uWxRg9deP1vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2EAug/btrRnJ68CZc/uqFOVoLJG2uWxRg9deP1vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2EAug%2FbtrRnJ68CZc%2FuqFOVoLJG2uWxRg9deP1vk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;283&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;root에 13을 올리면 root에서도 overflow가 발생합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;root에서 overflow가 발생했으므로, 노드를 둘로 나누고 tree의 높이를 증가시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uQ6Cu/btrRnkz1axy/9WoKzqvyzN8h5XPppwvFt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uQ6Cu/btrRnkz1axy/9WoKzqvyzN8h5XPppwvFt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uQ6Cu/btrRnkz1axy/9WoKzqvyzN8h5XPppwvFt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuQ6Cu%2FbtrRnkz1axy%2F9WoKzqvyzN8h5XPppwvFt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;403&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m/2 번째 인덱스인 10을 상위로 올리면서 tree의 높이를 증가시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;삭제&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;삭제 과정 또한 btree의 특징을 유지해야 하며, 삽입 과정에 비해 조건에 따라 삭제 방법이 달라 조금 복잡합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;삭제 과정&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;삭제 위치: leaf 노드.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;삭제해야 되는 값이 leaf 노드에 있다면 그대로 삭제합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;만약 삭제해야 되는 값이 leaf 노드에 있지 않다면, 해당 키의 바로 이전 값과 다음 값 중 하나를 선택하여 위치를 교환하고 삭제합니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;해당 값의 이전 값 혹은 다음 값은 leaf 노드에 위치하므로, 위치 교환 이후에는 leaf 노드에 있는 값을 삭제하게 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ex) 11, 12, 13 이 저장되어 있는 경우 12를 삭제해야 한다면, 11과 13중 하나를 선택하여 12를 삭제 후 12의 위치로 옮김&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/li70O/btrRnjA8f74/MlZXPEDb0KiRKPTY5ax8o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/li70O/btrRnjA8f74/MlZXPEDb0KiRKPTY5ax8o0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/li70O/btrRnjA8f74/MlZXPEDb0KiRKPTY5ax8o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fli70O%2FbtrRnjA8f74%2FMlZXPEDb0KiRKPTY5ax8o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;405&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;11을 삭제하는 경우를 봅시다. 이전 값인 10을 leaf 노드에서 찾습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1XyGg/btrRnleFcFA/sPCQJHoVN4NoF3GUh1wdO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1XyGg/btrRnleFcFA/sPCQJHoVN4NoF3GUh1wdO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1XyGg/btrRnleFcFA/sPCQJHoVN4NoF3GUh1wdO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1XyGg%2FbtrRnleFcFA%2FsPCQJHoVN4NoF3GUh1wdO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;419&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;11을 삭제하고 10을 기존 11의 위치에 위치시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;이전(transfer)&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;만약 삭제 후 leaf 노드에 underflow가 발생하면(m/2-1개의 키 값을 갖게 된다면) 인접한 형제 노드에서 키를 추가할 노드를 찾습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;인접한 형제 노드가 m/2(최소 키 갯수) 보다 많은 갯수 개의 키 를 보유하고 있다면, 해당 노드의 키를 부모 노드로 이동하고, 부모 노드의 키 하나를 undeflow가 발생한 노드로 이동시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCBkXO/btrRiZX6mKs/gYkhXTaUygm3TXrmrD4W2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCBkXO/btrRiZX6mKs/gYkhXTaUygm3TXrmrD4W2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCBkXO/btrRiZX6mKs/gYkhXTaUygm3TXrmrD4W2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCBkXO%2FbtrRiZX6mKs%2FgYkhXTaUygm3TXrmrD4W2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;405&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;5를 삭제하는 경우입니다. 5를 삭제할 경우 leaf 노드의 2번째 노드는 최소 키 갯수를 만족하지 못하게 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uX5dV/btrRmv2TY38/uGPkwu7Y2Jt3tTOETcI3aK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uX5dV/btrRmv2TY38/uGPkwu7Y2Jt3tTOETcI3aK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uX5dV/btrRmv2TY38/uGPkwu7Y2Jt3tTOETcI3aK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuX5dV%2FbtrRmv2TY38%2FuGPkwu7Y2Jt3tTOETcI3aK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;405&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;인접한 형제 노드에서 최소 키 갯수 보다 많이 키를 가진 노드에서 7을 이전 시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pHtjQ/btrRn08D228/FJVZ1KdyPMCTYL8snpvMc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pHtjQ/btrRn08D228/FJVZ1KdyPMCTYL8snpvMc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pHtjQ/btrRn08D228/FJVZ1KdyPMCTYL8snpvMc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpHtjQ%2FbtrRn08D228%2FFJVZ1KdyPMCTYL8snpvMc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;405&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;7을 부모 노드로 이동 -&amp;gt; 부모 노드의 6을 undeflow로 내립니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;합병(fusion)&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;leaf 노드의 인접한 형제 중 최소 키 갯수 보다 많은 키를 보유한 노드가 없다면, 형제 노드 + 부모 노드의 키 + undeflow가 발생한 노드를 합병합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;합병을 진행할 때 부모 노드의 키를 하나 빼게 되는데 이 과정에서 부모 노드의 키가 최소 키 갯수를 만족하지 않게 되는 경우 이 과정을 root 까지 반복합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/72o6C/btrRoyKJjbE/pGFEmQp7bq0wq14kH3tbZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/72o6C/btrRoyKJjbE/pGFEmQp7bq0wq14kH3tbZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/72o6C/btrRoyKJjbE/pGFEmQp7bq0wq14kH3tbZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F72o6C%2FbtrRoyKJjbE%2FpGFEmQp7bq0wq14kH3tbZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;405&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;leaf 노드의 2를 삭제 한다고 가정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;2를 삭제할 경우 leaf의 첫번째 노드의 키 갯수가 1개가 됩니다. 또한, 인접한 노드의 키 갯수도 2개라 이전 또한 불가능합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/venrV/btrRjWmnKtu/YuD87CgY5W7x0bLsaxCknK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/venrV/btrRjWmnKtu/YuD87CgY5W7x0bLsaxCknK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/venrV/btrRjWmnKtu/YuD87CgY5W7x0bLsaxCknK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvenrV%2FbtrRjWmnKtu%2FYuD87CgY5W7x0bLsaxCknK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;405&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2를 삭제하고 합병을 진행합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;undeflow가 발생한 노드(1), 부모 노드의 키(3), 형제 노드(4,6) 를 합병합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxkW4i/btrRjV8RNEY/8gV6Isvv4x1wKe7UPqzpe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxkW4i/btrRjV8RNEY/8gV6Isvv4x1wKe7UPqzpe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxkW4i/btrRjV8RNEY/8gV6Isvv4x1wKe7UPqzpe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxkW4i%2FbtrRjV8RNEY%2F8gV6Isvv4x1wKe7UPqzpe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;437&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;합병하여 1,3,4,6 이 하나가 된 노드를 생성하였습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;합병 과정에서 부모에 있는 3을 내렸으며, 이 과정에서 부모 노드의 키 갯수가 최소 키 갯수를 만족하지 못하게 됐습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;합병을 한번 더 진행해야 하며, undeflow가 발생한 노드(7), 부모 노드의 키(10), 형제 노드(14,17) 을 합병합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sZwxq/btrRkbw1rhl/rZPjP4T1ohFJYooxompmZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sZwxq/btrRkbw1rhl/rZPjP4T1ohFJYooxompmZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sZwxq/btrRkbw1rhl/rZPjP4T1ohFJYooxompmZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsZwxq%2FbtrRkbw1rhl%2FrZPjP4T1ohFJYooxompmZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;330&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;저장 가능한 키 갯수&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m차 btree의 각 레벨별로 저장 가능한 데이터 갯수는 다음과 같습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;level&lt;/span&gt;&lt;span&gt;갯수&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;root&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;m-1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;m(m-1)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;m^2(m-1)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;m^3(m-1)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;h&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;m^(h-1) (m-1)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;m-1은 하나의 키의 갯수 이며 m^(h-1) 은 노드의 갯수입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;m차 btree에서 최대 저장 가능한 키의 갯수는 m^h - 1개가 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span&gt;B+ tree&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B tree가 변형된 구조로 B tree와 유사하지만, leaf 노드가 모두 연결리스트로 구성되어 있어 범위 탐색이 가능하며, 범위 탐색 기능에 대해 높은 성능을 보장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;특징&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;m 차 b+ tree를 기준으로 설명합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;btree의 변형으로 인덱스 세트(index set)와 순차 세트(sequence set)로 구성됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;root와 leaf 노드를 제외한 모든 노드는 최소 m/2 - 1 개 최대 m 개의 서브 트리를 가집니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 leaf 노드들은 같은 레벨에 위치합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;한 노드 안에 있는 키 값들은 정렬된 상태를 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;구성&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;인덱스 세트&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인덱스 세트의 노드는 실제 데이터는 저장하지 않으며, 순차 세트에 있는 키 값을 찾아 갈 수 있는 경로만 제공합니다. 인덱스 세트에 저장된 데이터는 실제 값이 아니며, 순차 세트에 있는 키 값을 찾아 갈 수 있는 용도로만 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음과 같은 특징을 갖습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;인덱스 세트도 B tree의 키 값들과 마찬가지로 정렬된 상태를 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;내부 노드들이 인덱스 세트에 해당합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;순차 세트&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;순차 세트는 실제 데이터가 저장된 노드들입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음과 같은 특징을 갖습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;leaf 노드들이 순차 세트에 해당됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;인덱스 세트의 모든 키 값을 포함하지는 않습니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;순차 세트의 키 값을 삭제해도 인덱스 노드의 키 값은 유지됩니다. 인덱스 세트의 노드는 순차 세트의 키 값을 찾아가기 위한 용도입니다. 순차 세트의 키 값을 삭제해도 인덱스 세트의 키 값을 찾아가기 위한 기능을 위해 인덱스 노드의 키 값은 유지될 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;인덱스 노드에 있는 키 값은 leaf 노드에 다시 나타날 수도 있고, 안 나타날 수도 있습니다. 순차 세트의 키 값 k 가 삭제된 경우 인덱스 노드에 유지되는 키 값 k는 leaf 노드에서 나타나지 않을 수 있습니다. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;순차 세트의 노드는 연결리스트로 구성되어 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B+ tree 예시&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;313&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceU2rF/btrRmUuIn5B/csTzEwPWkxpBVRiRfXb581/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceU2rF/btrRmUuIn5B/csTzEwPWkxpBVRiRfXb581/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceU2rF/btrRmUuIn5B/csTzEwPWkxpBVRiRfXb581/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceU2rF%2FbtrRmUuIn5B%2FcsTzEwPWkxpBVRiRfXb581%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;313&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;313&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;탐색&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B tree와 마찬가지로 B+ tree도 탐색에 O(log(n)) 만큼의 시간 복잡도가 소요됩니다. 다만, B+ tree는 모든 leaf 노드가 연결리스트로 구성되어 범위 탐색에 효율적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;N개의 데이터가 저장된 B tree에서 m(범위 i ~ j)개의 갯수에 대한 범위 검색을 한다고 가정합니다. B tree의 경우 하나의 데이터를 탐색하는데 O(log(n)) 만큼의 시간이 소요됩니다. 탐색을 m개의 데이터에 대해 반복해야 하므로 총 O(m*log(n)) 만큼의 시간이 소요됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B+ tree의 경우 leaf 노드가 연결리스트가 되어 있으므로&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;범위 검색에 대한 시작점 i를 탐색&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;i 부터 j 까지 선형 탐색&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 가지 단계로 범위 탐색이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B+ tree의 i 가 위치한 leaf 노드 까지 내려가는데 높이 만큼의 시간(log(N))이 소요됩니다. i 에서 j 까지 m개의 데이터에 대해 선형 탐색을 하므로 m 만큼의 시간이 소요됩니다. 따라서 범위 탐색에 대해 O(m + log(N)) 만큼의 시간 복잡도가 소요됩니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Data Structure</category>
      <author>Prower</author>
      <guid isPermaLink="true">https://the-boxer.tistory.com/73</guid>
      <comments>https://the-boxer.tistory.com/73#entry73comment</comments>
      <pubDate>Fri, 11 Nov 2022 20:23:16 +0900</pubDate>
    </item>
  </channel>
</rss>