<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>abc94 님의 블로그</title>
    <link>https://abc94.tistory.com/</link>
    <description>abc94 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Tue, 7 Apr 2026 14:27:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>abc94</managingEditor>
    <item>
      <title>디스크 관리(1)</title>
      <link>https://abc94.tistory.com/10</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 시간에는 리눅스 시스템 내, 디스크가 어떻게 관리되는지 공부하는 시간을 갖고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스를 운영 하다보면 디스크, 파일시스템 과 같은 용어들을 많이 접할 수 있는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼륨, 파일시스템, 마운트, 블록 I/O 등 대충은 무얼 뜻하는지 알지만 정확하게 설명하기는 난해한 부분이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;리눅스 커널이 어떻게 핸들링 하는지 확인해보면서 정확한 개념을 얻고자 하는게 이번 섹션의 목표입니다.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;피드백은 언제나 환영입니다.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 물리 디스크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 파일시스템&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 파티셔닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 볼륨&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 물리디스크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리 디스크란, SSD,HDD 와 같은 하드 디스크를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한, 디스크를 CPU가 인식하기 위해선 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;인터페이스 컨트롤러&lt;/b&gt;&lt;/span&gt;가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터페이스 컨트롤러란, 하드웨어와 소프트웨어의 결합체 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하드웨어 : HBA 카드 or 마더보드 컨트롤러 칩셋&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;소프트웨어 : 내장 펌웨어&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAS,SATA,NVME 중 어떠한 인터페이스를 사용할 지 여부는 하드웨어 인터페이스(HBA, 칩셋)에 의해 결정됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바이스 드라이버는 OS의 커널에 로드되며, 드라이버 모듈을 통해 어떠한 장치를 인식하는지 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외장 스토리지(SAN)의 경우, HBA 카드에 내장된 인터페이스 컨트롤러를 통해 CPU가 볼륨을 인식합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 디스크의 경우, 마더보드에 내장된 인터페이스 컨트롤러를 통해 CPU가 디스크를 인식할 수 있습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 86.2791%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7674%; text-align: center;&quot;&gt;특성&lt;/td&gt;
&lt;td style=&quot;width: 23.721%; text-align: center;&quot;&gt;SAS&lt;/td&gt;
&lt;td style=&quot;width: 19.5349%; text-align: center;&quot;&gt;SATA&lt;/td&gt;
&lt;td style=&quot;width: 28.2558%; text-align: center;&quot;&gt;NVME&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7674%;&quot;&gt;속도&lt;/td&gt;
&lt;td style=&quot;width: 23.721%;&quot;&gt;12 Gbps&lt;/td&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;6 Gbps&lt;/td&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;32 Gbps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7674%;&quot;&gt;Latency&lt;/td&gt;
&lt;td style=&quot;width: 23.721%;&quot;&gt;낮음&lt;/td&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;다소 높음&lt;/td&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;매우 낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7674%;&quot;&gt;사례&lt;/td&gt;
&lt;td style=&quot;width: 23.721%;&quot;&gt;데이터 센터&lt;/td&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;PC&lt;/td&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;고성능 스토리지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7674%;&quot;&gt;비용&lt;/td&gt;
&lt;td style=&quot;width: 23.721%;&quot;&gt;높음&lt;/td&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;낮음&lt;/td&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;높음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면, 신규 디스크를 OS에 인식하기 위해선 어떠한 과정이 필요할까요??&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 파일시스템&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 디스크를 어떠한 방법으로 OS가 읽기 / 쓰기를 할지 결정해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 &quot;파일시스템으로 변환한다&quot; 라고 표현 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;파일시스템이란,&amp;nbsp; RAW 디스크나 파티션을 OS 가 데이터를 저장하고 읽을 수 있도록 포맷한 상태 입니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 시스템을 생성하고 마운트하는 과정을 통해서 디스크를 사용합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 파티셔닝&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAW 디스크를 그대로 사용하지 않고 디스크를 왜 논리적으로 나누어서 사용하는 것일까요?&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;가장 강력한 이유는 디스크 공간을 용도에 맞게 분리하여 사용할 수 있기 때문입니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;각 파티션은 논리적으로 분리되어, 독립적으로 사용되며 서로의 파티션에 영향을 미치지 않습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1720440500816&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Disk /dev/xvda: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: D209C89E-EA5E-4FBD-B161-B461CCE297E0

Device       Start      End  Sectors  Size Type
/dev/xvda1    2048     4095     2048    1M BIOS boot
/dev/xvda2    4096   413695   409600  200M EFI System
/dev/xvda3  413696  2510847  2097152    1G Linux extended boot
/dev/xvda4 2510848 20971486 18460639  8.8G Linux filesystem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 논리 볼륨&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 저장할 수 있는 논리적인 저장 공간을 의미 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파티션이랑 무슨 차이점이 있으며 왜 사용하는 것일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;결론부터 말씀드리며, 디스크 공간을 훨씬 유연하게 관리할 수 있습니다.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, pvcreate, vgcreate, lvcreate 와 같은 명령어를 통해서 논리 볼륨을 생성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 파티션으로 파일시스템을 생성하게 되면, resize 하는데 매우 복잡합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, LVM을 통해 파일시스템 생성시, resize가 매우 간단하여, 필요에 따라 용량을 쉽게 조정할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1720441406104&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo lvextend -L +50G /dev/myvg/mylv
sudo resize2fs /dev/myvg/mylv&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 시간에는 간단하게 디스크 관련 개념을 익혀보는 시간을 가졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째 챕터에서 뵙겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도 감사합니다.&lt;/p&gt;</description>
      <category>Linux</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/10</guid>
      <comments>https://abc94.tistory.com/10#entry10comment</comments>
      <pubDate>Mon, 8 Jul 2024 21:30:45 +0900</pubDate>
    </item>
    <item>
      <title>가상메모리에 관하여(3)</title>
      <link>https://abc94.tistory.com/9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 시간에 가상 메모리의 생성 과정을 코드로 확인해보는 시간을 가졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 실제 프로세스 구동에 필요한 코드나 데이터는 물리 메모리(RAM) 에 존재하는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 오늘 시간에는 CPU가 어떻게 물리메모리를 접근할 수 있는지에 대해 알아보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0. 메모리 액세스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 페이지 테이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 페이지 Fault&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;0. 메모리 액세스&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메모리 액세스란, CPU 가 가상 메모리 주소를 사용하여 물리 메모리에 저장된 데이터나 명령어를 R/W 하는 과정입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이때, CPU는 물리 메모리 주소에 접근하기 위 프로세스의 페이지 테이블을 참조합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;메모리 액세스의 순서는 다음과 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(1) Fetch&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CPU가 프로그램 카운터(PC)로 부터 다음에 실행되어야 할 instruction 을 가져 옵니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(2) Decode&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;해당 명령어를 해석하여 물리 메모리 r/w 여부를 판단합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(3) Execute&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;명령어를 실행하는 과정인데, 메모리 접근이 필요할 시 CPU는 MMU(Memory Managemnet Unit) 을 통해 페이지 테이블을 조회하고 가상주소를 물리 주소로 변환합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이후, 변환된 물리 주소를 사용하여 물리 메모리에 데이터를 읽고 씁니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그러면, objdump 를 통해서 해당 과정을 빠르게 해석해봅시다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1720340891709&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[root@ip-10-0-142-220 ~]# whatis objdump
