긴급 상황에서만 스왑 공간을 사용하려면 어떻게합니까?


41

8GB RAM과 16GB 스왑 이있는 데비안 (버스터) 랩톱이 있습니다. 나는 매우 오래 실행되는 작업을 실행하고 있습니다. 이것은 지난 6 일 동안 노트북이 계속 켜져있는 상태임을 나타냅니다.

이 작업을 수행하는 동안 정기적으로 랩톱으로 랩톱을 사용해야합니다. 이것은 문제가되지 않습니다. 오래 실행되는 작업은 I / O 바운드이며 USB 하드 디스크의 작업을 수행하며 많은 RAM (<200MB) 또는 CPU (<4 %)를 사용하지 않습니다.

문제는 몇 시간 후에 랩톱으로 돌아올 때 매우 느리며 정상으로 돌아 오는 데 30 분이 걸릴 수 있다는 것입니다. 이는 크래시 모니터가 해당 응용 프로그램을 정지 (특히 브라우저 창) 한 것으로 플래그를 지정하고 문제가 발생하기 시작합니다.

절반 정도 사용 된 2.5GB 중 시스템 모니터를 보면 스왑으로 전환됩니다. 스왑 공간 ( swapoff /dev/sda8) 을 제거하여 이것이 문제임을 확인했습니다 . 스왑 공간을 남기지 않으면 24 시간이 지나도 거의 즉각적으로 다시 살아납니다. 스왑을 사용하면 처음 5 분 동안 만 6 시간 동안 방치 된 벽돌입니다. 부재중에도 메모리 사용량이 3GB를 초과하지 않는 것을 확인했습니다 .

나는 swappiness ( 또한 Wikipedia 참조 )를 10and의 값으로 줄이려고 시도했지만 0여전히 문제가 지속됩니다. 하루 동안 활동이 없으면 커널은 전체 GUI가 더 이상 필요하지 않다고 생각하고이를 RAM에서 제거합니다 (디스크로 교체). 장기 실행 작업은 방대한 파일 트리를 읽고 모든 파일을 읽습니다. 캐싱이 도움이된다는 생각으로 커널이 혼동 될 수 있습니다. 그러나 파일 이름이 ~ 10 억 개인 2TB USB HD를 한 번 훑어 보면 GB RAM이 추가로 성능에 큰 도움이되지 않습니다. 하드 드라이브가 느린 저렴한 노트북입니다. 단순히 RAM에 데이터를 충분히 빨리 다시로드 할 수 없습니다.

비상시 스왑 공간 만 사용하도록 Linux에 지시하려면 어떻게해야합니까? 스왑없이 달리고 싶지 않습니다. 예기치 않은 일이 발생하고 OS에 갑자기 몇 GB가 더 필요한 경우 작업이 종료되는 것을 원하지 않으므로 스왑 사용을 선호합니다. 그러나 현재 스왑을 활성화하면 랩톱을 필요할 때 사용할 수 없습니다.

"비상"에 대한 정확한 정의는 토론의 문제 일 수 있습니다. 그러나 의미하는 바를 명확히하기 위해 : 프로세스가 스왑 또는 종료하는 것 이외의 다른 옵션없이 시스템이 남아있는 비상 사태가 발생할 수 있습니다.


응급 상황이란 무엇입니까? - 정말로 물어봐야합니까? .. 당신은 절대 불타는 건물에서 자신을 찾지 않기를 바랍니다!

이 질문에서 비상 사태를 구성 할 수있는 모든 것을 정의 할 수는 없습니다. 그러나 예를 들어, 커널이 메모리에 너무 밀려 OOM Killer로 프로세스 종료를 시작했을 때 긴급 상황이 발생할 수 있습니다 . 커널이 스왑을 사용하여 성능을 향상시킬 수 있다고 생각할 때 비상 사태는 아닙니다.


최종 편집 : 운영 체제 수준에서 요청한 내용을 정확하게 수행하는 답변을 수락했습니다. 미래 독자들은 또한 응용 프로그램 수준 솔루션을 제공하는 답변에 유의해야합니다.


11
"비상"을 정의하고 이것이 스왑이 사용될 때의 일반적인 상황과 어떻게 다른지에 대해 말하십시오.
Kusalananda

