강남역 REAL LINUX 세미나 노트
리눅스 세미나 개인 요약 필기 및 정리 노트
2019.11.28
REAL LINUX
2019.11.27 수요일 강남역에서 진행된 세미나
전세계 OS의 70퍼센트는 리눅스다.
개발자로써, 내가 만든 프로그램이 리눅스에서 돌아갈 확률이 높다.
트레이싱 : 디버그와 다르게, 프로그램의 동작을 가시적으로 확인 하는 것.
uftrace : User + Library + kernel 함수까지 다 보는 것들!
리눅스, 제대로 알고 코딩하자!
리눅스 커널도 C 프로그래밍이다
OS가 하는일?
- 사용자 application 관리
- HW 자원 관리 ( cpu, RAM, disk )
중요한것은 사용자 어플리케이션 관리이다! OS의 본 목적을 잊지 말자.
OS의 구성
- Core 부분 : 프로세스 매니지먼트 PM, 메모리 매니지먼트 MM , IRQ, Locking
- I/O 처리 : 네트워크, 스토리지 (VFS/FS/Block), 디바이스 드라이버
- 기타 : 보안, 툴, 소리
core부분은 다른 파트가 사용할 수 있는 API라고도 볼 수 있다.
위의 파트들 중 가장 개발이 활발한 분야는? 드라이버다.
따라서 어떤 제품을 판매 할 때 디바이스 드라이버에 넣는게 중요할 텐데
디바이스 드라이버 메인테이너 같은 사람을 직접 구인하거나 기부를 하고 있다.
커널도 make명령어로 컴파일 할 수 있는데, c를 컴파일하면 a.out이라는 바이너리로 나오는 것 처럼,
커널 코드도 make로 컴파일하면 vmlinux라는 하나의 아웃풋으로 출력하게 된다.
ELF는 Section의 모음이다. 우리가 짠 코드는 .text에 들어 있다.
마찬가지로 우리가 만든 vmlinux 또한 Section의 모음이며, 마찬가지로 .text에 코드가 들어있다.
따라서 커널또한 우리가 만든 C와 다를 바 없는 프로그램이다.
페이지폴트는 왜 발생할까?
컴퓨터, SW 동작 과정
CPU → 뇌
Memory → 공책
Disk → 책
우리가 디스크에서 프로그램을 실행하면 메모리에 적재됨! → 공책에 문제를 적음
CPU는 문제를 풀 때 풀이를 적을 수 있음 → 풀이를 적음
이때 문제는 text코드이며, 풀이는 stack, heap이라고 볼 수 있음.
그럼 페이지 폴트는 왜 발생할까?
물리 페이지 프레임이 없어서 : 이거는 부적절한 답변! 미분 거꾸로한게 적분이야! 같은 거임
페이지 폴트는?
메모리를 관리하는 하나의 메커니즘 때문에 생기는 문제. 진짜 메모리 조각을 지 않고 가상 메모리 조각만 주는 경우에 발생한다.
메모리를 사용 할 수 있는 애들이 있음 (프로그램들 : 크롬, 슬랙, 빔 … ) 얘네들은 메모리를 페이지라는 단위로 받아오는데, OS는 메모리를 실제로 주는게 아니라
가짜 종이를 나눠줌! 그게 페이지이다.
이때 보통 한 페이지가 4K이므로, 참고할 수 있는 주소가 4096개가 있는거임.
-
바이너리 인터페이스 깨짐 현상
가상 어드레스를 왜 사용할까? int a = 1; 이라고 하는 코드는 컴파일러에 의해서 mov 1 ( 주소 ) 이런 명령어로 바뀌게 되는데 이걸 피지컬 메모리로 사용하게 되면 내 컴퓨터에서 밖에 사용 할 수 있는 바이너리 인터페이스 깨짐 현상이 발생하게 된다.
왜 이렇게 사용할까?
- 실제로 필요할 때 요구하므로 메모리 절약할 수있다.
- 가상 메모리 레이어가 존재하므로 허가받지 못한 주소를 참조를 막을 수 있따.
- 바이너리 인터페이스 깨짐 현상 해결 ( 하드코딩 하지 않아도 된다. )
페이지 폴트의 종류는 2가지임. 인스트럭션을 가져오다가 폴트가 나거나, 아니면 힙이나 스택에 접근하다가 폴트가 나거나.
왜냐하면 리눅스에서는 프로그램 코드, 힙, 스택모두 가상 메모리에 올리기 때문임!!
ps -eo rsss,vsz,comm | head -2
명령어를 치면, 결과를 볼 수 있지만, 가상 메모리가 엄청엄청 커져도, 실제로 할당받는 애는 거의 없다.
성능적인 측면에서 늘리는 방법!
- 애초에 1이나 0을 마구 넣어서 피지컬 메모리를 잡아버린다.
- 폴트가 나서 느려지는것이니 폴트를 미리 내버린다!
페이지 관리 테이블은 프로그램마다 나눠져있다.
왜 하나가 아니라 여러개일까? 그것은 컴파일러가 컴파일 할 때 다른 프로그램과 무관하게 동작하게 하려고!
하기 때문이다. 그럼 프로그램이 여러개가 되면 페이지 테이블 개수도 같이 늘어나니까 엄청 무거워지지 않을까?
-
4레벨 페이지 테이블
페이지 테이블이 단순히 가상메모리와 피지컬 메모리의 1:1 매칭 이라면,
무려 공간이 4G = 4 * 1024 * 1024 개나 필요하므로, 여러가지 레벨로 나누어서
저장해 공간의 효율을 높인다.
리눅스 커널과 나의 서버 프로그램의 관계 및 성능에 미치는 영향?
System call interface |
VFS (virtual file system) Layer |
Indivisual File System Layer |
Block Layer |
문제 상황 : 커널 버전 업그레이드 이후 Disk I/O가 많아짐!
어디서 부터 봐야할까? → 트레이싱 기술이 중요하다.
커널에서 트레이싱 함수를 만들어서 어느 구간이 문제인지,
어느 구간에서 시간이 많이 걸렸는지를 체크할 수 있다.
트레이싱 기술의 중요성 강조!
연이어지는 call-graph 상에서 latency가 아니라
그냥 call count가 많아서 생기는 latency?
(latency : 자극과 반응사이의 시간 : 지연시간 )
read ahead 사이즈의 이해와 성능 영향?
컨테이너가 죽은 이유
- 컨테이너란?
-
chroot : 우리만의 공간 , namespace : 나만의 공간
-
cgroup : 나만의 자원, 우리만의 자원.
-
namespace를 눈에다 먹이면 나 혼자 리눅스를 쓰고 있다고 생각하는것과 비슷하나,
알고보면 다른 애들도 존재하는것이다.
활용 방법 ( Docker 컨테이너라고 보면 됨! )
cgroup은 메모리를 제한 해야하는 환경에서 직접 물리적 메모리를 바꾸지 않고도 제한할 수 있게해줌
namespace를 이용하면 아무것도 없는 빈 공간에서 나만의 프로세스를 돌릴 수 있음.
→ 나만의 독립된 리눅스 공간!
→ 어플리케이션 하나가 컨테이너 하나가될 수 있지만 하나의 컨테이너에 여러 어플레이케이션이 들어갈 수 있음!
다른 컨테이너가 죽은 이유
컨테이너를 사용 할 경우, 나는 나만 쓰는 리눅스라고 생각하고 있는데 옆 컨테이너의 영향에 의해
내가 죽을 수 있다! → 어처구니 없는 이유
실습 1! chroot를 통해 나만의 리눅스 만들기
sudo chroot rootfs /bin/bash
이럴경우 새로운 루트로 바뀌게 됨!
하지만 이때, ps 명령어를 입력하게 되면 프로세스를 기준으로 보면 프로세는 공유됨.
따라서 이것도 개인으로 바꿔주게 된다. (이런게 겹겹히 쌓여서 컨테이너가 된다.)
명령어 ~~
실습 2! cgroup을 통해서 메모리 제한하기
실습1 을 한 상태에서,
mkdir /sys/fs/cgroup/memory/test
echo 100000000 (100Mb) > /sys/fs/cgroup/test/memory.limit_in_bytes
echo 0 > /sys/fs/cgroup/memory/test/memory.swappiness ( 디스크에서 빌려오는거 금지 )
이때 메모리를 자꾸 먹는 py를 실행하면 죽는 모습을 볼 수 있다.
커널 기능을 통해 어떻게 죽는지도 볼 수 있다.
결론
리눅스는 더이상 어두운 Hidden Box가 아니다! 트레이싱과 함께라면 당신도 리눅스 삽고수
좋은 시간이었다!