본문으로 건너뛰기

[HPC From Scratch] 에피소드 6: Slurm Accounting, QOS, Fair Share 설정하기

Will Paik
작성자
Will Paik
대규모 GPU 클러스터를 최적화하는 HPC 엔지니어. 밤에는 방구석 미니 슈퍼컴퓨터를 조립하며(가끔은 태워 먹으며) 그 과정을 기록합니다.
HPC From Scratch - 이 글은 시리즈의 일부입니다.
파트 6: 이 글

스케줄러는 돌아가고 있습니다. 이제 누가 무엇을 얼마나 쓸 수 있는지 가르쳐줄 차례입니다.

에피소드 5에서는 Slurm을 설치하고, slurmdbd를 MariaDB에 연결하고, 첫 번째 작업을 제출했습니다. 클러스터는 잘 돌아갑니다.

하지만 지금 상태는 사실상 무법지대입니다. 작업에 시간 제한이 없고, 한 명이 큐에 작업을 수백 개씩 넣어도 아무도 막을 수 없습니다. 지난 일주일 내내 클러스터를 혼자 쓴 유저와 처음 작업을 제출한 유저를 스케줄러는 똑같이 취급합니다. 혼자 쓰는 클러스터라면 괜찮지만, 여러 명이 공유하는 순간 문제가 생깁니다.

이번 에피소드에서는 accounting 레이어를 처음부터 만듭니다. sacctmgr으로 account 계층을 구성하고, QOS 정책을 설정하고, 페어 쉐어(Fair Share) 스케줄링을 활성화합니다. 현재 시간 제한이 전혀 없는 파티션에도 wall time 제한을 추가합니다.

사전 요구사항: 이 에피소드는 에피소드 5를 완료한 상태를 전제로 합니다. slurmdbd가 MariaDB에 연결된 Slurm 설치 환경과 idle 상태의 컴퓨트 노드가 최소 하나 있어야 합니다.

1. Slurm Accounting 구조 이해하기
#

Slurm accounting에는 세 가지 레벨이 있습니다.

Cluster가 최상단입니다. 에피소드 5에서 sacctmgr -i add cluster cluster로 등록한 그 cluster입니다.

Account는 cluster 아래에 있는 그룹입니다. 부서, 연구 그룹, 또는 PI 랩 단위로 생각하면 됩니다. Account가 페어 쉐어 예산을 가지고 있습니다. research가 클러스터 전체 share의 80%를 갖고 demo가 20%를 가지면, 큐가 경합할 때 그 비율이 우선순위를 결정합니다.

User는 하나 이상의 account에 속합니다. 작업을 제출하면 Slurm이 사용량을 해당 account에 기록하고, 그것이 account의 페어 쉐어 점수에 영향을 줍니다.

에피소드 5 이후 현재 상태는 다음과 같습니다:

cluster
└── root
    ├── root  (user)
    └── wpaik

모든 것이 root account 아래에 구조 없이 쌓여 있습니다. 여기에 sub-account 두 개를 추가하고 유저를 적절한 위치에 배치합니다:

cluster
└── root
    ├── research  (share=80)
    │   ├── wpaik
    │   └── testuser1
    └── demo  (share=20)
        └── testuser2
Slurm 계정 계층

2. Account 트리 만들기
#

root 아래에 두 개의 sub-account를 만듭니다. parent=root 옵션이 기존 root account 아래에 위치시킵니다.

[wpaik@arbiter ~]$ sudo sacctmgr -i add account research parent=root \
    Description="Research Group" Organization="Cluster" fairshare=80

[wpaik@arbiter ~]$ sudo sacctmgr -i add account demo parent=root \
    Description="Demo Group" Organization="Cluster" fairshare=20

참고: sacctmgr write 명령어(add, modify, delete)는 admin 권한이 필요합니다. wpaik의 sacctmgr AdminLevelNone이므로 데이터베이스를 수정하는 모든 명령어에 sudo가 필요합니다. sacctmgr show 같은 read-only 명령어는 sudo 없이 실행할 수 있습니다.