objdump (1)          - display information from object files&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1720340891710&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;root@ip-10-0-142-220 test]# objdump -d hello

000000000401136 &amp;lt;main&amp;gt;:
  401136:       55                      push   %rbp
  401137:       48 89 e5                mov    %rsp,%rbp
  40113a:       48 83 ec 10             sub    $0x10,%rsp
  40113e:       c7 45 fc 01 00 00 00    movl   $0x1,-0x4(%rbp)
  401145:       8b 45 fc                mov    -0x4(%rbp),%eax
  401148:       89 c6                   mov    %eax,%esi
  40114a:       bf 10 20 40 00          mov    $0x402010,%edi
  40114f:       b8 00 00 00 00          mov    $0x0,%eax&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;i&gt;저희가, 참고해야 될 부분은 mov1 instruction 입니다.&lt;/i&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;movl $0x1, -0x4(%rbp) 명령어는 '1' 을 메모리 위치에 저장하는 명령어 입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;Execute 시, 메모리 액세스가 발생하는데 CPU는 %rbp 레지스터와 해당 코드의 offset 을 조합하여 가상 메모리 주소를 얻습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;이후, MMU 를 통해 페이지테이블 조회하여 변환된 물리주소에 '1' 을 저장합니다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 페이지 테이블&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 실제 메모리에 있는 데이터를 읽거나 쓰기 위해서 물리 메모리 접근(Memory Access) 과정이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 OS 는 프로세스별 페이지 테이블을 생성하고, 이 페이지 테이블을 통해 가상 주소와 물리 주소간의 매핑이 이뤄집니다. CPU 는 페이지 테이블을 참조하여 물리 메모리에 접근합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAqjo/btsH2ndo4lW/g7YMFPamL8TYtPSEXfJgHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAqjo/btsH2ndo4lW/g7YMFPamL8TYtPSEXfJgHk/img.png&quot; data-alt=&quot;페이지 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAqjo/btsH2ndo4lW/g7YMFPamL8TYtPSEXfJgHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAqjo%2FbtsH2ndo4lW%2Fg7YMFPamL8TYtPSEXfJgHk%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;656&quot; height=&quot;329&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;페이지 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 코드를 통해 페이지 테이블을 이해해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1718543139168&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int main() {
  int a = 1;

  printf(&quot;Hello, World! %d\n&quot;, a);
  printf(&quot;Address of a: %p\n&quot;, (void*)&amp;amp;a);

  while (1){
    sleep(1);
  }

  return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gcc 컴파일러를 통해 hello.c -&amp;gt; hello (ELF) 파일로 변환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hello 코드 내, 변수 a를 선언하였고, 이는 가상 메모리 내 스택 주소공간에 할당됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 변수 a가 stack 공간에 할당 되었는지 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1720335662565&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-142-220 test]# ./hello
Hello, World! 1
Address of a: 0x7ffc4f649e9c&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1720335728528&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-142-220 ~]# pidof hello
35202
[root@ip-10-0-142-220 ~]# cat /proc/35202/maps
00400000-00401000 r--p 00000000 ca:04 9098393                            /root/test/hello
00401000-00402000 r-xp 00001000 ca:04 9098393                            /root/test/hello
00402000-00403000 r--p 00002000 ca:04 9098393                            /root/test/hello
00403000-00404000 r--p 00002000 ca:04 9098393                            /root/test/hello
00404000-00405000 rw-p 00003000 ca:04 9098393                            /root/test/hello
007ff000-00820000 rw-p 00000000 00:00 0                                  [heap]
7fed57c00000-7fed57c28000 r--p 00000000 ca:04 25540836                   /usr/lib64/libc.so.6
7fed57c28000-7fed57d9d000 r-xp 00028000 ca:04 25540836                   /usr/lib64/libc.so.6
7fed57d9d000-7fed57df5000 r--p 0019d000 ca:04 25540836                   /usr/lib64/libc.so.6
7fed57df5000-7fed57df6000 ---p 001f5000 ca:04 25540836                   /usr/lib64/libc.so.6
7fed57df6000-7fed57dfa000 r--p 001f5000 ca:04 25540836                   /usr/lib64/libc.so.6
7fed57dfa000-7fed57dfc000 rw-p 001f9000 ca:04 25540836                   /usr/lib64/libc.so.6
7fed57dfc000-7fed57e09000 rw-p 00000000 00:00 0
7fed57f56000-7fed57f5a000 rw-p 00000000 00:00 0
7fed57f5e000-7fed57f60000 r--p 00000000 ca:04 25540832                   /usr/lib64/ld-linux-x86-64.so.2
7fed57f60000-7fed57f86000 r-xp 00002000 ca:04 25540832                   /usr/lib64/ld-linux-x86-64.so.2
7fed57f86000-7fed57f91000 r--p 00028000 ca:04 25540832                   /usr/lib64/ld-linux-x86-64.so.2
7fed57f92000-7fed57f94000 r--p 00033000 ca:04 25540832                   /usr/lib64/ld-linux-x86-64.so.2
7fed57f94000-7fed57f96000 rw-p 00035000 ca:04 25540832                   /usr/lib64/ld-linux-x86-64.so.2
7ffc4f62a000-7ffc4f64b000 rw-p 00000000 00:00 0                          [stack]
7ffc4f6d2000-7ffc4f6d6000 r--p 00000000 00:00 0                          [vvar]
7ffc4f6d6000-7ffc4f6d8000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 수행되고 있는 hello 프로세스의 맵을 확인하기 위해, /proc/[pid]/maps 를 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 a 의 가상주소가 stack 섹션에 위치 함을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면, 해당 가상주소가 어떠한 물리 주소에 매핑되어 메모리 액세스를 진행하는지 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/proc/[pid]/pagemap 파일 시스템을 통해 알 수 있는데, pagemap 의 경우 바이너리 파일이라 신규 프로그램을 작성해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1720337072006&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;inttypes.h&amp;gt;

