방금 여러 업그레이드를 마쳤고, 메모리 오류를 해결하는 가장 쉬운 방법은 스왑을 4GB로 두 배로 늘리는 것이라고 판단했습니다. 단점으로는 1GB 드롭렛에는 SSD 용량이 25GB밖에 되지 않아, 그중 4GB를 스왑으로 사용하게 되면 상당한 공간 손실이 발생한다는 점입니다. 25GB인 현재 용량도 이미 다소 빠듯한 상태입니다.
그래서 discourse-setup의 기본값을 3GB로 변경해야 할까요?
@Falco 님, 어떻게 생각하시나요?
방금 여러 업그레이드를 마쳤고, 메모리 오류를 해결하는 가장 쉬운 방법은 스왑을 4GB로 두 배로 늘리는 것이라고 판단했습니다. 단점으로는 1GB 드롭렛에는 SSD 용량이 25GB밖에 되지 않아, 그중 4GB를 스왑으로 사용하게 되면 상당한 공간 손실이 발생한다는 점입니다. 25GB인 현재 용량도 이미 다소 빠듯한 상태입니다.
그래서 discourse-setup의 기본값을 3GB로 변경해야 할까요?
@Falco 님, 어떻게 생각하시나요?
그렇게 하면 문제가 해결된다면, 난 전적으로 찬성이야.
설치 스크립트에서 메모리 처리에 영향을 미치는 두 가지 커널 튜너블도 설정하도록 강력히 제안합니다. 문제가 있는 것으로 보이는 모든 사용자에게 적어도 좋은 커널 설정의 시작점이 제공되는 것이 좋습니다.
이것은 나에게 합리적인 아이디어로 보인다. 전용 디스코urs 인스턴스에서 THP가 어디에 가치가 있을지 상상할 수 없고, 오버커밋은 OOM을 방지하는 데 도움이 될 수 있다.
각 항목을 별도로 제공하면서 기본 응답으로 설정하고, 비기본 옵션으로 옵트아웃할 수 있게 하는 것을 고려해 볼 수 있다.
또한, 스크립트는 변경을 수행하기 전에 sysctl을 사용하여 설정이 실제로 변경이 필요한지 확인할 수 있다. 누군가 이미 다른 파일로 이러한 변경을 했다면, 중복된 오버라이드를 생성하는 것은 혼란을 줄 수 있다. 모든 Linux 배포판이 기본적으로 메모리 오버커밋을 꺼져 있는 상태로 제공되는 것은 아니라고 생각한다.
if $(sysctl -n vm.overcommit_memory) != 1 ; then
....
fi
커널 튜닝에 관한 중요한 메시지를 흐리게 할 위험이 있지만, 두 번째 고려 사항이 있습니다. 현재 스크립트는 저용량 RAM 머신에서만 스왑을 생성합니다. 저의 생각으로는 이는 실수입니다. 스왑은 RAM의 유용성을 극대화하는 데 여전히 유용할 뿐만 아니라, 더 중요한 이유는 속도나 편의성을 위해 대용량 RAM 머신에 Discourse를 설치했다가 나중에 저용량 RAM으로 다운사이징할 경우 문제가 발생하기 때문입니다.
설정은 모든 경우에 스왑을 생성해야 합니다(이미 충분한 스왑이 있는 경우를 제외하고). 여러 스왑 파일을 사용하는 것은 유효하며 때로는 유용합니다.
결정권은 저에게 있지 않고, 저는 직접 세팅하는 머신들에서는 이 값들을 설정하고 있습니다. 하지만 이것은 (대부분의) Discourse 설치자가 실행하는 셸 스크립트입니다. 가능한 한 단순해야 하며, Raspberry Pi나 Mac, 그리고 사람들이 시도하는 그 외의 어떤 환경에서도 해당 설정이 제대로 작동하는지, 그리고 이미 설정되어 있는지 확인하는 방법이 모든 플랫폼에서 동작하는지 확신할 수 있을까요? 쉽지 않아 보입니다.
discourse-setup을 작성한 사람으로서, 여기에 변경 사항을 추가하는 것은 다소 무섭습니다.
항상 스왑 생성을 제안하는 것은 나쁜 아이디어가 아닙니다. 아마도 항상 3GB 또는 4GB의 스왑 설정을 제안하는 것은 어떨까요? 하지만 그 경우 그 양은 얼마로 해야 할까요? 한때 알고 있던 경험칙은 스왑 크기를 RAM 크기와 동일하게 하는 것이었습니다. 그리고 현재로서는 스왑을 생성하지 않으면 Ctrl+C를 눌러 종료하는 것만이 유일한 선택지입니다. 즉, 사용자에게 스왑 생성을 강요하거나, 새로운 Y/N 질문을 추가해야 합니다(이 경우 discourse-setup을 실행하는 제 스크립트를 수정해야 하므로
). 아! 아니면 --skip-swap 스위치로 제어하는 방법도 있습니다. 이 방법은 괜찮아 보입니다. 스왑에 대해 충분히 아는 사용자라면 건너뛰기 스위치를 찾을 수 있을 테니까요. 해당 경고(WARNING) 메시지에 스위치에 대한 주석을 추가할 수 있습니다.
그리고 연결 테스트가 실패할 때 --skip-connection-test에 대한 주석도 추가하면 좋겠습니다.
이미 스왑이 설정되어 있다면, 사용자가 자신이 무엇을 하는지 알고 있다고 가정해도 안전할 것 같습니다.
감사합니다! 네, 충분히 이해하고 있습니다. 저라면 같은 기분이 들었을 것입니다. 확실히 신중한 검토와 테스트가 필요합니다. 그리고 이는 최소한 몇몇 호스팅 제공업체의 저렴한 머신과 Pi에서도 실행되어야 합니다. Windows나 Mac에 대해서는 확실하지 않습니다 - 지원이 예상된다면, 당연히 그렇겠죠. 하지만 더 가능성 높은 시나리오는 개발 머신으로 사용될 것이라는 점이며, 이는 또 다른 문제입니다.
그렇습니다. 현재 필요한 것으로 보이는 만큼 설정하는 것이 좋겠습니다. 상황이 한 단계 더 진전된 것 같습니다. 하지만 이러한 보고들이 커널의 오버커밋(overcommit) 설정 조정을 포함하고 있는지 아닌지 알 수 없다는 점이 매우 안타깝습니다. 이전 논의들을 통해 오버커밋 설정이 차이를 만든다는 것을 확실히 알고 있습니다.
또한 25GB 인스턴스, 특히 20GB 인스턴스에서는 디스크 공간이 빠듯하다는 것도 알고 있습니다. 저는 그런 머신에서 운영 중입니다: 25GB 디스크와 1GB RAM(이미 2GB 스왑이 필요하고 요즘은 더 필요할 수도 있음) 환경, 그리고 20GB 디스크와 2GB RAM(현재 1GB 스왑 사용 중) 환경입니다.
더 많은 Y/N(예/아니오) 질문을 권장하지는 않습니다. 커맨드 라인 옵션이 더 나은 방법이라고 생각합니다.
이 스크립트를 변경할 계획이라면, 저는 여러 개의 1GB 스왑파일을 만드는 것을 권장합니다. 이는 유연성을 극대화하고, 낭비를 없애며, 그 결정을 내리기 가장 쉬운 시점이기 때문입니다.
이 부분에는 동의하지 않습니다. 가장 작은 인스턴스에 네이티브 Ubuntu나 Debian이 설치되어 있고 이미 일부 스왑이 설정되어 있다면(이것은 확인이 필요합니다) - 스왑이 부족할 경우 문제가 시작됩니다. free 명령을 사용하여 RAM+스왑을 측정하고, 1GB 미만 구성(AWS인 것 같고, 아마도 Oracle도 포함)에 맞게 통상적으로 조정하고, 그 다음 현재 합의된 수량까지 1GB 스왑파일을 추가하는 것이 훨씬 낫습니다. 커널 오버커밋이 적절히 설정된다면 총 4GB가 충분할 것입니다.
도움을 드릴 수 있습니다.
흠. 그래요. 방금 조정했던 것들에 대해 그 부분을 확인해 보았어야 했는데 아쉬워요.
흠. 제 생각에는 하나인 것이 더 낫지만, 여러 개로 하면 유연성이 더해지고, 더 많은 스왑이 필요할 경우 discourse-setup을 실행하여 추가 스왑파일을 만들 수 있도록 할 수 있습니다. 그러면 모든 사용자에게 스왑 문제를 "수정"하기 위해 discourse-setup을 실행하라고 안내할 수 있겠죠. 그리고 아마 오버커밋 문제도 함께 처리할 수 있을 것 같습니다–우리가 신경 쓰는 것이 리눅스뿐이므로, 리눅스에 대해서만 명시적으로 그렇게 시도해 보는 것도 좋겠네요.
동의하지 않습니다. 스왑은 보편적인 장점이 아닙니다. 과거에는 특정 상황에서 스왑이 이루어지지 않더라도 VM 코드를 더 고르게 만들기 위해 중요했지만, VM 알고리즘이 변경되었습니다.
그것은 더 이상 적용되지 않는 매우 오래된 커널 코드 휴리스틱에 기반한 것이었습니다.
또한, 측정을 고려할 때: zswap이 사용 중인 경우 스왑과 메모리를 측정하기 위해 무엇을 해야 할지조차 모릅니다. 하지만 이것은 아마도 "우선 해를 끼치지 말라"는 원칙이 적용되는 경우일 것입니다.
"스왑이 너무 많다"는 것의 유일한 단점이 반드시 필요한 것보다 더 많은 디스크 공간을 사용하는 것뿐이라는 데에는 상당히 확신이 있습니다. 이는 여러 개의 적당히 크기를 맞춘 스왑 파일을 두는 것이 더 바람직한 이유이기도 합니다. 디스크 공간을 확보해야 할 필요가 생기면, 스왑을 해제하고 점진적으로 파일을 제거할 수 있기 때문입니다. 또한, 리눅스가 이 스왑 파일들을 점진적으로 사용하는 데 꽤 잘 작동한다고 생각합니다:
NAME TYPE SIZE USED PRIO
/var/local/swap/swapfile.1 file 1024M 863.6M -2
/var/local/swap/swapfile.0 file 1024M 4.6M -3
우리가 처한 상황은 저렴한 인스턴스가 RAM과 디스크 공간 모두에서 상당히 제한적이라는 점이며, Discourse는 내부의 수많은 패키지가 발전함에 따라 점점 더 많은 자원을 사용하게 됩니다. 하지만 여전히, 월 요금을 두 배나 네 배로 올리는 것 외에는 다른 선택지가 없는 사람들을 위해 이 문제를 현명하게 해결할 수 있는 방법들이 있다고 생각합니다.
스와핑 속도는 충분히 느리기 때문에, "지금 막 방이 부족하다"는 이유로 현재 기본 권장치에 1GB 이상을 추가하는 것은 적절하지 않다고 생각합니다. 전용 Discourse 인스턴스에서 경험해 본 바와 같이, 1GB는 상당한 양의 스왑 공간입니다.
네, 기본적으로 Linux는 우선순위 순서대로 스왑을 사용하며, 여러 디바이스에 동일한 우선순위를 부여하여 스왑을 명시적으로 스트라이핑하는 것도 가능합니다. 하지만 작은 사이트의 경우 대량의 스왑을 추가하는 것은 특히 가치 있다고 보지 않습니다.
따라서 대략 10년 동안 사람들이 2GB를 간신히 넘어서는 경우가 드물다면, 기본값을 4GB가 아닌 3GB로 변경하는 것을 제안합니다. 그리고 전용 Discourse 인스턴스에 필요한 스왑 양은 메모리 크기에 따라 특별히 증가하지 않아야 합니다. 실제로 스왑 아웃될 콘텐츠가 크게 변하지 않기 때문입니다.
메모리가 증가할수록 스왑도 증가해야 한다는 아이디어는 주로 범용 컴퓨팅에서 기인하며, RAM이 많이 필요할수록 수요가 더 클 것이라는 일반화된 가정에 기반합니다. 하지만 전문화된 Discourse 인스턴스의 스왑 압력은 그런 패턴을 따르지 않을 것이라고 생각합니다.
THP(투명 거대 페이지)는 거대 페이지를 지원하는 플랫폼에 고유한 것으로, 모든 플랫폼이 지원하는 것은 아닙니다. 이를 처리하는 일반적인 방법은 존재하는지 확인하는 것입니다. 제가 가진 Raspberry Pi 중 하나에서는 다음과 같습니다:
$ sysctl sys.kernel.mm.transparent_hugepage.enabled
sysctl: cannot stat /proc/sys/sys/kernel/mm/transparent_hugepage/enabled: No such file or directory
$ echo $?
255
반면에 오버커밋(overcommit)은 지난 몇십 년간 Linux의 일반적인 VM 파라미터였습니다. 같은 Raspberry Pi에서는 다음과 같습니다:
$ sysctl vm.overcommit_memory
vm.overcommit_memory = 0
셸에서 free 명령의 출력을 파싱하는 것은 다소 번거롭습니다. procps의 원작자로서, 이 경우에는 /proc/meminfo에서 SwapFree를 찾는 것을 추천합니다. ![]()
비용이 제한적인 환경에서 RAM 크기에 따라 스왑을 확장하는 것이 더 이상 좋은 방안이 아니라는 데에 동의합니다. 역사적으로 그 다음 아이디어는 RAM이 매우 커서 스왑이 필요하지 않다는 것이었습니다. 그 후에는 RAM을 더 효율적으로 사용할 수 있기 때문에 일부 스왑은 유용하다는 지혜가 따라왔습니다. (제한이 없는 환경에서는 단순히 방대한 양의 RAM을 갖추면 되지만, 이는 특수한 경우입니다.)
지난 몇 달간 우리는 메모리 부족 문제와 재구축 실패를 겪는 사람이 더 많아지는 것을 보고 있습니다. 웹 업그레이드는 실패하지만 명령줄은 작동한다는 문제를 발견하는 사람도 더 늘고 있습니다. 단순한 지원 관점에서도, 제품의 평판 측면에서도, 우리는 일반적인 조언과 기본 설정에 변화를 줄 필요가 있다고 생각합니다. 3GB의 스왑은 가장 간단하고 최소한의 변경 사항이며, 다른 조치를 취하지 않더라도 이 정도는 해야 한다고 생각합니다.
하지만 여전히 여러 개의 작은 스왑 파일이 더 현명한 선택이라고 생각합니다. 여기서는 이를 뒷받침하는 지원 스레드도 확인할 수 있습니다. 또한 여전히 RAM+스왑 크기를 기준으로 설정하는 것이 가장 좋다고 생각합니다. 왜냐하면 이것이 제한 요인이자 사람들이 문제를 겪게 만드는 원인인 것이기 때문입니다. 이 계산을 수행하는 방식이 다를 수도 있습니다. 어떤 전술이 유지보수 가능하고, 이해하기 쉬우며, 장기적으로 유효한지에 대한 일반적인 주의사항은 여전히 적용됩니다.
투명 거대 페이지(transparent huge pages)에 대해서는, 제 이해로는 "투명(transparent)"이라는 부분이 문제를 일으킨다고 봅니다. 커널이 병합과 역병합을 반복하며 스래싱(thrashing)을 일으켜 성능 저하를 유발하지만 큰 이점은 없기 때문입니다. 작은 시스템에서는 거대 페이지(hugepages)를 사용하는 것이 부적절하다고 확신합니다.
이는 시스템의 크기보다는 워크로드의 특성에 더 관련이 있습니다. RAM이 1GB인 시스템에서 RAM을 대량으로 사용하는 비교적 안정적인 프로세스가 실행되는 경우, 기본 2MB hugepages는 TLB 스래싱을 줄이고 성능을 향상시킬 수 있습니다. TLB는 1GB RAM의 매핑을 모두 커버할 수 없기 때문입니다. 이는 일반적으로 메모리를 병합(coalesce)하기 위해 CPU를 소비하는 것과 TLB 캐시 미스 사이의 트레이드오프이며, 1GB 메모리를 가진 머신에서도 THP(Transparent Huge Pages)에서 상당한 이점을 얻을 수 있는 워크로드가 많습니다. (THP를 비활성화하라는 많은 권장 사항은 구현 초기에 나온 것으로, 이후 크게 개선되었습니다.) Discourse에 대해 THP를 비활성화하라는 권장 사항은 1GB RAM 크기 때문이 아니라, Discourse가 사용하는 온디스크(on-disk) 영속화를 사용하는 Redis에 특정된 것입니다:
안타깝게도 Linux 커널에서 투명 거대 페이지(transparent huge pages)가 활성화되어 있으면, 디스크에 영속화하기 위해
fork호출이 사용된 후 Redis는 큰 지연 시간 페널티를 겪습니다. 거대 페이지는 다음 문제의 원인입니다:
…