Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Sidekiq 클러스터 스크립트 소개

Honeybadge에서는 처리 파이프라인에서 Sidekiq에 크게 의존합니다. 우리가 하는 거의 모든 일은 어느 시점에서 대기열을 통해 실행됩니다. 결과적으로 Sidekiq을 잘 실행하고 있는지 확인하고 싶습니다. 최근 EC2로 이전하면서 안정적인 장기 서버 세트에서 작업을 실행하는 끊임없이 변화하는 인스턴스 세트로 변경했습니다. 이로 인해 부팅 시 Sidekiq를 시작하는 방법을 다시 살펴보게 되었습니다. 지금은 이전보다 훨씬 더 중요하기 때문입니다.

과거에 우리는 모든 작업자 프로세스를 실행하기 위해 신에 의존했습니다. 왜냐하면 우리는 신이 그들을 모니터링하고 너무 많은 메모리를 사용하게 된 프로세스를 종료하기를 원했기 때문입니다. 우리의 god 구성은 해당 작업자를 실행하기 위해 배포한 서버에 맞게 손으로 조정되었습니다. 불행히도 systemd를 사용하여 새 인스턴스에서 이전 god 구성을 부팅할 때 지정된 구성보다 더 많은 작업자가 실행되는 경우가 있음을 발견했습니다. 이는 인스턴스에 대한 메모리 압박으로 이어지며 이는 좋지 않은 소식이었습니다. 잠시 만지작거리다가 기능을 많이 사용하지 않는다는 것을 깨닫고 God을 사용하여 프로세스를 관리하는 것을 중단할 때라고 결정했습니다.

여러 Sidekiq 프로세스를 실행하기 위한 하나의 간단한 명령

내가 정말로 원했던 것은 코어당 하나의 Sidekiq 프로세스를 생성하고 너무 많은 메모리를 소비하는 프로세스를 다시 시작하는 시스템 서비스로 실행할 수 있는 스크립트였습니다. 스크립트는 다양한 크기의 EC2 인스턴스에서 작동할 수 있어야 했습니다. 코어 수와 RAM의 양이 워크로드에 가장 적합한 것을 확인하기 위해 다양한 인스턴스 크기를 시도했기 때문에 다를 수 있기 때문입니다. 정확히 그렇게 하는 스크립트를 찾을 수 없었기 때문에 다음과 같이 작성했습니다.

물론 그 스크립트에는 약간의 빌린 코드가 있습니다. :) process_count의 코드 메서드는 아마도 Stack Overflow(저는 유니콘 구성에서 몇 년 동안 사용해왔습니다)와 fork_child 메소드는 기본적으로 sidekiq입니다. sidekiq gem의 bin.

이 스크립트는 존재하는 CPU 코어 수를 기반으로 여러 하위 프로세스를 생성하며 각 하위 프로세스는 sidekiq를 실행한 것과 동일합니다. 직접 명령합니다. 결과적으로 이 스크립트에 전달하는 모든 명령줄 옵션은 Sidekiq CLI 코드로 전달(및 구문 분석)됩니다. 즉, sidekiq에 전달할 수 있는 모든 옵션을 이 스크립트에 전달할 수 있습니다. 직접 실행할 때 일부 옵션(예:pid 파일 옵션)은 사용하기에 적합하지 않습니다. 스레드는 또한 각 자식 프로세스의 메모리 사용량을 주기적으로 확인하기 위해 생성됩니다. 자식 프로세스가 사용량 임계값을 초과하면 해당 프로세스가 종료되고 이를 대체할 새 프로세스가 생성됩니다.

클러스터 작업

프로세스 수는 기본적으로 코어 수로 설정되지만(Sidekiq 프로세스를 실행하는 데 전용 인스턴스를 사용한다고 가정) 스크립트를 실행하기 전에 SK_PROCESS_COUNT 환경 변수를 설정하여 이를 재정의할 수 있습니다. 마찬가지로 메모리 임계값은 인스턴스의 총 RAM에 대한 백분율로 설정되지만(라인 58의 process_count 값에 1을 추가하여 일부 RAM을 남겨둠) SK_MEMORY_PCT_LIMIT 환경 변수를 사용하여 원하는 백분율을 설정할 수 있습니다. 이 두 변수를 사용하여 UI를 구동하는 Rails 앱을 실행하는 인스턴스에서 Sidekiq 프로세스 수와 메모리 사용량을 제한합니다.

추가 보너스로 이 스크립트는 일반적으로 Sidekiq 프로세스를 관리하는 데 사용되는 신호를 포착하고 해당 신호를 하위 프로세스에 전달합니다. 이를 통해 pkill -f -USR1 skcluster를 사용할 수 있습니다. 자식 프로세스가 새 작업 수락을 중지하도록 하려면(이는 배포 스크립트의 초기 작업임) pkill -f skcluster를 사용할 수 있습니다. 모든 것을 종료합니다.

시스템 구성

시스템화된 서비스 정의는 간단합니다.

모든 인스턴스에서 pgbouncer를 사용하여 postgres에 대한 연결을 프록시하므로 sidekiq 프로세스가 부팅되기 전에 pgbouncer 서비스가 실행되고 있는지 확인합니다. 동일한 인스턴스에서 redis를 실행하는 경우 Requires 및 After 라인에 redis-server.service도 추가합니다. EnvironmentFile은 파일 이름에 - 접두사를 사용하여 파일이 존재하지 않아도 괜찮다고 systemd에 알립니다. 이를 통해 기본 프로세스 수와 메모리 제한을 사용하려는 경우 해당 파일을 생략할 수 있습니다. --require를 사용합니다. Sidekiq가 Rails 애플리케이션의 구성 및 초기화 프로그램을 로드할 위치를 알려주는 옵션입니다. skcluster 스크립트가 SIGTERM을 포착하므로 systemctl restart skcluster.service를 사용할 수 있습니다. 모든 작업자를 다시 시작합니다(이는 배포 스크립트의 늦은 작업입니다).

우리는 이 스크립트를 한동안 사용해 왔으며 챔피언처럼 작동했습니다. 부팅 시 너무 많은 프로세스가 생성되는 문제가 더 이상 없으며 모니터링에서 더 이상 메모리 사용 경고가 표시되지 않으며 원하는 모든 유형의 EC2 인스턴스를 시작할 수 있습니다. 번거롭지 않은 작업은 내가 가장 좋아하는 작업입니다. :)