#define PAGEMAP_LENGTH 8

uint64_t get_pagemap_entry(uint64_t virt_addr) {
    FILE *f;
    uint64_t file_offset, pagemap_entry;
    ssize_t bytes_read;

    // Open the pagemap file for the current process
    f = fopen(&quot;/proc/self/pagemap&quot;, &quot;rb&quot;);

    // Calculate the offset in the pagemap file
    file_offset = (virt_addr / getpagesize()) * PAGEMAP_LENGTH;

    // Read the entry from the pagemap file
    bytes_read = fread(&amp;amp;pagemap_entry, 1, PAGEMAP_LENGTH, f);

    fclose(f);

    return pagemap_entry;
}

int main() {
    int a = 1;
    uint64_t virt_addr = (uint64_t)&amp;amp;a;
    uint64_t pagemap_entry = get_pagemap_entry(virt_addr);

    // Extract the physical page number (PPN)
    uint64_t phys_addr = (pagemap_entry &amp;amp; 0x7FFFFFFFFFFFFF) * getpagesize();
    
    printf(&quot;Virtual address: 0x%&quot; PRIx64 &quot;\n&quot;, virt_addr);
    printf(&quot;Physical address: 0x%&quot; PRIx64 &quot;\n&quot;, phys_addr);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1720337670253&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-142-220 test]# ./hello_pagemap
Virtual address: 0x7ffc4fdc6254
Physical address: 0x1b02f000&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 물리 메모리 접근 시, 컴파일된 프로그램의 offset 과 커널이 알고 있는 가상 메모리 주소를 결합하여 페이지 테이블을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 코드를 통해, 대략적인 페이지 테이블을 그려보면 아래와 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 71.6279%; height: 70px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;VA&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;PA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;0x7ffc4dc6254&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;0x1b02f000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 페이지 Fault&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Page Fault, ?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. CPU 가 페이지 테이블을 참조하는데, 가상 주소와 물리 메모리 주소가 매핑되지 않은 상태.&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 71.6279%; height: 70px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%;height: 17px;&quot;&gt;VA&lt;/td&gt;
&lt;td style=&quot;width: 50%;height: 17px;&quot;&gt;PA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%;height: 17px;&quot;&gt;0x7ffc4dc6254&lt;/td&gt;
&lt;td style=&quot;width: 50%;height: 17px;&quot;&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 페이지 테이블에 매핑 되어 있으나, SWAP OUT 되어 해당 페이지가 디스크에 있는 경우.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjisJA/btsIpvEaiL7/gtG0tnHOn4HzfwZtOZKQf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjisJA/btsIpvEaiL7/gtG0tnHOn4HzfwZtOZKQf0/img.png&quot; data-alt=&quot;swapping&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjisJA/btsIpvEaiL7/gtG0tnHOn4HzfwZtOZKQf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjisJA%2FbtsIpvEaiL7%2FgtG0tnHOn4HzfwZtOZKQf0%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;698&quot; height=&quot;614&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;swapping&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;이러한 경우, OS 는 어떠한 역할을 수행하게 될까요?&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Page Fault 처리 과정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 페이지 폴트 핸들러 실행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. OS 가 페이지 테이블을 검사 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 페이지 로드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 페이지 스왑 아웃의 경우, 스왑 영역에서 해당 페이지를 찾아 물리 메모리에 로드합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 신규 페이지의 경우, 물리 메모리에서 빈 페이지를 찾아 페이지 테이블을 업데이트 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 프로세스 재개&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도 방문해주셔셔 감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백은 언제나 환영입니다.&lt;/p&gt;</description>
      <category>OS</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/9</guid>
      <comments>https://abc94.tistory.com/9#entry9comment</comments>
      <pubDate>Sun, 7 Jul 2024 18:09:15 +0900</pubDate>
    </item>
    <item>
      <title>가상 메모리에 관하여(2)</title>
      <link>https://abc94.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 시간에 이어, 가상 메모리에 대한 이야기를 본격적으로 시작하고자 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0. 가상 메모리는 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 가상 메모리의 작동 원리&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0. 가상 메모리는 무엇일까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 메모리(Virtual Memory), 즉 가상의 메모리입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리는 CPU와 함께 프로세스 수행 시 중요한 역할을 담당하고 있습니다. CPU는 특정 프로그램 내, 함수를 무수히 실행한다면, 메모리는 해당 함수(코드)가 저장될 수 있는 공간을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가상 메모리는 OS에서 실제 메모리 보다 큰 주소 공간을 프로세스에게 제공하기 위해 고안된 메모리 관리 기법입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, &quot;그래서 도대체 뭐야?&quot;라는 의구심이 계속 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 윈도우즈 PC에서 Excel.exe 프로그램을 더블 클릭하면 엑셀 프로그램이 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면, 엑셀의 여러 기능들이 실행되기 위해선 CPU와 메모리가 필요하겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;여기서 Excel 프로세스만의 함수가 저장되는 공간을 가상 메모리로 이해해 주시면 됩니다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엑셀 프로그램 이외에, 크롬을 열었다고 생각해 봅시다. 그러면, 크롬 작업을 위한 별도의 가상메모리가 하나 더 할당됩니다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;즉, 프로세스의 개별 작업 공간입니다.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 메모리가 없으면 물리 메모리(RAM)를 크롬이나 엑셀 등이 같이 공유했겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 가상 메모리는 OS 커널이 생성/관리합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ylxTC/btsH1pbvkaG/oiZKgVX2yz225vkYFzwhN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ylxTC/btsH1pbvkaG/oiZKgVX2yz225vkYFzwhN1/img.png&quot; data-alt=&quot;가상 메모리 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ylxTC/btsH1pbvkaG/oiZKgVX2yz225vkYFzwhN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FylxTC%2FbtsH1pbvkaG%2FoiZKgVX2yz225vkYFzwhN1%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;630&quot; height=&quot;404&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;가상 메모리 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://velog.io/@tjdtn0219/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EA%B0%80%EC%83%81-%EB%A9%94%EB%AA%A8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@tjdtn0219/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EA%B0%80%EC%83%81-%EB%A9%94%EB%AA%A8&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진을 통해 알 수 있듯이, 프로세스마다 개별 작업 공간이 존재하는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. 가상 메모리의 작동 원리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 가상 메모리는 어떻게&amp;nbsp; 작동되는 것일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 프로그램의 실행과정, 즉 프로세스 생성 과정을 이해해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XgLN6/btsHZvktSui/mgfrMamZbto8qqNpNQcgMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XgLN6/btsHZvktSui/mgfrMamZbto8qqNpNQcgMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XgLN6/btsHZvktSui/mgfrMamZbto8qqNpNQcgMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXgLN6%2FbtsHZvktSui%2FmgfrMamZbto8qqNpNQcgMK%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;623&quot; height=&quot;335&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;335&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 실행되어야 할 파일, A.exe 가 SSD에 적재되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. User가 A.exe 실행 요청을 하면 A.exe 파일이 물리 메모리(RAM)에 로드됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 커널의 시스템 콜(execve)을 통해, A.exe 프로그램 경로와 실행에 필요한 인자를 커널에게 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 커널은 Process A를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 커널은 Process A를 위한 가상 메모리 공간(Virtual Memory A)을 할당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. execve 시스템 콜로부터 전달받은 프로그램 정보를 가상 메모리 공간에 매핑합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접, 프로그램을 실행하고 가상 메모리 매핑 과정을 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히, hello world를 print 하는 프로그램(ELF)을 만들었습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718444641633&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
  printf(&quot;Hello, World!\n&quot;);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1718444729891&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 test]# ls -al
