Skip to content

태그: BPF

eBPF로 서버 성능 Profiling하는 법: Pyroscope의 구현 살펴보기
공부
eBPF를 사용한 모니터링을 공부하며 Pyroscopee의 eBPF 기능에 관심이 생겼다. 구현 코드를 살펴보면서 eBPF를 활용하는 방법과 그에 연관된 Linux 기능을 익힐 수 있었는데, 내용을 되새기기 위해 공부했던 부분을 전체적으로 풀어 설명해보려 한다. 우선 관련된 기술 배경부터 알아보자. Pyroscope Grafana Pyroscope는 애플리케이션을 지속적으로 프로파일링하는 오픈소스 플랫폼이다. 프로파일링(profiling)이란? 프로그램을 실행하면서 성능을 측정하고, 분석하는 행위를 프로파일링이라고 한다. 함수 혹은 메소드가 CPU를 얼마나 오랫동안 사용하는가, 얼마나 많이 호출되는가 메모리를 얼마나 자주 할당 및 해제하는가, 얼마나 많이 할당하느냐 와 같은 정보를 측정한다. 애플
메모리 로딩
bpf
BPF는 일반적인 프로그램과 유사한 방식으로 개발하기 때문에 유사한 실행파일 및 메모리 구조를 가지고 있지만, 커널 안에서 제한된 환경으로 실행되기 때문에 로딩(loading) 또한 다른 방식으로 실행된다 데이터 유형 일반적인 실행파일에서 가장 중요한 두 가지는 코드와 데이터이다. 코드는 말그대로 상위언어를 컴파일한 머신코드를 의미하고, 데이터는 실행시 코드가 참조하는 메모리를 의미한다. 데이터는 스택과 힙같이 실행시 메모리가 할당/해제되는 동적 데이터와 전역변수처럼 코드에서 선언되는 정적 데이터로 나뉘는데, 정적 데이터는 실행파일을 로딩할 때 메모리가 할당되고 해당 메모리를 참조하는 코드도 재배치(relocation)된다. 그리고 정적 데이터는 크게 읽기전용 변수, 초기화된 전역변수 그리고
서브프로그램
bpf
BPF는 일반적으로 하나의 함수(main 함수)가 하나의 섹션이 되고, 하나의 섹션이 하나의 프로그램이 된다. 그리고 커널에서 해당 프로그램을 실행할 때는 프로그램의 시작 위치가 메인함수의 시작 위치이기 때문에 간단히 처음부터 실행하면 된다. 하지만 아래와 같이 메인함수에서 공통함수를 호출하는 경우처럼 두 개 이상의 함수가 필요한 경우에는 프로그램의 시작 위치를 어떻게 보장할까? BPF는 이러한 상황에서 시작 위치 보장을 위해 서브프로그램이라는 기능을 제공한다. 아래 코드는 bcc의 filetop 예제코드이다. 해당 예제는 vfs_read와 vfs_write 커널함수에서 각각 사용할 두 개의 BPF 메인함수와 두 개의 함수에서 사용하는 공통함수(probe_entry)로 구성되어 있다. static
BPF ring buffer
bpf
BPF 프로그램은 수집한 데이터를 후처리하고 로깅하기 위해 정보를 User space로 전송하는데, 대부분의 경우 이를 위해 BPF Perf buffer(Perfbuf)를 사용한다. Perfbuf는 CPU마다 하나씩 생성되는 순환 버퍼로, Kernel space와 Use space간 데이터를 효율적으로 교환할 수 있도록 한다. 하지만 Perfbuf에는 두가지의 문제점이 있었다. 각 CPU에 대해 별도의 버퍼를 사용하기 때문에 데이터 스파이크에 대응하기 위해서 각각의 버퍼크기를 크게 할당해주어야 한다. 이 때문에 필요한 것 보다 더 많은 메모리 공간이 낭비될 수 있다. 연관된 이벤트가 서로 다른 CPU에서 빠르게 발생하는 경우 이벤트가 순서대로 전달되지 않을 수 있다. 이 때문에 이벤트를 옳은 순서로