#author("2026-04-26T17:09:06+00:00","default:sysosa","sysosa")
#author("2026-04-26T17:10:23+00:00","default:sysosa","sysosa")
ジョブの履歴、投入時刻、計算終了時刻、成功/失敗、実行者らを記録する
「Account」を作ってそれをposixユーザにアサインしてチームでの課金とかが図れるっぽい

加えて同時実行可能ジョブの数を制限することもできます。特定ユーザによるリソースの占有を防げます。Account単位とかも可能っぽい

このaccountingを利用するには 追加パッケージ slurmdbd と MariaDB データベースが必要です

参照先[[https://gist.github.com/DaisukeMiyamoto/d1dac9483ff0971d5d9f34000311d312>+https://gist.github.com/DaisukeMiyamoto/d1dac9483ff0971d5d9f34000311d312]]様

&size(10){単に利用状況の可視化なら[[XDMoD]]とかで};

***MariaDB の準備 [#k4db0f68]
MariaDBをどこに設置するか.
-管理ノード(slurmノード)内にslurmdbdを設置して、そこにDBも同居させる.
-管理ノード内にslurmdbdを設置するが、DBは別の場所(ノード)に.
-管理ノードとは別のノードにslurmdbdを設置して、そこにDBも住まわせる.
-管理ノードとは別のノードにslurmdbdを設置して、DBも別の場所で稼働させる.

とかでしょうか.

ここでは「管理ノードとは別のノードにslurmdbdを設置して、そこにDBも置く」で作ってみる.

ディストリビューター様のパッケージを使います. &size(10){RockyLinux9.7で提供される MariaDB は 10.5.29 である. MySQLでは 5.7系 に相当};
#code(nonumber){{
[root@slurmdbd ~]# cat /etc/redhat-release
Rocky Linux release 9.7 (Blue Onyx)

[root@slurmdbd ~]# dnf install mariadb-server

[root@slurmdbd ~]# systemctl enable mariadb --now

(確認)
[root@slurmdbd ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.5.29-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

MariaDB [(none)]> \q
Bye
[root@slurmdbd ~]#
}}
全くの初期状態である.

これにデータベース「slurm_acct_db」を作って、そのデータベースにアクセス可能なユーザとして
slurmを作ります. &size(10){データベース内アカウントでOSアカウントではないです}; っで管理ノードからこのslurmを使ってアクセスする想定です
#code(nonumber){{
[root@slurmdbd ~]# mysql

(database作成)
MariaDB [(none)]> create database slurm_acct_db;
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| slurm_acct_db      |
+--------------------+

(databaseアクセスユーザの作成)
MariaDB [(none)]> create user 'slurm'@'localhost' identified by 'SLURM';
MariaDB [(none)]> select user,host from mysql.user;
+-------+-----------+
| user  | host      |
+-------+-----------+
| root  | 127.0.0.1 |
| root  | ::1       |
| root  | localhost |
| slurm | localhost |  <-- 作られたユーザ
| root  | slurmdbd  |
+-------+-----------+

MariaDB [(none)]>

(権限付与)
MariaDB [(none)]> grant all on slurm_acct_db.* TO 'slurm'@'localhost';
MariaDB [(none)]> FLUSH PRIVILEGES;
}}
あと微調整 &size(10){[[https://slurm.schedmd.com/accounting.html>+https://slurm.schedmd.com/accounting.html]]}; /etc/my.cnf.d/mariadb-server.cnfの[mysqld]セクションに値を追加します.
#code(diff,nonumber){{
--- /etc/my.cnf.d/mariadb-server.cnf.orig       2023-10-13 00:17:48.000000000 +0900
+++ /etc/my.cnf.d/mariadb-server.cnf    2024-11-03 00:33:37.271777078 +0900
@@ -18,6 +18,10 @@
 socket=/var/lib/mysql/mysql.sock
 log-error=/var/log/mariadb/mariadb.log
 pid-file=/run/mariadb/mariadb.pid
+innodb_buffer_pool_size=4096M
+innodb_log_file_size=64M
+innodb_lock_wait_timeout=900
+max_allowed_packet=16M


 #
}}
として
#code(nonumber){{
[root@slurmdbd ~]# systemctl restart mariadb
}}