4
커널이 스왑을 사용할 수있게하는 특별한 범위를 벗어난 "비상 이벤트"를 어떻게 정의하고 싶은지 알고 싶지만 스왑은 사용되지 않습니다. AFAIK 메모리 페이징은 어쨌든 느리고 "긴급 상황"에서만 수행되는 작업이며 "스왑"은이 동작을 조정할 수있는 유일한 방법입니다 (하지만 Linux 사용자는 아닙니다).
Kusalananda

2
아니 맞습니다. 응급 상황에서만 수행되는 것이 아닙니다. 적어도 나는 내 질문에 8GB 중 3GB 만 사용했다는 것을 알았다고 생각했다. 그것은 비상 사태는 아니지만 커널은 어쨌든 바뀌고있다. 나는 당신이 교환과 주변 주제에 대해 읽을 것을 제안합니다. 스와핑의 여러 가지 이유에 대해 꽤 많은 논의가 있습니다. 커널에 존재하지 않는 개념을 요구하는 것은 그럴듯하지만, 그것을 요구하는 이유는 상당히 정당화됩니다.
Philip Couling

4
조언은 항상 "스왑없이 실행되지 않았다"는 것을 알고 있습니다. 그러나 메모리 크기가 확장 된 하드 드라이브 (SSD가 아닌 HDD) 읽기 / 쓰기 속도를 넘어서면서 스왑이 점점 더 나쁘게 생각되고 있습니다. 일부 사람들은 8GB RAM + 8GB 스왑이 16GB RAM + 0 스왑을 수행한다고 생각합니다. 그것이 실제로라면 Linux 커널에 뭔가 잘못되었습니다.
Philip Couling

7
@Philip Couling : 아니요, 요점은 16GB RAM + 16GB 스왑이 16GB 및 0 스왑을 능가한다는 것입니다. 특히 코드에 17GB의 메모리가 필요한 경우 :-)
jamesqf

답변:


11

요즘 그런 스왑을 갖는 것은 종종 나쁜 생각입니다. OS가 스왑하기 위해 몇 GB의 메모리를 스왑 할 때까지 시스템은 이미 본 것처럼 크롤링되었습니다.

작은 백업 스왑 파티션과 함께 사용 zram하는 것이 좋습니다 . ChromeOS, Android 및 다양한 Linux 배포판과 같은 많은 OS는 기본적으로 zram을 몇 년 동안, 특히 RAM이 적은 시스템에서 기본적으로 활성화했습니다. HDD 스왑보다 훨씬 빠르며이 경우 시스템 응답 성을 명확하게 느낄 수 있습니다. SSD에서는 그렇지 않지만 여기서 벤치 마크 결과 에 따르면 기본 lzo 알고리즘을 사용하더라도 여전히 더 빠른 것처럼 보입니다. 압축률이 약간 더 낮 으면서 성능을 향상시키기 위해 lz4 로 변경할 수 있습니다 . 공식 벤치 마크를 기준으로 디코딩 속도가 lzo보다 거의 5 배 빠릅니다.

도 있는데 zswap내가 그것을 사용한 적이 있지만. 시도해 볼만한 가치가 있으며 사용 사례에 더 적합한 것을 비교하십시오.

그 후 다른 제안은 IO 바인딩 프로세스의 우선 순위줄이고 시스템이 높은 부하 상태 일 때도 즉시 명령을 실행할 수 있도록 우선 순위가 높은 터미널을 실행하는 것입니다

추가 자료


내가 이해할 수 있도록, zram블록 장치를 만들고 스왑으로 사용하고 우선 순위가 낮은 스왑을 HDD 파티션으로 사용할 수 있다고 말하고 있습니까?
Philip Couling

@PhilipCouling HDD를 사용한다면 zram 또는 이와 유사한 솔루션을 사용해야합니다. 스왑의 우선 순위는 zram보다 낮아야하므로 Linux에서 zram을 먼저 사용하려고 시도한 다음 스왑을 고려합니다. Ubuntu를 사용하는 경우 zram-config 패키지는 이미 우선 순위 설정을 처리합니다.
phuclv