total 28
drwxr-xr-x.  2 root root    34 Jun 15 18:44 .
dr-xr-x---. 12 root root  4096 Jun 15 18:44 ..
-rwxr-xr-x.  1 root root 17504 Jun 15 18:44 hello
-rw-r--r--.  1 root root    75 Jun 15 18:44 hello.c
[root@ip-10-0-131-237 test]# file hello
hello: ELF 64-bit LSB executable, x86-64&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1.&amp;nbsp;hello라는 프로그램을 실행해 보고, strace를 활용하여 시스템 호출을 추적하자.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1718445850687&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;strace -o strace.hello ./hello&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1718445900846&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 test]# cat strace.hello
execve(&quot;./hello&quot;, [&quot;./hello&quot;], 0x7ffc237213e0 /* 37 vars */) = 0
brk(NULL)                               = 0x14df000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe417925e0) = -1 EINVAL (Invalid argument)
access(&quot;/etc/ld.so.preload&quot;, R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, &quot;/etc/ld.so.cache&quot;, O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=30887, ...}) = 0
mmap(NULL, 30887, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe4b6531000
close(3)                                = 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제, execve 시스템 콜을 호출하는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. hello 프로세스의 가상 메모리 할당 주소와 gdb 디버거를 통해 비교해 보자.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-1. 위 소스 코드를 실행하면 실제 프로세스를 확인할 수 없으니, &lt;b&gt;&lt;i&gt;sleep 함수를 추가한 뒤, gdb를 통해 디버그 합니다.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718447720288&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 test]# gdb ./hello&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-2. run을 입력하여 실행시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1718448300063&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(gdb) run
Starting program: /root/test/hello
[Thread debugging using libthread_db enabled]
Using host libthread_db library &quot;/lib64/libthread_db.so.1&quot;.
Hello, World!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-3. /proc/pid/maps를 통해 hello 프로세스가 할당받은 가상 메모리 주소를 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1718448361291&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 292146]# cat maps
00400000-00401000 r--p 00000000 ca:04 10501005                           /root/test/hello
00401000-00402000 r-xp 00001000 ca:04 10501005                           /root/test/hello
00402000-00403000 r--p 00002000 ca:04 10501005                           /root/test/hello
00403000-00404000 r--p 00002000 ca:04 10501005                           /root/test/hello
00404000-00405000 rw-p 00003000 ca:04 10501005                           /root/test/hello
00405000-00426000 rw-p 00000000 00:00 0                                  [heap]
7ffff7c00000-7ffff7c28000 r--p 00000000 ca:04 8544281                    /usr/lib64/libc.so.6
7ffff7c28000-7ffff7d9d000 r-xp 00028000 ca:04 8544281                    /usr/lib64/libc.so.6
7ffff7d9d000-7ffff7df5000 r--p 0019d000 ca:04 8544281                    /usr/lib64/libc.so.6
7ffff7df5000-7ffff7df6000 ---p 001f5000 ca:04 8544281                    /usr/lib64/libc.so.6
7ffff7df6000-7ffff7dfa000 r--p 001f5000 ca:04 8544281                    /usr/lib64/libc.so.6
7ffff7dfa000-7ffff7dfc000 rw-p 001f9000 ca:04 8544281                    /usr/lib64/libc.so.6
7ffff7dfc000-7ffff7e09000 rw-p 00000000 00:00 0
7ffff7fb5000-7ffff7fb9000 rw-p 00000000 00:00 0
7ffff7fc1000-7ffff7fc5000 r--p 00000000 00:00 0                          [vvar]
7ffff7fc5000-7ffff7fc7000 r-xp 00000000 00:00 0                          [vdso]
7ffff7fc7000-7ffff7fc9000 r--p 00000000 ca:04 8544277                    /usr/lib64/ld-linux-x86-64.so.2
7ffff7fc9000-7ffff7fef000 r-xp 00002000 ca:04 8544277                    /usr/lib64/ld-linux-x86-64.so.2
7ffff7fef000-7ffff7ffa000 r--p 00028000 ca:04 8544277                    /usr/lib64/ld-linux-x86-64.so.2
7ffff7ffb000-7ffff7ffd000 r--p 00033000 ca:04 8544277                    /usr/lib64/ld-linux-x86-64.so.2
7ffff7ffd000-7ffff7fff000 rw-p 00035000 ca:04 8544277                    /usr/lib64/ld-linux-x86-64.so.2
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1718448394193&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(gdb) info proc
process 292146
cmdline = '/root/test/hello'
cwd = '/root/test'
exe = '/root/test/hello'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-4. main 함수의 가상 메모리 주소를 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1718448469309&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(gdb) info address main
Symbol &quot;main&quot; is at 0x401136 in a file compiled without debugging.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버거를 통해, main 함수의 가상 메모리주소가 0x401136 임을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 가상 메모리 내, 텍스트 세그먼트에 위치해 있음을 알 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1718448592599&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 292146]# cat maps
00400000-00401000 r--p 00000000 ca:04 10501005                           /root/test/hello
00401000-00402000 r-xp 00001000 ca:04 10501005                           /root/test/hello&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 가상 메모리의 매핑 과정을 눈으로 확인해 보았는데요. 실제 write 시스템 콜이 호출되면 Physical Memory Access 가 일어나게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 가상 메모리 주소만으로 물리 메모리 주소에 접근할 수 있을까요?&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;바로, 페이지 테이블이 존재하기 때문인데요!&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 시간에는 매핑된 페이지 테이블을 확인해 보고 코드 수행 동작을 살펴보는 시간을 갖겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도 감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/7</guid>
      <comments>https://abc94.tistory.com/7#entry7comment</comments>
      <pubDate>Sat, 15 Jun 2024 20:03:43 +0900</pubDate>
    </item>
    <item>
      <title>성능 지표(IOPS) 를 알아보자(2)</title>
      <link>https://abc94.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저번 IOPS 측정 방법 시간에 이어, 추가적인 내용을 작성하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 시간의 내용을 참고해보면, &quot;IOPS 는 블록사이즈와 반비례 한다&quot; 라고 전달드렸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼, 성능 측정을 하기위해 애플리케이션이 발생시키는 file I/O 의 블록 크기를 측정해야 하는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 시간에는 블록 사이즈를 측정하는 방법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백은 언제나 환영 입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;#.테스트 시나리오&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;1. dd 를 통한 빈 파일 생성&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;2. blktrace를 활용하여 블록 디바이스 트래픽 추적&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;3. 결과 확인&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. dd 를 통한 빈 파일 생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, dd 명령은 무엇일까요?&lt;/p&gt;