***接続テスト [#jaa85f71]
#code(nonumber){{
[root@slurmdbd ~]# mysql -u slurm -h localhost -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.35-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> quit
Bye
[root@slurmdbd ~]#
}}
と接続は上手く行った


***slurm-slurmdbdパッケージのインストールとmunge.keyの受領 [#y90d10c6]
[[slurm/rpm]にて作成したパッケージを入れます
#code(nonumber){{
(同じRockyLinux8の管理ノードslurmから)
[root@slurm ~]# scp rpmbuild/RPMS/x86_64/slurm-22.05.7-1.el8.x86_64.rpm rpmbuild/RPMS/x86_64/slurm-slurmdbd-22.05.7-1.el8.x86_64.rpm slurmdbd:

[root@slurmdbd ~]# groupadd -g 5000 slurm
[root@slurmdbd ~]# useradd -M -d /var/lib/slurm -s /sbin/nologin -u 5000 -g slurm slurm

[root@slurmdbd ~]# dnf localinstall slurm-22.05.7-1.el8.x86_64.rpm slurm-slurmdbd-22.05.7-1.el8.x86_64.rpm

(管理ノードslurmからslurm.keyのコピー)
[root@slurm ~]# scp /opt/slurm/etc/slurm.key slurmdbd:/opt/slurm/etc/

[root@slurmdbd ~]# chown slurm. /opt/slurm/etc/slurm.key
}}


***接続設定 [#c67a2b8d]
管理ノードとは別のノードに slurmDBD を設置したので、管理ノードのslurmにslurmDBDの場所を伝える必要がある
#code(nonumber){{
[root@slurm ~]# vi /opt/slurm/etc/slurm.conf
(略)
AccountingStorageType=accounting_storage/slurmdbd
AccountingStorageHost=slurmdbd      # slurmctldと同居なら localhost で可
#AccountingStorageExternalHost=     # 単一クラスターのslurmファーマなら不要。フェデレーション構成、NAT越え、内部IPと外部IPが異なる環境の際に使用
AccountingStoragePort=6819
AccountingStoreFlags=job_comment    # slurm が slurmdbd にどの追加情報を保存するかを制御する設定, job_comment(ジョブコメントを保存), job_script(ジョブスクリプト本文を保存), job_env(環境変数も)
                                    # AccountingStoreFlags=job_comment,job_script,job_env なら完全再現型となるがDBは肥大する. 「job_comment」か「job_comment,job_script」とかで
}}
次にslurmDBDノードでの設定ファイルを作る

ジョブの実況状態を残すアーカイブ機能がありますが、テキストファイルで出てきます。っでこの解析は面倒で、
むしろデータベースに入れて置いて、そこで解析した方が楽っぽい。
なので書き出しはしない方向です

#code(nonumber){{
[root@slurmdbd ~]# mkdir /opt/slurm/etc
[root@slurmdbd ~]# vi /opt/slurm/etc/slurmdbd.conf
##
SlurmUser=slurm    # slurmdbd をユーザ slurm で動かします
##
## Archiving DBに溜まったジョブ情報はファイルにアーカイブせずに期間が着たらDBから削除する。ファイルにアーカイブしたら解析し辛いので無意味かな
ArchiveJobs=no     # ジョブの基本情報(ジョブID,ユーザ、開始時間、終了時間、終了ステータス、使用リソース量[CPU/GPU])
ArchiveEvents=no   # ジョブ内の詳細ステップ
ArchiveSteps=no    # クラスターの出来事(計算ノードのダウン/アップ, メンテナンス時間など)
ArchiveResvs=no    # 予約(Reservation)の情報
ArchiveSuspend=no  # ジョブの中断・再開(Suspend/Resume)の記録
ArchiveTXN=no      # データベースの操作履歴(Transaction)
ArchiveUsage=no    # リソース使用量の集計データ(Rollup)
#ArchiveDir=       # ArchiveJobs=yesならその保存先、平文で出てきてmysqlのdumpではない。保存先はslurm.confのSlurmUserで書き込みできること.