3
이 답변은 내가 요청한 것과 정확히 일치하기 때문에이 답변을 수락합니다. 16GB 스왑을 여전히 낮은 우선 순위로 활성화 한 경우 커널은 zswap이 소진 된 경우에만이를 사용합니다. IE : "긴급 상황". debian-buster에 대한 참고 사항은 zram-tools를 설치하기 만하면 설치가 매우 쉽습니다.
Philip Couling

25

한 가지 수정 사항은 메모리 cgroup 컨트롤러가 활성화되어 있는지 확인하는 것입니다 (기본적으로 절반 정도의 커널에서도 가능하다고 생각합니다. 그렇지 않으면 cgroup_enable=memory커널 명령 줄 에 추가해야합니다 ). 그런 다음 메모리 제한이있는 cgroup에서 I / O 집약적 작업을 실행할 수 있으며, 이로 인해 소비 할 수있는 캐시의 양도 제한됩니다.

당신이 systemd를 사용하는 경우, 당신은 설정할 수 있습니다 +MemoryAccounting=yes및 중 MemoryHigh/ MemoryMax또는 MemoryLimit단위로, 또는 슬라이스를 포함하는 (당신이 cgroup에의 V1 또는 V2를 사용하는 경우에 depeneds을). 슬라이스 인 경우 슬라이스 systemd-run에서 프로그램을 실행하는 데 사용할 수 있습니다 .

메모리 제한으로 Firefox를 실행하는 시스템 중 하나의 전체 예. 이것은 cgroups v2를 사용하며 루트가 아닌 내 사용자로 설정됩니다 (v1보다 v2의 장점 중 하나는 루트가 아닌 것으로 위임하는 것이 안전하므로 systemd가 수행한다는 것입니다).

$ systemctl --user cat mozilla.slice 
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target

