Linux에서 버퍼 캐시 크기 제한

Linux에서 버퍼 캐시 크기 제한

Linux 커널에 특정 비율의 메모리만 버퍼 캐시로 사용하도록 지시하는 방법이 있습니까? 일시적으로 캐시를 지우는 데 사용할 수 있다는 것을 알고 있지만 /proc/sys/vm/drop_caches캐시가 주 메모리의 50%를 초과하여 증가하는 것을 방지하는 영구적인 설정이 있습니까?

내가 이 작업을 수행하려는 이유는 지속적으로 디스크에서 데이터를 제공하고 몇 시간 내에 전체 물리적 메모리를 버퍼 캐시로 사용하는 Ceph OSD를 실행하는 서버가 있기 때문입니다. 동시에 대량(수십 GB)의 물리적 메모리를 할당하는 애플리케이션을 실행해야 합니다. 대중적인 믿음(버퍼 캐싱에 관한 거의 모든 질문에 제공된 조언 참조)과는 달리, 깨끗한 캐시 항목을 삭제하여 자동으로 메모리를 해제하는 것은아니요일시적: 버퍼 캐시가 가득 차면(*) 앱을 실행하는 데 최대 1분 정도 걸릴 수 있지만, 캐시를 지운 후에는( 를 사용하여 echo 3 > /proc/sys/vm/drop_caches) 동일한 앱이 거의 즉시 시작됩니다.

(*) 이름이 지정된 함수의 Vtune에 따르면 이 부팅 시간 동안 애플리케이션이 새 메모리에서 충돌을 일으키지만 해당 시간의 100%를 커널에서 소비합니다 pageblock_pfn_to_page. 이 기능은 거대한 페이지를 찾는 데 필요한 메모리 압축과 관련이 있는 것으로 보이며, 이로 인해 실제로 조각화가 문제라고 믿게 됩니다.

답변1

절대적인 제한이 필요하지 않지만 버퍼를 더 빠르게 플러시하도록 커널에 압력을 가하는 경우 다음을 살펴봐야 합니다.vm.vfs_cache_pressure

이 변수는 VFS 캐시(페이지 캐시 및 스왑과 비교) 캐시에 사용되는 메모리를 회수하는 커널의 경향을 제어합니다. 이 값을 늘리면 VFS 캐시 회수율이 높아집니다.

범위는 0~200입니다. 더 높은 압력을 얻으려면 200쪽으로 이동하십시오. 기본 설정은 100입니다. 이 slabtop명령을 사용하여 메모리 사용량을 분석 할 수도 있습니다 . 귀하의 경우에는 dentry그 금액이 *_inode_cache높아야 합니다.

절대 한도를 원하면 찾아봐야 합니다 cgroups. Ceph OSD 서버를 cgroup에 배치하고 memory.limit_in_bytescgroup의 매개변수를 설정하여 사용할 수 있는 최대 메모리를 제한합니다.

memory.memsw.limit_in_bytes결합된 메모리 및 스왑 사용량의 최대량을 설정합니다. 단위가 지정되지 않으면 값은 바이트로 해석됩니다. 그러나 더 큰 단위를 나타내는 데 접미사를 사용할 수 있습니다. k 또는 K는 킬로바이트, m 또는 M은 메가바이트, g 또는 G는 기가바이트입니다.

인용하다:

[1]-GlusterFS Linux 커널 튜닝

[2]-RHEL 6 리소스 관리 가이드

답변2

Ceph OSD가 별도의 프로세스인 경우 다음을 사용할 수 있습니다.cgroup프로세스에서 사용하는 리소스를 제어합니다.

group1이라는 cgroup을 생성하고 메모리 제한을 설정합니다(예: CPU와 같은 다른 제한을 지원하는 50GB도 예제에 언급되어 있음).

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

그런 다음 애플리케이션이 이미 실행 중이면 애플리케이션을 이 cgroup에 넣습니다.

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

또는 이 cgroup에서 애플리케이션을 실행합니다.

cgexec -g memory,cpu:group1 your_app_name

답변3

A%에 대해서는 잘 모르지만, x분 후에 삭제되도록 시간 제한을 설정할 수 있습니다.

먼저 터미널에서

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

현재 캐시를 지웁니다.

cron-job Alt-F2로 만들고 gksudo gedit /etc/crontab, 그런 다음 하단 근처에 이 줄을 추가합니다.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

**15분마다 청소하세요. 정말로 원한다면 첫 번째 매개변수를 *로 변경하거나 1분 또는 5분으로 설정할 수 있습니다./5 대신/15

사용 가능한 RAM을 확인하려면(캐시 제외):

free -m | sed -n -e '3p' | grep -Po "\d+$"                          

답변4

질문 끝에서 당신의 직감이 정확하다고 생각합니다. 나는 A. NUMA 인식 메모리 할당이 CPU 간 페이지를 마이그레이션하거나 B. 연속적이고 정렬된 영역을 찾으려고 시도하는 투명한 hugepage 조각 모음 코드일 가능성이 더 높다고 생각합니다.

Hugepages 및 Transparent hugepages는 특정 워크로드의 성능을 크게 향상시키는 것으로 알려져 있지만 많은 이점을 제공하지 못하고 CPU 시간을 많이 소비합니다.

실행 중인 커널, /proc/meminfo의 내용(또는 적어도 HugePages_* 값) 및 (가능한 경우) pageblock_pfn_to_page()를 참조하는 추가 vtune 프로파일러 호출 그래프를 아는 것이 도움이 될 것입니다.

또한 내 추측을 받아들이고 싶다면 대형 페이지 조각 모음을 비활성화해 보세요.

echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag

(어쩌면 커널에 따라 다를 수도 있습니다.)

echo 'never' > /sys/kernel/mm/redhat_transparent_hugepage/defrag

마지막으로 이 애플리케이션은 수십 기가바이트의 메모리를 사용합니다. 어떤 언어?

"메모리 페이지 오류"라는 용어를 사용하셨으니, 운영 설계와 가상 메모리에 대해서는 충분히 익숙하실 것 같습니다. 너무 심각하게 실패하여 많은 I/O를 읽지 못하는 상황/애플리케이션을 상상하기 어렵습니다. 거의 항상 제한하려는 버퍼 캐시에서 읽습니다.

(궁금하신 경우 MAP_ANONYMOUS 및 MAP_POPULATE와 같은 mmap(2) 플래그와 실제로 어떤 가상 페이지가 물리적 페이지를 매핑했는지 확인하는 데 사용할 수 있는 mincore(2)를 확인하세요.)

행운을 빌어요!

관련 정보