&lt;pre id=&quot;code_1717832255510&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 ~]# whatis dd
dd (1)               - convert and copy a file&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면, 해당 명령어를 통해 빈 파일을 생성함과 동시에, blktrace로 트래픽을 추적하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717832421335&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dd if=/dev/zero of=./file_2 bs=4K count=100000&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4K 블록을 100,000 번 수행하여 file_2 라는 파일을 생성해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717832604087&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;100000+0 records in
100000+0 records out
409600000 bytes (410 MB, 391 MiB) copied, 3.49065 s, 117 MB/s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;392MB의 파일이 생성되었습니다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. blktrace 를 통한 트래픽 추적&lt;/h4&gt;
&lt;pre id=&quot;code_1717832697742&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 ~]# whatis blktrace
blktrace (8)         - generate traces of the i/o traffic on block devices&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;u&gt;&lt;b&gt;※ 주의점, dd 를 통한 빈 파일 생성 명령어를 추적을 해야 하므로, 다른 터미널에서 아래 명령어를 동시에 실행해주세요&lt;/b&gt;&lt;/u&gt;.&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1717832817523&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 ~]# blktrace -d /dev/xvda4 -o - | blkparse -i -&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-d 옵션 뒤에는, 파일이 생성될 파티션 이름, blktrace 로 추적된 바이너리 정보를 blkparse 를 통해 읽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령어를 실행하면 추적 결과를 아래와 같이 보실 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUuDVv/btsHRYNcwCB/530WKRUa5ZkAKhB4vdYxnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUuDVv/btsHRYNcwCB/530WKRUa5ZkAKhB4vdYxnK/img.png&quot; data-alt=&quot;blkparse&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUuDVv/btsHRYNcwCB/530WKRUa5ZkAKhB4vdYxnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUuDVv%2FbtsHRYNcwCB%2F530WKRUa5ZkAKhB4vdYxnK%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;511&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;blkparse&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I/O 발생 CPU 번호, 이벤트 시퀀스, 타임스탬프, PID, 이벤트 타입, 블록번호와 길이 등이 보이네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 블록 사이즈를 알기 위해선.. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;블록번호와 길이 (ex. 4945936 + 256)&lt;/b&gt;&lt;/span&gt; 을 봐야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 섹터에 +256 (섹터 단위) 를 Write 한다 라고 이해할 수 있겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면, 해당 디스크의 섹터 단위는 어디서 확인 할 수 있을까요?&lt;/p&gt;
&lt;pre id=&quot;code_1717833554579&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 ~]# fdisk -l
Disk /dev/xvda: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: D209C89E-EA5E-4FBD-B161-B461CCE297E0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 디스크는 1 섹터가 512 byte 라는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로, 256 * 512 / 1024 = 128 KB 임을 알 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;근데, 여기서 의문점이 있습니다.. 분명 dd 를 통해 빈파일 생성 시, 4K 사이즈 단위의 블록을 생성한다고 했는데, 왜 128KB 씩 생성 했을까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 부분은 sysfs 파라미터를 보면 알 수 있습니다.&lt;/span&gt;&lt;/i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. 결과 확인&lt;/h4&gt;
&lt;pre id=&quot;code_1717834107837&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 queue]# cat /sys/block/xvda/queue/max_sectors_kb
128&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max_sectors_kb 파라미터의 값을 통해 원인을 알 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당, 파라미터는 리눅스 커널에서 I/O 요청의 최대 크기를 조정하는 데 사용되는 파라미터 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단일 I/O 요청으로 디스크에 보낼 수 있는 최대 데이터 크기를 결정 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 해당 파라미터는 sysctl 명령어를 통해 관리되지 않습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;sysfs 인터페이스를 통해 관리되며, 해당 인터페이스는 특정 하드웨어나 커널 서브시스템 관련 설정을 제공합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 값을 조정해보십니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717834325576&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@ip-10-0-131-237 queue]# echo 4 &amp;gt; /sys/block/xvda/queue/max_sectors_kb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 테스트를 다시 수행하면 우리가 원했던 4K 블록 사이즈 Write 트래픽이 발생됨을 보실 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 시간을 통해, blktrace 를 통해 트래픽을 추적해보고, 블록 사이즈를 실제 확인해 보는 시간을 가졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도&amp;nbsp; 감사합니다.&lt;/p&gt;</description>
      <category>Storage</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/6</guid>
      <comments>https://abc94.tistory.com/6#entry6comment</comments>
      <pubDate>Sat, 8 Jun 2024 17:19:27 +0900</pubDate>
    </item>
    <item>
      <title>성능 지표(IOPS) 를 알아보자(1)</title>
      <link>https://abc94.tistory.com/5</link>
      <description>&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;1. IOPS(Input/Output Operations Per Second)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스토리지 성능 평가 시, 중요하게 사용되는 지표 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스토리지 장치가 초당 수행할 수 있는 입출력 작업의 수를 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;각 작업의 평균 대기 시간(T)을 통해 IOPS를 계산할 수 있습니다:&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;&lt;span&gt;IOPS = 1/T(초 단위)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: center;&quot;&gt;&lt;span&gt;​작업 평균 대기시간이 0.5ms 인 경우, 초당 2000 개의 입출력 작업을 처리할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 작업이란, 서버와 스토리지 간에 읽기 또는 쓰기 작업을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDC 상에서 많이 사용되고 있는 디스크의 IOPS를 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSD : 10,000 - 100,000 IOPS&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VMWARE ESXI 환경에서, 스토리지 성능 측정 시 HCI Bench를 많이 이용합니다. 간단하게 사용 예제를&amp;nbsp; 보면서 해당 개념을 이해해봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HCI Bench 는 성능 지표로 사용될 VM 들을 클러스터로 묶어서 스토리지와 Block I/O 를 일으킵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;727&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ofzyJ/btsHMArY8Ld/gtlqmgSbP1n5YK1WNE0rSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ofzyJ/btsHMArY8Ld/gtlqmgSbP1n5YK1WNE0rSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ofzyJ/btsHMArY8Ld/gtlqmgSbP1n5YK1WNE0rSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FofzyJ%2FbtsHMArY8Ld%2FgtlqmgSbP1n5YK1WNE0rSK%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;300&quot; height=&quot;320&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;727&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number of Disks to Test : VM 에 할당된 디스크의 수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number of Threads Per Disk : IO 를 발생시킬 쓰레드의 수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Block Size : 블록 크기 설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 4 KB : 데이터베이스 트랜잭션&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 64 KB : 혼합된 I/O 패턴, 일반적인 파일 서버&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 1 MB : 대용량 파일 전송&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HCI Bench 는 위 사진처럼 스토리지 성능 테스트의 워크로드를 설계하고, 실제 테스트 수행은 VM 내, FIO 가 수행하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3,000 IOPS 를 제공하는 EBS 볼륨을 대상으로 진행했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#1. block size = 4K&lt;/p&gt;