[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G

$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &

나는 사용자가 슬라이스를 사용해야하는 작업을하는 것을 발견했습니다. 시스템 1은 옵션을 서비스 파일에 넣거나 systemctl set-property서비스를 사용 하여 작동합니다.

다음은 cgroup v1을 사용하는 서비스 예입니다. 마지막 두 줄에 유의하십시오. 이것은 시스템 (pid = 1) 인스턴스의 일부입니다.

[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql  --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo  --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G

설명서는에 systemd.resource-control(5)있습니다.


1
당신은 단지 사용하여 비교 및 ​​휴대용 무언가를 할 수 없습니까 ulimit?
Old Pro

1
@OldPro는 실제로는 아닙니다. 첫째, 페이지 캐시 (여기서 과도하게 사용되는 사용량)를 포함하여 총 메모리 사용량에 대한 AFAIK에는 제한이 없습니다. 둘째, 메모리에 대한 ulimit는 프로세스마다 다르며 cgroup은 장시간 실행되는 작업을 수행하더라도 작동합니다.
derobert

최신 시스템에서 메모리 계정이 기본적으로 활성화되는 이유는 systemd버전 238 의 변경 때문이라고 생각했습니다 .
sourcejedi

1
@sourcejedi는 비교적 최근입니다. 메모리 컨트롤러가 처음 도입되었을 때, 사용 가능하지 않은 경우에도 일부 배포판은 기본적으로 최소한 디스토로 디스 에이블 할 수있는 충분한 성능 비용이 들었으며,이를 위해서는 커널 명령 줄 인수를 전달해야했습니다. 성능 문제가 수정되어 변경되었으며보다 최근에는 시스템화되어 기본적으로 활성화됩니다.
derobert

14

하루 동안 활동이 없으면 커널은 전체 GUI가 더 이상 필요하지 않다고 생각하고이를 RAM에서 제거합니다 (디스크로 교체).

커널은 The Right Thing ™을 믿고 있습니다. 왜 사용되지 않는 메모리 1 개 를 RAM에 유지 하여 캐시 나 다른 것으로 사용하는 대신 본질적으로 낭비합니까?

나는 리눅스 커널이 페이지를 스왑 아웃한다고 생각하지 않는다고 생각합니다. 그렇다면 RAM에 다른 것을 저장하여 장기 실행 작업의 성능을 높이거나 적어도이 목표를 달성해야합니다.

랩톱을 미리 재사용해야하는시기를 알고 있다면 at명령 (또는 crontab)을 사용하여 스왑 정리 ( swapoff -a;swapon -a) 를 예약 할 수 있습니다 .

스왑 청소로 잔인한, 심지어 OOM 킬러를 실행할 수있는 경우 RAM에 어떤 이유로, 모든 것이 적합를 들어, 수도 그냥 "unswap" 당신이 부활 할 실행중인 응용 프로그램과 관련된 모든 것을.

이를 수행하는 한 가지 방법 gdb은 영향을받는 각 프로세스와 같은 디버거를 연결 하고 코어 덤프 생성을 트리거하는 것입니다.

# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit

작성한 것처럼 장기 실행 응용 프로그램은 초기 단계 후에 읽은 데이터를 재사용하지 않으므로 장기 캐싱이 유용하지 않은 특정 경우에 있습니다. 그런 다음 Will Crawford가 제안한 것과 같은 직접 I / O를 사용하여 캐시를 무시하는 것이 좋습니다.

또는, 당신은 정기적으로 반향하여 파일 캐시를 플러시 수 1또는 3받는 /proc/sys/vm/drop_cachesOS가 그것이 당신의 GUI 응용 프로그램 및 환경을 바꿀 수있는 좋은 아이디어라고 생각하기 전에 의사 파일.

Linux 시스템에서 버퍼를 비우고 캐시하는 방법을 참조하십시오 . 자세한 내용은.

1 의미에서 사용되지 않음 : 상당한 기간 동안 더 이상 적극적으로 사용되지 않고 메모리는 여전히 소유자와 관련이 있습니다.
2 스왑 영역에 저장된 RAM 페이지를 다시 넣습니다.


2
가능한 원인에 대한 생각에 감사드립니다. 관련성이 있기 때문에 질문에 조금 추가했습니다. 응용 프로그램 자체 메모리에 대한 캐싱 우선 순위를 낮추는 방법이 있는지 궁금합니다.
Philip Couling

5
"리눅스 커널이 페이지를 무용지물로 스왑 아웃한다고 생각하지는 않는다. 그렇게한다면 RAM에 다른 것을 저장하여 성능을 향상시켜야한다." – 나는이 표현이 약간 모호하다고 생각합니다. 커널은 기회가있을 때마다 (예 : 디스크 I / O가 거의 없음) 스왑 할 페이지를 확실히 작성합니다. 그러나 RAM에서 제거하지는 않습니다. 이렇게하면 두 가지 이점을 모두 얻을 수 있습니다. 해당 페이지를 빠르게 다시 필요로하면 이미 RAM에 있고 수행 할 작업이 없습니다. 비상 사태가 (영업이 그것을 넣어)이 발생하는 경우, 당신은 단순히, RAM에서 해당 페이지를 무료 때문에 필요
요 르그 W MITTAG

3
… 그들은 이미 교환 중입니다. 그리고 이것이 바로 긴급 상황에서만 스왑을 사용하고 싶지 않은 이유 입니다. 긴급 상황에서는 시스템이 이미 스트레스를 받고 있고 마지막으로 원하는 것은 대량의 디스크 I / O를 추가하기 때문입니다.
Jörg W Mittag

2
스왑 아웃을 일으키는 것은 아마도 오래 실행되는 프로세스 일 것입니다 : 디스크의 파일에 액세스하고 있습니다. 메모리에있는 파일은 GUI의 메모리보다 최근에 사용되었습니다.
jpmc26

3
@ JörgWMittag I / O 사용량이 적을 때 스왑 영역에 페이지를 "있는 경우"(예 : RAM에서 비우지 않음)에 선제 적으로 쓰는 Linux 커널의 증거가 있습니까?
jlliagre

10

실행중인 프로세스가 직접 생성 한 프로세스입니까?

그렇다면, 그것은 사용하여 파일을 열려면 코드를 조정 가치가있을 수도 있습니다 O_DIRECT인용하는 플래그, 매뉴얼 페이지를 -

이 파일에 대한 I / O의 캐시 효과를 최소화하십시오. 일반적으로 이는 성능을 저하 시키지만 응용 프로그램이 자체 캐싱을 수행하는 경우와 같은 특수 상황에서 유용합니다. 파일 I / O는 사용자 공간 버퍼로 /로부터 직접 수행됩니다. O_DIRECT 플래그는 자체적으로 데이터를 동 기적으로 전송하려고하지만 데이터 및 필요한 메타 데이터가 전송된다는 O_SYNC 플래그를 보장하지는 않습니다. 동기 I / O를 보장하려면 O_DIRECT 외에 O_SYNC를 사용해야합니다. 자세한 내용은 아래 참고를 참조하십시오.


1
또 다른 비슷한 (하지만 아마도 O_DIRECT에는 정렬 제한이 있고 읽기가 크지 않으면 성능이 저하 될 것이라고 확신하기 때문에 더 쉬울 것입니다) 커널에 해당 데이터를 다시 필요로하지 않도록 커널에 알리십시오. 페이지 캐시. (전화 또는 링크 제공, 죄송합니다)
derobert

1
@derobert 하나는이 nocache명령 이 편리한 해킹입니다. (LD_PRELOAD를 사용하여 일부 libc 호출을 도용합니다).
sourcejedi

6

여기에 내가 시도하지 않은 아이디어가 있습니다 (지금 실험 해 보지 못한 것이 유감입니다).

백그라운드 프로세스를 위해 512MB의 메모리로 작은 VM을 생성한다고 가정하면 호스트 시스템에서 스왑, 호출 및 스왑을 수행할지 여부는 확실하지 않습니다.


3

최근 OS에서 몇 년 전과 같은 방식으로 스왑을 더 이상 사용하지 않으므로 스왑을 제거하거나 약 20 % ( 시스템에 따라 다를 수 있음 )를 줄입니다. 아마도 귀하의 질문에 대한 답변이 될 것입니다.

-> 공식 redhat.com

아래의 Red Hat 정보 중 일부

과거에는 일부 응용 프로그램 공급 업체에서 RAM과 동일한 크기 또는 RAM의 두 배로 교체 할 것을 권장했습니다. 이제 2GB의 RAM과 2GB의 스왑이있는 위에서 언급 한 시스템을 상상해 봅시다. 시스템의 데이터베이스가 실수로 5GB의 RAM이있는 시스템으로 구성되었습니다. 실제 메모리가 사용되면 스왑이 사용됩니다. 스왑 디스크가 RAM보다 훨씬 느리기 때문에 성능이 저하되고 스 래싱이 발생합니다. 이 시점에서 시스템에 로그인조차 불가능할 수 있습니다. 점점 더 많은 메모리가 기록됨에 따라 결국 물리적 메모리와 스왑 메모리가 완전히 소진되고 OOM 킬러가 시작되어 하나 이상의 프로세스가 종료됩니다. 이 경우 상당히 많은 스왑을 사용할 수 있으므로 성능이 저하되는 시간이 길다.

https://wiki.debian.org/Swap

위의 데비안 링크 부분

사용할 스왑 양과 관련된 정보 및 고려 사항 :

"권장 된 스왑 공간의 양은 전통적으로 시스템 메모리 양의 두 배였습니다. 이것은 시간이 지남에 따라 시스템 메모리의 1.5 배로 변경되었습니다. 두 답변 모두 괜찮은 기준선이지만 시간이 지남에 따라 질문에 대한 유용한 답변은 점점 줄어들고 있습니다. 시스템과 사용하려는 시스템 스왑을 결정하는 용도에 대한 많은 변수가 있습니다. "

시도해 볼 수 있습니다 :

"리눅스에서 스왑을 비활성화하는 가장 좋은 방법"


개인 메모 :


RAM이 6GB이고 최근의 모든 Linux OS에 있습니다. 스왑 사용에 대한 징후는 본 적이 없습니다. 나는 공간 (몇 기가 바이트 이상)과 시스템을 때때로 느리게하기 위해 꺼야 한다고 결정했습니다 .


1
과거에는 일부 응용 프로그램 공급 업체에서 RAM과 동일한 크기 또는 RAM의 두 배로 교체 할 것을 권장했습니다. 어쨌든 나는 ~ 528MB의 장벽에 HDD 중 하나와 2.5GB를 가지고 있지만 어떻게 든 그 인용문을 가지고 있지만 훨씬 오래 전에 느낍니다. 몇 년 전에 비슷한 문제가 발생한 이유를 설명 할 수 있습니다. 나는 그것을 고치기 위해 sysctl을 사용했다고 생각하지만 그 전날이라면 정확히 어떤 설정인지 기억하지 못한다.
Pryftan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.