# Authentication info
AuthType=auth/slurm  # mungeではなくslurm独自の認証で動きます (/opt/slurm/etc/slurm.keyが必須)
#
# slurmDBD info
DbdHost=slurmdbd  # slurmDBDが動いているサイト
DbdPort=6819      # slurmDBDの接続port
DebugLevel=info   # slurmDBDのログレベル
LogFile=/var/log/slurm/slurmdbd.log  # ログファイルの場所
PidFile=/run/slurmdbd/slurmdbd.pid

# db purge mysql/mariaDBに溜まるデータをいつの時点でpurgeするのか
# 重要なデータは1年保持
PurgeJobAfter=18months
PurgeUsageAfter=18months
PurgeTXNAfter=18months
PurgeEventAfter=18months
PurgeResvAfter=18months
# 重くなりやすい詳細データは短めに
PurgeStepAfter=14days
PurgeSuspendAfter=14days

# Database info
# データの保管場所
StorageType=accounting_storage/mysql
StorageHost=localhost
StorageHost=localhost                 # mysqlで作成した 'slurm'@'localhost' に符合するようにします
StorageUser=slurm
StoragePass=SLURM
StorageLoc=slurm_acct_db

[root@slurmdbd ~]#
[root@slurmdbd ~]# echo "D /run/slurmdbd 0755 slurm slurm -" > /usr/lib/tmpfiles.d/slurmdbd.conf
[root@slurmdbd ~]# /usr/bin/systemd-tmpfiles --create /usr/lib/tmpfiles.d/slurmdbd.conf
}}

あと、データベース接続のためのパスワードが平文で入っているので 0600 にします. それと所有者を変更します. あとログの配置場所も用意します.
#code(nonumber){{
[root@slurmdbd ~]# chmod 600 /opt/slurm/etc/slurmdbd.conf
[root@slurmdbd ~]# chown slurm. /opt/slurm/etc/slurmdbd.conf

[root@slurmdbd ~]# mkdir /var/log/slurm/archive ; chown slurm. /var/log/slurm/archive ; chmod 700 /var/log/slurm/archive
}}

***firewall [#b7a1fdad]
#code(nonumber){{
[root@slurmdbd ~]# firewall-cmd --add-port=6819/tcp --zone=public --permanent
[root@slurmdbd ~]# firewall-cmd --reload
}}

***起動 [#z1a57c9d]
#code(nonumber){{
[root@slurmdbd ~]# systemctl enable slurmdbd.service --now
}}

起動順番的には mariadb(データベース) -> slurmdbd(課金ノード)/slurmd(計算ノード) -> slurmctld(管理ノード) って感じかな.

「&color(magenta){mysql_db_insert_ret_id: We should have gotten a new id: Table 'slurm_acct_db.cluster_job_table' doesn't exist};」
あるいは
「&color(magenta){error: Problem getting jobs for cluster cluster};」
って言われたら、これは slurm_acct_db に cluster=cluster が存在しないときに出るみたい.

#code(nonumber){{
[root@slurm ~]# sacctmgr list cluster
   Cluster     ControlHost  ControlPort   RPC     Share GrpJobs       GrpTRES GrpSubmit MaxJobs       MaxTRES MaxSubmit     MaxWall                  QOS   Def QOS
---------- --------------- ------------ ----- --------- ------- ------------- --------- ------- ------------- --------- ----------- -------------------- ---------
[root@slurm ~]#
}}
と何もないのが原因で、slurm.confの「ClusterName=cluster」を登録します
#code(nonumber){{
[root@slurm ~]# sacctmgr add cluster cluster
 Adding Cluster(s)
  Name           = cluster
Would you like to commit changes? (You have 30 seconds to decide)
(N/y): y

[root@slurm ~]#

(確認)
[root@slurm ~]# sacctmgr list cluster
[root@beluga ~]# sacctmgr list cluster
   Cluster     ControlHost  ControlPort   RPC     Share GrpJobs       GrpTRES GrpSubmit MaxJobs       MaxTRES MaxSubmit     MaxWall                  QOS   Def QOS