&lt;pre id=&quot;code_1717646852359&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fio --name=small_block_test --filename=testfile --rw=randread --bs=4k --size=1G --numjobs=1 --runtime=60 --group_reporting --ioengine=libaio --iodepth=32&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#2. blcok size = 1M&lt;/p&gt;
&lt;pre id=&quot;code_1717647121479&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fio --name=small_block_test --filename=testfile --rw=randread --bs=1M --size=1G --numjobs=1
 --runtime=60 --group_reporting --ioengine=libaio --iodepth=32&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 비교&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 51px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;Throuput(KiB/s)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;IOPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;block size = 4K&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;6800&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;1700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;blcok size = 1M&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;55296&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;64&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로, 블록 사이즈의 크기의 반비례하게 IOPS 가 측정됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;오늘의 결론!&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;i&gt;&lt;b&gt;성능의 좋다/나쁘다를 판가름할 시,&amp;nbsp; IOPS 수치만 고려하는게 아닌, 애플리케이션의 I/O 블록 크기도 같이 고려해야겠죠?&lt;/b&gt;&lt;/i&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 시간에는 latency 에 대해 공부해보고, 어느정도의 수치가 사용자가 느끼기에 느리다고 생각할지?? 에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;</description>
      <category>Storage</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/5</guid>
      <comments>https://abc94.tistory.com/5#entry5comment</comments>
      <pubDate>Thu, 6 Jun 2024 13:25:35 +0900</pubDate>
    </item>
    <item>
      <title>성능 지표(Bandwidth, T-put) 를 알아보자 (1)</title>
      <link>https://abc94.tistory.com/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요 여러분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 성능 측정을 할때 좋다?? 나쁘다를 구분할 수 있는 기준들을 분석해 보는 시간을 갖겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 장비 모니터링을 하면서 위와 같은 수치를 굉장히 많이 접할 수 있었는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히, 어느 정도 수치가 객관적으로 좋은 수치인지는 환경에 따라 다르겠지만, 적어도 어떻게 계산되는지 알아야 할 필요는 있지 않을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백은 언제나 환영입니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;Throughput (T-put)&lt;/li&gt;
