はじめに
認証認可を担うKeycloakというソフトウェアを開発モード(start-dev)で動作させた際にユーザ数がどの程度パフォーマンスに影響するのかを簡易的に調査しました。具体的にはユーザ数が以下の場合に「ユーザ数の取得」「具体的なユーザの検索」をAPI経由で行い、時間の計測を行っています。
- 50
- 500
- 5,000
- 50,000
環境情報
- Red Hat Enterprise Linux : 9.3 (Plow)
- Memory : 4GB
- CPU : 1 socket x 2 cores x 1 threads
- keycloak-22.0.8
調査方法
レルムを指定した上で同レルムに属するユーザ情報を取得します。尚、スクリプトを用意して事前にユーザは作成済みとします。
ユーザ数を出力
GET /admin/realms/<REALM_NAME>/users/count
ユーザ情報を出力
GET /admin/realms/<REALM_NAME>/users
検証結果
50ユーザの場合
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users/count -H "Authorization: Bearer "$AT 50 real 0m0.013s user 0m0.003s sys 0m0.004s
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users?max=100000 -H "Authorization: Bearer "$AT | jq -r '.[] | select(.username == "test10") | .id' ... 8c0daa0a-b1b3-47f1-a4a9-dd97ed2d842f real 0m0.104s user 0m0.089s sys 0m0.010s
500ユーザの場合
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users/count -H "Authorization: Bearer "$AT 500 real 0m0.011s user 0m0.004s sys 0m0.004s
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users?max=100000 -H "Authorization: Bearer "$AT | jq -r '.[] | select(.username == "test10") | .id' ... 8c0daa0a-b1b3-47f1-a4a9-dd97ed2d842f real 0m1.495s user 0m0.084s sys 0m0.018s
5,000ユーザの場合
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users/count -H "Authorization: Bearer "$AT 5000 real 0m0.031s user 0m0.004s sys 0m0.004s
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users?max=100000 -H "Authorization: Bearer "$AT | jq -r '.[] | select(.username == "test10") | .id' ... 8c0daa0a-b1b3-47f1-a4a9-dd97ed2d842f real 1m32.077s user 0m0.140s sys 0m0.028s
50,000ユーザの場合
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users/count -H "Authorization: Bearer "$AT 50000 real 0m0.158s user 0m0.003s sys 0m0.005s
$ time curl -k -X GET --silent --no-progress-meter http://localhost:8080/admin/realms/master/users?max=100000 -H "Authorization: Bearer "$AT | jq -r '.[] | select(.username == "test10") | .id' ... 8c0daa0a-b1b3-47f1-a4a9-dd97ed2d842f real 5m0.202s user 0m0.173s sys 0m0.053s
検証結果考察
カウントのAPIに関してはユーザ数に対して1秒以内で応答しているため、実運用を考慮しても大きな懸念はありません。
50 | 0m0.013s |
500 | 0m0.011s |
5000 | 0m0.031s |
50000 | 0m0.158s |
一方でユーザ情報の取得は出力情報が大きいからか無視できない程度の時間がかかっています。
50 | 0m0.104s |
500 | 0m1.495s |
5000 | 1m32.077s |
50000 | 5m0.202s |
取得した全ユーザの情報を元に他のAPIを利用していくような形を考慮すると、さらに時間はかかります。
終わりに
「ユーザ数が数万人になってくるとデフォルトではパフォーマンスに影響が出てくる」という話があったので、実際に実機上でAPIを叩いてみました。API経由ではなくDBに直接SQLを発行するとより高速に結果が取得できる可能性はありますが、API経由でのユーザ操作が推奨されているためSQLを利用する判断は難しいとも思いました。
以上、ご参考になれば幸いです。