---------- --------------- ------------ ----- --------- ------- ------------- --------- ------- ------------- --------- ----------- -------------------- ---------
   cluster       127.0.0.1         6817 11264         1                                                                                           normal
[root@slurm ~]#

}}
その後に slurmdbd と slurmctld を再起動.

もし再起動後しても動かない場合、「journalctl -u slurmctld.service」で
#code(nonumber){{
   systemd[1]: Started Slurm controller daemon.
   slurmctld[296198]: [2026-03-07T12:29:22.221] accounting_storage/slurmdbd: clusteracct_storage_p_register_ctld: Registering slurmctld at port 6817 with slurmdbd
   slurmctld[296198]: [2026-03-07T12:29:22.228] fatal: CLUSTER ID MISMATCH.
   slurmctld[296198]: slurmctld has been started with "ClusterID=1371"  from the state files in StateSaveLocation, but the DBD thinks it should be "80".
   slurmctld[296198]: Running multiple clusters from a shared StateSaveLocation WILL CAUSE CORRUPTION.
   slurmctld[296198]: Remove /var/spool/slurm/ctld/clustername to override this safety check if this is intentional.
   systemd[1]: slurmctld.service: Main process exited, code=exited, status=1/FAILURE
   systemd[1]: slurmctld.service: Killing process 296261 (worker[28]) with signal SIGKILL.
   systemd[1]: slurmctld.service: Failed with result 'exit-code'.
}}
となら、「slurmctld: ClusterID=1371」で「slurmdbd : ClusterID=80」と違うため。
#code(nonumber){{
rm /var/spool/slurm/ctld/clustername

systemctl restart slurmctld
}}
で修復可能

***accounting 動作確認 [#n1398054]
クライアントノード(slurm-client)で
#code(nonumber){{
[illya@slurm-client ~]$ sacct
JobID           JobName  Partition    Account  AllocCPUS      State ExitCode
------------ ---------- ---------- ---------- ---------- ---------- --------
[illya@slurm-client ~]$ sacctmgr list cluster
   Cluster     ControlHost  ControlPort   RPC     Share GrpJobs       GrpTRES GrpSubmit MaxJobs       MaxTRES MaxSubmit     MaxWall                  QOS   Def QOS
---------- --------------- ------------ ----- --------- ------- ------------- --------- ------- ------------- --------- ----------- -------------------- ---------
   cluster                            0     0         1                                                                                           normal
[illya@slurm-client ~]$
}}
ジョブを流した後
#code(nonumber){{
[illya@slurm-client sample]$ sacct
JobID           JobName  Partition    Account  AllocCPUS      State ExitCode
------------ ---------- ---------- ---------- ---------- ---------- --------
71                 a.sh      workq                     2  COMPLETED      0:0
71.batch          batch                                2  COMPLETED      0:0
[illya@slurm-client sample]$
}}
sleepを含ませたjobを流したら
#code(nonumber){{
[illya@slurm-client sample]$ sacct
JobID           JobName  Partition    Account  AllocCPUS      State ExitCode
------------ ---------- ---------- ---------- ---------- ---------- --------
71                 a.sh      workq                     2  COMPLETED      0:0
71.batch          batch                                2  COMPLETED      0:0
72                 a.sh      workq                     2    RUNNING      0:0
72.batch          batch                                2    RUNNING      0:0
[illya@slurm-client sample]$
}}
となった.
より詳しく
#code(nonumber){{
[illya@slurm-client sample]$ sacct -o User,JobID,Partition,NNodes,Submit,Start,End,Elapsed,State -X
     User JobID         Partition   NNodes              Submit               Start                 End    Elapsed      State
--------- ------------ ---------- -------- ------------------- ------------------- ------------------- ---------- ----------
    illya 71                workq        1 2022-12-29T01:32:25 2022-12-29T01:32:25 2022-12-29T01:32:29   00:00:04  COMPLETED
    illya 72                workq        1 2022-12-29T01:33:36 2022-12-29T01:33:36 2022-12-29T01:34:25   00:00:49  COMPLETED