&lt;li&gt;Bandwidth (대역폭)&lt;/li&gt;
&lt;/ul&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;IOPS&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 네트워크 - Bandwidth 란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크를 통해 일정 시간 동안 전달 할 수 있는 최대 데이터 양을 뜻합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;대역폭 = 데이터 양(Data Size) / 시간(Time)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 10G 이더넷 케이블 / 32G FC 케이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDC 를 경험해본 분들이라면, 위와 같은 케이블을 많이 접할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 10G 이더넷 케이블의 경우, 초당 10 Gigabit 의 데이터 양을 전송할 수 있는 케이블 입니다. 주로, (서버-스위치) / (스위치-네트워크 장비) 연동 구간에 많이 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 32G FC 케이블의 경우, 초당 32 Gigabit의 데이터 양을 전송할 수 있겠죠? 주로, (서버HBA 카드 - SAN 스위치) / (SAN 스위치 - 스토리지) 연동 구간에 많이 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 얼만큼의 수치인지 가늠하기가 어렵기에, 바이트로 변환해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;32 기가비트는 약 4GB 로 환산할 수 있습니다. 따라서, 초당 4GB를 전송할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 4GB 짜리 영화 한편 정도는 1초만에 다운로드 할 수 있겠네요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 네트워크 - Throughput 이란 ?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 기준, Bandwidth 보다 살짝 더 감이 오지 않는데요.. 한번 같이 살펴보도록 하죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkFkIF/btsHMf8eRMq/SBtl58Kk9M37Dr85UmG4aK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkFkIF/btsHMf8eRMq/SBtl58Kk9M37Dr85UmG4aK/img.png&quot; data-alt=&quot;wireshark_statistics&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkFkIF/btsHMf8eRMq/SBtl58Kk9M37Dr85UmG4aK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkFkIF%2FbtsHMf8eRMq%2FSBtl58Kk9M37Dr85UmG4aK%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;600&quot; height=&quot;412&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;wireshark_statistics&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽 축을 보시면, Average Throughput (bits/s) 로 표시 된걸 확인 하실 수 있을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약, 1.8 * 10^8 임을 확인할 수 있고, 이는 180 Mbps 로 환산 할 수 있습니다. (1 Mbps = 1,000,000 bps)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;= 22.5MB/s&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는, 약 10GB 크기의 파일을 전송하는데, 7분 정도가 소요되는 시간 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;※ IDC 기존, 1Gbps 이상의 대역폭을 제공하는 케이블들로 네트워크가 구성되어 있습니다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;병목 현상, 네트워크 혼잡 등을 고려하더라도, 위 속도는 그저그런(?) 속도라고 보여집니다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Throughput = 총 전송된 데이터 양(bits) / 측정 시간(seconds)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR9JFs/btsHMcrg1WO/lIeJGtyJQ9AH1Pbolptde1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR9JFs/btsHMcrg1WO/lIeJGtyJQ9AH1Pbolptde1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR9JFs/btsHMcrg1WO/lIeJGtyJQ9AH1Pbolptde1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR9JFs%2FbtsHMcrg1WO%2FlIeJGtyJQ9AH1Pbolptde1%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;591&quot; height=&quot;322&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot; data-alt=&quot;Image from&amp;amp;nbsp;https://forum.huawei.com/enterprise/en/network-latency-vs-bandwidth-vs-throughput/thread/789837-861&quot; data-lightbox=&quot;lightbox&quot; data-url=&quot;https://blog.kakaocdn.net/dn/d4YQcr/btrJfqodENo/8wiL4zTLKMpIW4F6dPme91/img.png&quot;&gt;&lt;/span&gt;&lt;a href=&quot;https://forum.huawei.com/enterprise/en/network-latency-vs-bandwidth-vs-throughput/thread/789837-861&quot;&gt;https://forum.huawei.com/enterprise/en/network-latency-vs-bandwidth-vs-throughput/thread/789837-861&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 시간은 네트워크 성능 지표 측정은 위 수치 말고도 다양한 값들이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 부분은 추후 wireshark 편에서 공부해보도록 하겠습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스토리지 부분은 금방 업로드 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도 감사합니다!&lt;/p&gt;</description>
      <category>Network</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/4</guid>
      <comments>https://abc94.tistory.com/4#entry4comment</comments>
      <pubDate>Mon, 3 Jun 2024 21:16:33 +0900</pubDate>
    </item>
    <item>
      <title>com.jcraftjschJSchException-Auth-fail</title>
      <link>https://abc94.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사 내부에서 겪었던 오류와 문제 해결 과정에 대해 공유하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 원인 자체는 단순했습니다만, 원인을 찾고 해결하는 과정에서 얻은 러닝 포인트를 기록하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인 자체는 서버 계정 패스워드 변경 이슈 였습니다;;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;해결 과정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 인프라 구조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인을 파악하기 전, 이해를 돕기 위해 내부 인프라 구조를 간략하게 전달드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sty6t/btsHKA0cCn2/op7nbsKbvyt3zak0dZC4k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sty6t/btsHKA0cCn2/op7nbsKbvyt3zak0dZC4k0/img.png&quot; data-alt=&quot;인프라 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sty6t/btsHKA0cCn2/op7nbsKbvyt3zak0dZC4k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsty6t%2FbtsHKA0cCn2%2Fop7nbsKbvyt3zak0dZC4k0%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;660&quot; height=&quot;315&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인프라 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모니터링 서버(Jeus8)을 통해 San storage의 Health Check / Lun 생성 등을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특이하게, 특정 SAN 장비만 SSH 프로토콜을 이용해서 통신을 진행했었고, 별도의 Managing 서버를 통해 해당 Storage 에 명령어를 전달 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 발생 원인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹에서 표현되는 오류 만으로는 어떠한 이슈인지 알 수 없었기에, 소스를 통해 해당 원인을 분석하고자 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인이 되는 소스는 대략 아래와 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSCH 라이브러리를 통해 JAVA 에서 원격으로 SSH 명령어를 전달할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 소스는 계정 정보를 통해 해당 서버와 Session을 맺기 위한 소스로 볼 수 있겠군요&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;background-color: #000000; color: #0c0d0e; text-align: left;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

public class Main {

    public static void main(String[] args) throws JSchException, SftpException, IOException {
        
        String username = &quot;XXXXXX&quot;;
        String host = &quot;XXXXXX&quot;;
        String passwd = &quot;XXXXXX&quot;;
        JSch conn = new JSch();
        Session session = null;
        session = conn.getSession(username, host, 22);
        session.setPassword(passwd);
        session.setConfig(&quot;StrictHostKeyChecking&quot;, &quot;no&quot;);
        session.connect();

        channel.disconnect();
        session.disconnect();   

    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 해결 과정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 모니터링 서버에서는 Storage managing 서버와 SSH 접속이 잘 되는가?&lt;/li&gt;
&lt;li&gt;Storage managing 서버에서 secure 로그는 어떻게 찍혔을까?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3-1 실제 모니터링 서버에서는 Storage managing 서버와 SSH 접속이 잘 되는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 결과, 모니터링 서버와 Storage managing 서버와의 세션 연결은 잘되었습니다. 하지만, 간과하고 있었던 점이 하나 있었는데, SSH 프로토콜의 인증 방식은 두가지가 있다는 점이었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;키 인증 방식&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;패스워드 인증 방식&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;해당 부분에 대해서는 SSH 프로토콜 편에서 자세히 다루겠습니다.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3-2. Storage manaing 서버에서 secure 로그는 어떻게 찍혔을까?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;/var/log/secure&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssh 로그인 시도 / 인증 시도와 같은 로그를 저장하는 파일입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bByNbz/btsHMfAiOSH/xsJ8kPx35kdX2GxpVVGK20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bByNbz/btsHMfAiOSH/xsJ8kPx35kdX2GxpVVGK20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bByNbz/btsHMfAiOSH/xsJ8kPx35kdX2GxpVVGK20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbByNbz%2FbtsHMfAiOSH%2FxsJ8kPx35kdX2GxpVVGK20%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;936&quot; height=&quot;372&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;372&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 파일을 통해 com.jcraftjschJSchException-Auth-fail - password 오류 관련된 메시지를 발견할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(위 사진과는 무관합니다)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 패스워드가 변경되었는지 확인하기 위해, Storage Managing 서버에 저장된 모니터링 서버의 공개키를 제거하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패스워드가 어떠한 이유 때문인지는 모르겠지만, 모니터링 서버 DB 에 저장된 Password 와 달랐었습니다;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후, 패스워드 동기화를 통해 해당 문제를 해결했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 마치며..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 원인 자체는 되게 단순하였습니다.&lt;/p&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;/var/log/secure 파일의 역할&lt;/li&gt;
&lt;li&gt;SSH 프로토콜의 인증 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘도, 방문해 주셔셔 감사합니다.&amp;nbsp;&lt;/p&gt;</description>
      <category>Trouble Shooting</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/3</guid>
      <comments>https://abc94.tistory.com/3#entry3comment</comments>
      <pubDate>Sun, 2 Jun 2024 16:53:51 +0900</pubDate>
    </item>
    <item>
      <title>안녕하세요</title>
      <link>https://abc94.tistory.com/notice/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 / 네트워크에 호기심이 많은 시스템 엔지니어의 블로그 입니다.&lt;/p&gt;</description>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/notice/2</guid>
      <pubDate>Sat, 1 Jun 2024 23:26:19 +0900</pubDate>
    </item>
    <item>
      <title>가상 메모리에 관하여(1)</title>
      <link>https://abc94.tistory.com/1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;가상 메모리의 도입 배경과 어떤 방식으로 작동하는지 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백은 언제나 환영입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0. 우리는 왜 가상메모리에 대해 알아야 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실, 해당 개념을 모르더라도 프로그램 개발에 있어서 문제 될 건 없습니다. 물리적 메모리의 위치를 신경 쓰지 않아도, OS 가 메모리 관리를 해주고 있기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 엔지니어 기준, 가상 메모리에 대한 개념을 알아야 하는 이유는 다음과 같을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&amp;nbsp;시스템 엔지니어&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;리눅스 기준, top, vmstat, free 명령어를 통해 프로세스 메모리 모니터링을 합니다.&lt;/li&gt;
&lt;li&gt;우리는 아래와 같은 상황을 주로 접하게 됩니다.&lt;/li&gt;
&lt;li&gt;메모리 누수를 유발하고 있는 프로세스는 무엇이고, 해결을 어떻게 해야 하는지?&lt;/li&gt;
&lt;li&gt;특정 가상 메모리 주소를 사용하고 있는 코드에 문제가 있는 것은 아닌지?&lt;/li&gt;
&lt;li&gt;메모리 증설해야 될 상황에 대한 기준을 어떻게 잡을지?&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 가상 메모리의 도입 배경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 메모리 의존성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 메모리 단편화(Memory Fragmentation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보안&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;메모리 의존성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 메모리의 개념이 도입되기 전, 무슨 어려움이 있었을까요? 가장 까다로웠던 것은 개발자가 아닐까 싶습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 개발되고, 해당 프로그램이 실행되기 위해서는 메모리 자원을 활용해야 합니다. &lt;b&gt;즉, 프로그램의 코드와 데이터를 메모리에 로드를 해야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. 메모리 규격이 서버마다 다르면 무슨 문제점이 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말씀드리면, 개발자분들은 시스템의 메모리 구조와 크기에 맞춰 프로그램을 재컴파일 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 프로그램의 호환성이 매우 떨어지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 개발하는 것도 어려운데, 해당 코드의 물리적 메모리 위치까지 고려해서 만들면.. 굉장히 많은 노력이 들어가겠죠??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, 32bit 시스템의 경우 (2^32) 4GB의 메모리 주소를 갖게 됩니다. 해당 운영체제가 사용하는 공간도 있을 것이고, 여러 프로그램이 메모리를 공유해서 사용하기에, 프로그램의 메모리 배치는 더욱 까다로웠을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;메모리 단편화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 메모리 단편화 현상이 자주 발생되어 메모리의 효율성이 매우 떨어졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 단편화는 외부 / 내부로 나눠지는데, 해당 내용은 추후에 같이 공부해 보는 걸로..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우선, 외부 메모리 단편화는 물리적 메모리의 비연속적인 공간을 활용할 수 없는 문제입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아래의 그림처럼, Process D에 할당해 줄 물리적 자원은 있지만, 연속된 공간이 필요한 Process D는 메모리를 할당받을 수 없는 상황이 발생됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UbKlE/btsHKcZxyrA/ILL5g0PBi9y0aYBvMKeDP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UbKlE/btsHKcZxyrA/ILL5g0PBi9y0aYBvMKeDP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UbKlE/btsHKcZxyrA/ILL5g0PBi9y0aYBvMKeDP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUbKlE%2FbtsHKcZxyrA%2FILL5g0PBi9y0aYBvMKeDP1%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;820&quot; height=&quot;347&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot; data-alt=&quot;https://sycho-lego.tistory.com/9&quot; data-lightbox=&quot;lightbox&quot; data-url=&quot;https://blog.kakaocdn.net/dn/cJTGk5/btqzuPKCuNq/OTW4GBKni3cZgL0qlnwKF1/img.png&quot;&gt;&lt;/span&gt;&lt;a href=&quot;https://sycho-lego.tistory.com/9&quot;&gt;https://sycho-lego.tistory.com/9&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만, 가상 메모리 개념과 페이징 기법으로 인하여 해당 문제를 해결할 수 있었습니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;보안&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가상 메모리 시스템에서는 각 프로세스 별로 고유한 가상 주소 공간을 사용할 수 있습니다.&lt;/b&gt; 즉, 이러한 공간은 하나의 프로세스의 것으로 자신만의 공간이 생겼다는 의미입니다. 이 주소 공간은 다른 프로세스와 격리되어 타 프로세스가 해당 메모리 영역에 접근할 수 없도록 보장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. 이를 역으로 생각해면.. 가상 메모리의 개념이 없었을 시절에는 무슨 문제점들이 있었을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 프로세스들이 물리 메모리 주소 공간을 공유했기 때문에, 타 프로세스의 영역을 침범할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 자신에게 할당되지 않은 메모리 영역에 접근함으로써, 타 프로세스의 코드나 데이터를 변경할 수도 있었죠..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 가상 메모리 개념을 왜 알아야 하며, 가상 메모리의 개념이 왜 도입이 되었는지 고민해 보는 시간을 가졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 편에, 가상메모리의 구조를 알아보고 리눅스를 통해 직접 살펴보는(?) 시간을 갖겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방문해 주셔서 감사합니다.&lt;/p&gt;</description>
      <category>OS</category>
      <author>abc94</author>
      <guid isPermaLink="true">https://abc94.tistory.com/1</guid>
      <comments>https://abc94.tistory.com/1#entry1comment</comments>
      <pubDate>Sat, 1 Jun 2024 21:35:42 +0900</pubDate>
    </item>
  </channel>
</rss>