Slurm accounting에 유저를 추가하기 전에, testuser1과 testuser2가 실제 시스템 유저로 존재해야 합니다. 이 클러스터는 FreeIPA를 사용하므로 거기서 먼저 만듭니다. 데모용이라면 홈 디렉토리 없이 최소한의 계정만 만들어도 됩니다.

[wpaik@arbiter ~]$ ipa user-add testuser1 --first=Test --last=User1
[wpaik@arbiter ~]$ ipa user-add testuser2 --first=Test --last=User2

이제 accounting 데이터베이스에 유저를 추가합니다:

# wpaik은 에피소드 5에서 root account에 이미 등록되어 있습니다.
# research에 추가하면 두 번째 association이 생기고 기본 account가 바뀝니다.
[wpaik@arbiter ~]$ sudo sacctmgr -i add user wpaik account=research defaultaccount=research

[wpaik@arbiter ~]$ sudo sacctmgr -i add user testuser1 account=research defaultaccount=research
[wpaik@arbiter ~]$ sudo sacctmgr -i add user testuser2 account=demo defaultaccount=demo

유저는 여러 account에 동시에 속할 수 있습니다. wpaik은 이제 rootresearch 두 곳에 association이 생겼습니다. 기본 account는 research로 바뀌었습니다.

Admin account에 대한 참고: 이 시리즈에서는 wpaik이 sacctmgr 명령어, slurm.conf 수정, sudo 작업을 포함한 모든 클러스터 관리를 담당합니다. 홈 랩에서는 흔한 구조입니다. 다만 실제 HPC 환경에서는 관리 작업을 별도의 서비스 계정으로 분리하는 것이 일반적입니다. 여기서 중요한 것은 wpaik의 sacctmgr AdminLevelNone이라는 점입니다. Linux sudoer 권한은 스케줄러가 전혀 인식하지 않습니다.

트리를 확인합니다:

[wpaik@arbiter ~]$ sacctmgr show associations format=cluster,account,user,share,qos,defaultqos
   Cluster    Account       User     Share                QOS DefQOS
---------- ---------- ---------- --------- -------------------- ------
   cluster       root                    1
   cluster       root       root         1
   cluster   research                   80       normal,high,gpu normal
   cluster   research      wpaik         1       normal,high,gpu normal
   cluster   research  testuser1         1       normal,high,gpu normal
   cluster       demo                   20                normal normal
   cluster       demo  testuser2         1                normal normal

wpaik이 두 곳에 보이는 이유: wpaik은 root(에피소드 5에서 생성)와 research(이번에 추가) 두 곳에 association이 있습니다. sshare -l을 실행하면 wpaik이 두 줄로 나옵니다. root 항목에는 에피소드 5에서 돌렸던 작업의 사용량이 쌓여 있고, research 항목은 이번에 새로 만들어져서 사용량이 0입니다. 앞으로 제출하는 작업은 기본적으로 research account에 청구됩니다.

3. QOS: 작업에 가중치 부여하기
#

QOS(Quality of Service)를 사용하면 작업에 규칙을 붙일 수 있습니다. 얼마나 오래 돌릴 수 있는지, 리소스를 얼마나 요청할 수 있는지, 큐에서 얼마나 높은 우선순위를 가지는지 등을 정의합니다. QOS 없이는 모든 작업이 같은 조건에서 경쟁합니다.

세 가지 레벨을 만듭니다:

QOS Priority MaxWall 용도
normal 0 24시간 모든 작업의 기본값
high 100 4시간 큐를 앞당기는 짧고 긴급한 작업
gpu 50 8시간 GPU 파티션 작업

생성하고 설정합니다:

[wpaik@arbiter ~]$ sudo sacctmgr -i add qos normal
[wpaik@arbiter ~]$ sudo sacctmgr -i modify qos normal set Priority=0 MaxWallDurationPerJob=1-00:00:00

[wpaik@arbiter ~]$ sudo sacctmgr -i add qos high
[wpaik@arbiter ~]$ sudo sacctmgr -i modify qos high set Priority=100 MaxWallDurationPerJob=04:00:00

[wpaik@arbiter ~]$ sudo sacctmgr -i add qos gpu
[wpaik@arbiter ~]$ sudo sacctmgr -i modify qos gpu set Priority=50 MaxWallDurationPerJob=08:00:00

각 account에 사용 가능한 QOS를 지정합니다. research는 세 가지 모두, demonormal만 사용할 수 있습니다.

[wpaik@arbiter ~]$ sudo sacctmgr -i modify account name=research set qos=normal,high,gpu defaultqos=normal
[wpaik@arbiter ~]$ sudo sacctmgr -i modify account name=demo set qos=normal defaultqos=normal

기본이 아닌 QOS를 사용하려면 작업 스크립트에 다음과 같이 작성합니다:

#SBATCH --qos=high

demo 소속 유저가 --qos=high로 제출하면 Slurm이 큐에 들어가기도 전에 즉시 거부합니다:

sbatch: error: Batch job submission failed: Invalid qos specification

참고: high QOS는 4시간 wall limit이 있습니다. --qos=high--time=08:00:00을 동시에 지정할 수 없습니다. 우선순위 부스트를 받는 대신 더 짧은 런타임 제한을 감수하는 구조입니다.

4. 페어 쉐어: 많이 쓰면 기다리게 하기
#

Fair share 일정 관리 컨셉

페어 쉐어(Fair Share) 없이는 Slurm이 제출 순서대로(FIFO) 스케줄링합니다. 지난 주에 작업을 몇 백 개 돌렸든 처음 제출하든 상관없이 먼저 들어온 작업이 먼저 실행됩니다.

페어 쉐어는 사용 이력을 추적해서 우선순위를 조정합니다. 본인 할당량보다 많이 쓴 유저는 우선순위가 낮아지고, 적게 쓴 유저는 높아집니다. 오늘 많이 쓰면 내일 우선순위가 낮아지는 방식으로 자동 조정됩니다.

페어 쉐어 활성화하기
#

arbiter/etc/slurm/slurm.conf에 다음 줄을 추가합니다:

[wpaik@arbiter ~]$ sudo vim /etc/slurm/slurm.conf
# Priority / Fair Share
PriorityType=priority/multifactor
PriorityWeightFairShare=100000
PriorityWeightAge=1000
PriorityDecayHalfLife=5-0
PriorityMaxAge=7-0
AccountingStorageEnforce=associations,qos

PriorityType=priority/multifactor Slurm을 FIFO에서 가중치 기반 멀티팩터 우선순위 모델로 전환합니다. 이 한 줄이 이 섹션의 나머지 설정들을 활성화시킵니다.

PriorityWeightFairShare=100000 페어 쉐어를 우선순위 계산의 핵심 요소로 만듭니다. 작업 대기 시간 같은 다른 요소들도 반영되지만, 사용 이력이 스케줄링 결정을 주도합니다.

PriorityWeightAge=1000 오래 기다린 작업에 조금씩 보너스를 추가합니다. 이 덕분에 페어 쉐어 점수가 낮아진 유저의 작업도 결국 실행될 수 있습니다. 무한정 기다리는 상황(starvation)을 방지합니다.

PriorityDecayHalfLife=5-0 스케줄러가 과거 사용량을 얼마나 오래 기억하는지를 결정합니다. 5일마다 누적 사용량이 절반으로 줄어듭니다. 오늘 쓴 CPU 1시간이 5일 전 쓴 CPU 1시간보다 두 배 영향을 미칩니다.

PriorityMaxAge=7-0 대기 시간 보너스를 7일에서 제한합니다. 2주 동안 큐에서 기다렸다고 해서 우선순위가 계속 쌓이지는 않습니다.

AccountingStorageEnforce=associations,qos Slurm이 잡 제출 시점에 accounting 규칙을 실제로 강제하도록 합니다. associations는 accounting 데이터베이스에 없는 유저의 잡을 거부합니다. qos는 계정에 허용되지 않은 QOS를 요청하는 잡을 거부합니다. 이 줄이 없으면 sacctmgr에서 설정한 QOS 제한이 데이터베이스에만 기록되고 실제로 검사되지 않습니다. demo 계정의 유저가 --qos=high로 제출해도 그냥 돌아가는 문제가 생깁니다.

Decay vs. Reset
#

과거 사용량을 처리하는 방법은 두 가지입니다:

방식 파라미터 동작
점진적 감소 PriorityDecayHalfLife=5-0 지수적 감소, 오래된 사용량이 서서히 영향력을 잃음
완전 리셋 PriorityUsageResetPeriod=MONTHLY 고정된 주기마다 전체 사용량이 0으로 초기화됨

완전 리셋은 개념적으로 단순합니다. 매월 1일에 모두가 깨끗하게 시작합니다. 하지만 벼랑이 생깁니다. 2일에 쌓인 사용량은 리셋 직전까지 그대로인데 0시에 갑자기 0으로 떨어집니다. 월초에 클러스터를 독점한 유저가 나머지 기간 동안 절약할 이유가 없어집니다.

점진적 감소는 그 벼랑이 없습니다. 5일 half-life라면 지난주 사용량은 오늘의 약 1/4 수준으로 반영됩니다. 갑작스러운 리셋 없이 우선순위가 연속적으로 조정됩니다. 5일이라는 값은 합리적인 시작점입니다. 단발성 작업 하나로 수 주 동안 불이익을 받을 만큼 길지 않으면서, 스케줄러가 실제로 기억할 만큼은 깁니다. 실제 HPC 클러스터는 대개 1-7일 범위 안에서 설정합니다.

Fair Share 벼랑

실제로 어떻게 작동하나요?
#

research가 share=80, demo가 share=20인 상황에서:

  • wpaik이 3일 내내 작업을 돌렸다면 FairShare 점수가 1.0 아래로 크게 내려갑니다.
  • demo의 testuser2는 아무것도 돌리지 않았습니다. FairShare 점수가 1.0을 유지합니다.
  • 둘이 동시에 작업을 제출하면, testuser2의 account share가 작더라도 testuser2 작업이 먼저 실행될 수 있습니다. 아무것도 소비하지 않았기 때문입니다.

이것이 의도된 동작입니다. 페어 쉐어는 할당량 자체가 아니라 할당량 대비 실제 사용량을 기준으로 합니다. research가 share=80을 가진다는 것은 모두가 동시에 경쟁할 때 80%를 가져간다는 의미입니다. 항상 먼저 실행된다는 뜻이 아닙니다.

5. 파티션 제한 설정하기
#

두 파티션 모두 현재 MaxTime=UNLIMITED이고 DefaultTime이 없습니다. --time을 지정하지 않고 작업을 제출하면 무제한 wall time이 적용됩니다. 작업이 멈추면 리소스를 무한정 점유할 수 있습니다.

arbiterslurm.conf에서 기존 PartitionName= 줄을 아래로 교체합니다:

PartitionName=cpu Nodes=interceptor-[01-02] Default=YES MaxTime=1-00:00:00 DefaultTime=01:00:00 State=UP
PartitionName=gpu Nodes=corsair-01 Default=NO MaxTime=08:00:00 DefaultTime=01:00:00 AllowQos=normal,gpu State=UP

DefaultTime=01:00:00 --time을 지정하지 않은 작업에 1시간 제한을 자동으로 부여합니다. 두 파라미터 중 더 중요한 것입니다. 기본값이 없으면 --time을 빠뜨리는 것이 무제한 런타임을 요청하는 것과 같습니다.

MaxTime=1-00:00:00 CPU 작업을 24시간으로 제한합니다. 그보다 오래 걸리는 작업은 어차피 24시간 단위로 체크포인팅을 해야 합니다.

AllowQos=normal,gpu GPU 파티션에서 high QOS를 사용하지 못하도록 막습니다. 우선순위 부스트 QOS는 짧은 CPU 작업용이지, GPU 큐를 앞당기는 용도가 아닙니다.

6. 변경사항 적용하기
#

sacctmgr 변경사항(account, user, QOS)은 이미 데이터베이스에 반영됐습니다. 재시작이 필요 없습니다.

slurm.conf 변경사항(priority 설정, 파티션 제한)은 전체 노드에 배포하고 slurmctld를 재시작해야 합니다.

# 업데이트된 slurm.conf를 전체 노드에 배포
[wpaik@arbiter ~]$ ansible all_nodes -b -m copy \
    -a "src=/etc/slurm/slurm.conf dest=/etc/slurm/slurm.conf owner=slurm group=slurm mode=0644"

# arbiter에서 slurmctld 재시작
[wpaik@arbiter ~]$ sudo systemctl restart slurmctld

# 모든 slurmd 데몬에 config 재읽기 신호 전송
[wpaik@arbiter ~]$ sudo scontrol reconfigure

# 확인
[wpaik@arbiter ~]$ sudo systemctl status slurmctld
[wpaik@arbiter ~]$ tail -n 20 /var/log/slurm/slurmctld.log

scontrol reconfigure 단계가 중요합니다. slurm.conf를 배포하고 slurmctld를 재시작하면 컨트롤러가 새 파일 기반으로 config hash를 다시 계산합니다. 이 명령 없이는 컴퓨트 노드의 slurmd 데몬이 예전 hash를 그대로 들고 있어서 Slurm 로그에 config mismatch 경고가 계속 나타납니다.

7. 검증하기
#

Account 및 QOS 구조
#

[wpaik@arbiter ~]$ sacctmgr show associations format=cluster,account,user,share,qos,defaultqos
[wpaik@arbiter ~]$ sacctmgr show qos format=name,priority,maxwall,flags

페어 쉐어 트리
#

[wpaik@carrier ~]$ sshare -l
             Account       User  RawShares  NormShares  RawUsage  EffectvUsage  FairShare
-------------------- ---------- ---------- ----------- --------- ------------- ----------
root                               1          0.000000         0      0.000000   1.000000
 root                    wpaik    1          0.009804         0      0.000000   1.000000
 research                         80         0.784314         0      0.000000        inf
  research              wpaik     1          0.500000         0      0.000000   1.000000
  research           testuser1    1          0.500000         0      0.000000   1.000000
 demo                             20         0.196078         0      0.000000        inf
  demo               testuser2    1          1.000000         0      0.000000   1.000000

wpaik이 rootresearch 두 줄로 나오는 것은 정상입니다. root 항목에는 에피소드 5에서 쌓인 사용량이 있고, research 항목은 이번에 새로 만들어져서 0입니다. inf는 research와 demo account의 사용량이 아직 0이라 비율 계산이 안 된다는 의미입니다. 작업을 돌리면 숫자로 바뀝니다.

작업 우선순위 분석
#

[wpaik@carrier ~]$ sprio -l

큐에 있는 각 작업의 우선순위를 FairShare 기여도, Age 기여도, QOS 기여도별로 나눠서 보여줍니다. 왜 어떤 작업이 다른 작업보다 먼저 실행되는지 확인할 때 유용합니다.

작업 실행 이력
#

[wpaik@carrier ~]$ sacct -u wpaik --format=JobID,JobName,Partition,Account,AllocCPUS,State,Elapsed

파티션 제한 확인
#

[wpaik@carrier ~]$ scontrol show partition cpu
[wpaik@carrier ~]$ scontrol show partition gpu

GPU 파티션은 아래와 같이 나와야 합니다:

PartitionName=gpu
   AllowGroups=ALL AllowAccounts=ALL AllowQos=normal,gpu
   DefaultTime=01:00:00 MaxTime=08:00:00
   Nodes=corsair-01
   ...

확인할 항목: AllowQos=normal,gpu (ALL이 아님), MaxTime=08:00:00, DefaultTime=01:00:00. AllowQos=ALL이나 MaxTime=UNLIMITED이 여전히 보이면 아래 트러블슈팅을 참고하십시오.

8. 트러블슈팅
#

scontrol show partition gpu에서 AllowQos=ALL이 계속 표시되는 경우

먼저 arbiter의 slurm.conf에 PartitionName=gpu 줄이 실제로 업데이트됐는지 확인합니다:

[wpaik@arbiter ~]$ grep "PartitionName=gpu" /etc/slurm/slurm.conf

AllowQos=normal,gpu가 포함되어 있어야 합니다. 포함되어 있다면 파일이 모든 노드에 배포됐는지 확인합니다:

[wpaik@arbiter ~]$ ansible all_nodes -b -m shell \
    -a "grep 'PartitionName=gpu' /etc/slurm/slurm.conf"

노드 중 예전 버전을 가진 곳이 있으면 ansible copy를 다시 실행합니다. 그다음 재시작합니다:

[wpaik@arbiter ~]$ sudo systemctl restart slurmctld
[wpaik@arbiter ~]$ sudo scontrol reconfigure
[wpaik@carrier ~]$ scontrol show partition gpu | grep AllowQos

slurmctld 로그에 slurm.conf hash mismatch 경고

slurmctld 재시작 후 다음과 같은 에러가 보일 수 있습니다:

error: Node interceptor-01 appears to have a different slurm.conf than the slurmctld.

파일 내용이 동일해도 나오는 에러입니다. slurmctld는 재시작하면서 새 파일의 hash를 계산했는데, 컴퓨트 노드의 slurmd는 아직 예전 hash를 들고 있어서 생기는 불일치입니다.

[wpaik@arbiter ~]$ sudo scontrol reconfigure

이 명령이 모든 slurmd 데몬에 config 재읽기 신호를 보냅니다. 이후 로그에 해당 경고가 사라지면 정상입니다.

PriorityType 추가 후 slurmctld 시작 실패

먼저 컨트롤러 로그를 확인합니다:

[wpaik@arbiter ~]$ tail -n 50 /var/log/slurm/slurmctld.log

가장 흔한 원인은 slurmctld가 시작될 때 slurmdbd가 준비가 안 된 경우입니다. PriorityType=priority/multifactor는 시작 시 accounting 데이터베이스 접근이 필요합니다.

[wpaik@arbiter ~]$ sudo systemctl status slurmdbd
[wpaik@arbiter ~]$ sudo systemctl restart slurmdbd
[wpaik@arbiter ~]$ sudo systemctl restart slurmctld

slurmdbd를 먼저 시작하고 그 다음 slurmctld를 시작해야 합니다.

sacctmgr -i add account가 “already exists” 에러 반환

setup 스크립트는 idempotent하지 않습니다. 일부를 이미 실행했다면 account가 이미 있을 수 있습니다.

[wpaik@arbiter ~]$ sacctmgr show account

account가 이미 있으면 add 명령은 건너뛰고 modify를 사용합니다. fairshare 값이 잘못됐다면:

[wpaik@arbiter ~]$ sudo sacctmgr -i modify account name=research set fairshare=80

sshare가 모두 0이거나 데이터가 없음

PriorityType=priority/multifactor가 아직 활성화되지 않은 상태입니다. slurm.conf 변경이 적용되지 않았거나, 변경 후 slurmctld를 재시작하지 않은 경우입니다.

# 설정이 실제로 적용됐는지 확인
[wpaik@arbiter ~]$ scontrol show config | grep PriorityType

아직 basic으로 나오면 slurmctld를 재시작하고 다시 확인합니다.

작업 제출 시 “Invalid qos specification” 에러

해당 유저의 account에 그 QOS가 허용되지 않은 상태입니다.

[wpaik@arbiter ~]$ sacctmgr show associations format=account,user,qos where user=testuser2

QOS가 없으면 추가합니다:

[wpaik@arbiter ~]$ sudo sacctmgr -i modify account name=demo set qos=normal,high

9. 다음 에피소드는?
#

이제 클러스터에 제대로 된 멀티 유저 accounting 구조가 생겼습니다. 작업은 정해진 share 가중치를 가진 account 아래에서 실행되고, 많이 쓴 유저는 자동으로 우선순위가 낮아지고, 파티션에는 시간 제한이 생겨서 runaway 작업으로부터 다른 유저를 보호할 수 있습니다.

다음 에피소드는 Lmod입니다. 클러스터에 Lmod 모듈 시스템을 설치하고 실제 소프트웨어 모듈을 구성합니다.

이번 에피소드의 설정 파일과 sacctmgr setup 스크립트는 GitHub 저장소에 있습니다.


즐거운 컴퓨팅 되세요!

HPC From Scratch - 이 글은 시리즈의 일부입니다.
파트 6: 이 글