[illya@slurm-client sample]$
}}
「sacct -o」の中で使える項目は「sacct --helpformat」で見える
#code(nonumber){{
[illya@slurm-client sample]$ sacct --helpformat
Account             AdminComment        AllocCPUS           AllocNodes
AllocTRES           AssocID             AveCPU              AveCPUFreq
AveDiskRead         AveDiskWrite        AvePages            AveRSS
AveVMSize           BlockID             Cluster             Comment
Constraints         ConsumedEnergy      ConsumedEnergyRaw   Container
(略
[illya@slurm-client sample]$
}}


***ジョブ制限を掛けてみる [#e8884f2a]

原則として、まずユーザはどっかの「Account」に参加する必要がある。
ユーザ1人の「Account」、複数ユーザが参加した「Account」でも構わない。
この「Account」でジョブ実行に制限が掛けられる.

「Account」とその構成員は「sacctmgr list account」で確認出来て
#code(nonumber){{
[root@slurm ~]# sacctmgr list account
   Account                Descr                  Org 
---------- -------------------- -------------------- 
      root default root account                 root 
[root@slurm ~]# 
}}
となっていて、初期状態ではrootというAccountの中に所属はrootユーザのみです

っでユーザには役が定義づけられている
#code(nonumber){{
[root@slurm ~]# sacctmgr list user format=User,DefaultAccount,AdminLevel%20
      User   Def Acct                Admin 
---------- ---------- -------------------- 
      root       root        Administrator 
[root@slurm ~]#
}}
役目の項目「Admin」としては「AdminLevel」で「none」「Operator」「Administrator」の3つがあって、「Operator」はノード状態変更(down/up)、ジョブ操作(他人のジョブも)ができるけど、account や user 管理は基本できない

っで「Account」を作る
#code(nonumber){{
sacctmgr -i add account saber                   --> Account saber を削除するには「sacctmgr delete account name=saber」
sacctmgr -i add user saber Account=saber        --> ユーザsaberを削除するには「sacctmgr delete user name=saber」
}}
「-i」は「--immediate」で確認なしで実行します

っで肝心な制限ですが、ここでは「最大10個のジョブは同時実行可能にしますが、GPUも同時に10枚までしか使えない」としてみます。1つのジョブで10枚GPUを使用したら終わるまで待ち。ってな算段。
#code(nonumber){{
sacctmgr -i modify account saber set MaxJobs=10
sacctmgr -i modify account name=saber set GrpTRES=gres/gpu=10
sacctmgr -i modify user saber set Fairshare=1

(確認)
[root@slurm ~]# sacctmgr show assoc user=saber format=User,Account,MaxJobs,GrpTRES,Fairshare
      User    Account MaxJobs       GrpTRES     Share
---------- ---------- ------- ------------- ---------
     saber      saber      10   gres/gpu=10         1

[root@slurm ~]#
}}

あと「最近たくさん使った人ほど優先度が下がる仕組み」を入れる
「/opt/slurm/etc/slurm.conf」に下記を加える
#code(nonumber){{
AccountingStorageEnforce=associations,limit   # Accountに未登録のlinuxユーザは利用できないです
PriorityType=priority/multifactor             # ジョブの実行優先順位をデフォの「priority/basic」の単純な「早い者勝ち(FIFO)」ではなく複数要件で決める
PriorityWeightFairshare=1000                  # 最近たくさん計算機を使った人は後回しに、あまり使っていない人は優先的になる(値が大きいと). でも大きすぎると誰も使っていないのに使えない状態がでてくる..
PriorityWeightTRES=CPU=0,Mem=0,GRES/gpu=1000  # GPU使用枚数が少なければ優先度があがる
PriorityWeightAge=100                         # この値が大きければ大きいほど、キューの中で長く待っているジョブの優先順位があがる
PriorityDecayHalfLife=7-0                     # 過去の使用実績記録の半減期を示す。7日で使用量の影響が半減。昔使った分は忘れながら優先度が決まる
}}


***ジョブ制限を掛けてみる(その2) [#ybb509d3]

全部のAccoutに MaxJobs や GrpTRES を個別に定義するのではなく、別途用意したタグのようなもの(QOS,Quality of Service) を付けて制限してみる

一般ユーザ向けのQOS, パワーユーザ向けのQOS, 無制限のQOS とか作って Account に割り付けます

-qos-general
3同時実行で3枚までGPUを利用可能。ジョブ1つに1枚のGPUなら3ジョブまで。1ジョブに3枚使うならその1ジョブのみ
-qos-power
6同時実行で6枚までGPUを利用可能。ジョブ1つに1枚のGPUなら6ジョブまで。1ジョブに6枚使うならその1ジョブのみ。submitは20まで(実行中と待機中を合わせた数)
-qos-unlimited
制限なし

っでそのQOSを用意してみる
#code(nonumber){{
(qos-general)
sacctmgr -i add qos qos-general   MaxJobsPerUser=3  MaxTRESPerUser=gres/gpu=3    --> 「sacctmgr list qos」「sacctmgr list qos format=Name%15,MaxTRESPU,MaxJobsPU,MaxSubmitPU」削除は「sacctmgr delete qos name=qos-general」

(qos-power)
sacctmgr -i add qos qos-power     MaxJobsPerUser=10 MaxTRESPerUser=gres/gpu=10 MaxSubmitJobsPerUser=20  --> MaxSubmitPUはsubmitできる数で、実行中と待機中を合わせた数です

(qos-unlimited)
sacctmgr -i add qos qos-unlimited  --> 「Flags=OverPartQOS」は不要かも. パーティションに「MaxJobsPerUser=3 MaxTRESPerUser=gres/gpu=3」と制限が付くなら付けるが.

[確認]
sacctmgr list qos format=Name%15,MaxTRESPU,MaxJobsPU,MaxSubmitPU,Flags
           Name     MaxTRESPU MaxJobsPU MaxSubmitPU                Flags 
--------------- ------------- --------- ----------- -------------------- 
         normal                                                          
    qos-general    gres/gpu=3         3                                  
      qos-power   gres/gpu=10        10          20                      
  qos-unlimited  
}}

作ったQOSをまずは「/opt/slurm/etc/slurm.conf」のパーティション(queue名)にAllowQOSとして割り当てます
#code(nonumber){{ 
PartitionName=workq Nodes=ALL Default=YES MaxTime=INFINITE State=UP AllowQOS=qos-general,qos-power,qos-unlimited
AccountingStorageEnforce=associations,limits,qos                                      <-- これがあるとAccountに所属していて許可されていればジョブが動くが、Accountに所属していないとジョブは受け付けてくれない.
}}
ここで「scontrol reconfig」で反映させる

そして個別にアカウントを設けてそこにユーザを加えて
#code(nonumber){{
sacctmgr -i add account ac-saber  description="Account of saber"
sacctmgr -i add user saber Account=ac-saber

(確認)
sacctmgr show association  format=User,Account,QOS,DefaultQOS
}}
っで「ac-saber」にQOSの「qos-general」を割り当てる
#code(nonumber){{
sacctmgr -i modify account ac-saber set QOS=qos-general   DefaultQOS=qos-general  --> これで「srun --gres=gpu:3 --pty bash」は通るけど「srun --gres=gpu:4 --pty bash」は通らない

(代わりにQOSの「qos-power」を割り当てるなら
sacctmgr -i modify account ac-saber set QOS=qos-power     DefaultQOS=qos-power 

(代わりにQOSの「qos-power」を割り当てるなら
sacctmgr -i modify account ac-saber set QOS=qos-unlimited DefaultQOS=qos-unlimited 
}}
とします

QOSに優先度を設けられる
#code(nonumber){{
sacctmgr modify qos qos-general   set Priority=100
sacctmgr modify qos qos-power     set Priority=200
sacctmgr modify qos qos-unlimited set Priority=300
}}
でPriorityの数字が高い方が優先される. でも実際にはslurm.confでのPriorityWeightQOSの値やジョブの待ち時間、フェアシェアらの変数も入って優先が決まるみたい
1

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS