ユーザーログインの Jira Stats 記録
プラットフォームについて: Data Center - この記事は、Data Center プラットフォームのアトラシアン製品に適用されます。
このナレッジベース記事は製品の Data Center バージョン用に作成されています。Data Center 固有ではない機能の Data Center ナレッジベースは、製品のサーバー バージョンでも動作する可能性はありますが、テストは行われていません。サーバー*製品のサポートは 2024 年 2 月 15 日に終了しました。サーバー製品を利用している場合は、アトラシアンのサーバー製品のサポート終了のお知らせページにて移行オプションをご確認ください。
*Fisheye および Crucible は除く
環境
Jira Data Center 8.22 (8.20.8) and later
はじめに
In Jira 8.22 (backported to 8.20.8) we have provided some bug fixes and performance improvements to the user login process and closed the following public issues:
JRASERVER-70690
Bug-Fix
We’re adding “unique” constraint to idx_mem_dir_parent_child
index of cwd_membership
table. This will improve data consistency and eliminate rare user login issues. Jira will perform this work automatically during the upgrade, just keep in mind that it might take some additional time.
JRASERVER-71483
Bug-Fix
User login was occasionally disrupted by the inconsistent state of caches across the cluster. We’ve made the process independent from the cache which will prevent any issues with logging in to the instances.
JRASERVER-70468 & JSWSERVER-20844
Performance-Fix
このリリースにはパフォーマンスの修正が含まれます。これはベーシック認証経由で Jira に頻繁にログインする bot を主な対象にしています。
Jira is now delaying storing user login counters and timestamps. Because of that the performance of instances will improve but the latest information might be not available immediately. The information displayed is eventually consistent with a maximum delay of 30 seconds.
Authentications are now cached inside Jira for 15 minutes or until first unsuccessful attempt. This will improve the performance and reduce the load on authenticating external directories.
パフォーマンスの結果
テスト用のセットアップは次のとおりです。
8 ノード
50,000 ユーザーが含まれる LDAP
ノードは jmeter 経由のベーシック認証で REST トラフィックを生成
最大 30 分の実行テスト
これまで (Jira 8.20) | 修正後 (Jira 8.22.0) | |
---|---|---|
テスト中のユーザー ログインのアクション数 | 975_394 (1M) | 16_045_878 (16M) |
ユーザー ログインの平均時間 | 282 ミリ秒 | 17 ミリ秒 |
ユーザー ログインの 99p 時間 | 1_511 ミリ秒 | 38 ミリ秒 |
ユーザー ログインの最大時間 | 10_521 ミリ秒 | 5_082 ミリ秒 |
DB 使用率 | 高 | 低 |
リモート ディレクトリ通信 | 高 | 低 |
ノード間通信 | 高 | 低 |
Jira Stats
During this work, we have added several Jira Stats related to user login which can be used to monitor user-login performance.
[JIRA-STATS] [LOGIN-STATS]
In these stats, we can see which can compare local authentication requests to remote authentication requests.
- settings - 構成パラメーター
- topUsers - 認証をリクエストしている上位のユーザーとカウンター。ここでは、ユーザー big_mac がこのノードで (ノードの起動以降: duration=PT2H53M18.768S) 9_648 回の認証を行っています。
- authCacheGetOrLoadInMillis
- "count": 3205 - 認証回数 (ローカルまたはリモート)
- "avg": 21 - 認証の平均時間 (ミリ秒)
- authSuccessfulInMillis
- "count": 69 - リモート認証の成功数
- "avg": 904 - リモート認証の平均成功時間 (ミリ秒)
- authFailedInMillis
- "count": 3205 - リモート認証の失敗数
- "avg": 64 - リモート認証の平均失敗時間 (ミリ秒)
- authCacheInvalidation: 42 - number of cache invalidations per user (key); cache can be invalidated on following events: user log-out, user credential updated, user renamed, user profile updated; this should happen rarely compared to the total number of authentications (authCacheInvalidation << authCacheGetOrLoadInMillis.count)
ログインの stats の例
[JIRA-STATS] [LOGIN-STATS] total stats: duration=PT2H53M18.768S, statsOverhead=n/a, data=
{
"settings": {
"legacyMode": false,
"authCacheExpireMin": 15,
"authCacheMaxSize": 10000,
"passwordEncoder": "atlassian-sha1"
},
"topUsers": {
"big_mac": 9648,
"s_wiseman": 3742,
"": 3137,
"backbone_sync_bot": 1606,
"bruce_lee": 26,
"serv_sef_rep_bot": 14,
"server_jirasync_bot": 5,
"dc_jira_bot": 4
},
"authSuccessfulInMillis": {
"count": 69,
"min": 177,
"max": 16880,
"sum": 62425,
"avg": 904,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 0,
"1000": 65,
"5000": 2,
"9223372036854775807": 2
}
},
"authFailedInMillis": {
"count": 3205,
"min": 15,
"max": 1536,
"sum": 205535,
"avg": 64,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 2971,
"1000": 228,
"5000": 6
}
},
"authCacheGetOrLoadInMillis": {
"count": 18223,
"min": 0,
"max": 16881,
"sum": 389061,
"avg": 21,
"distributionCounter": {
"1": 14783,
"10": 2,
"100": 2957,
"1000": 456,
"5000": 19,
"9223372036854775807": 6
}
},
"authCacheInvalidation": 42,
"encodePasswordInMillis": {
"count": 69,
"min": 0,
"max": 7,
"sum": 7,
"avg": 0,
"distributionCounter": {
"0": 68,
"1": 0,
"5": 0,
"9223372036854775807": 1
}
},
"validatePasswordInMillis": {
"count": 14933,
"min": 0,
"max": 10,
"sum": 21,
"avg": 0,
"distributionCounter": {
"0": 14930,
"1": 0,
"5": 1,
"9223372036854775807": 2
}
}
}
[JIRA-STATS] [LOGIN-STORE-STATS
]
These are stats that describe the performance of the delayed login store update, i.e. user login counters, and timestamps.
Login store data:
"loginInfo":
{
"failedLoginCount": 14959,
"loginCount": 643073,
"lastFailedLoginTime": "2022-01-17T12:37:05.662+0000",
"previousLoginTime": "2022-01-17T13:31:52.253+0000"
}
ログイン ストアの stats の例
[JIRA-STATS] [LOGIN-STORE-STATS] total stats: duration=PT3H33M53.089S, statsOverhead=n/a, data=
{
"settings": {
"legacyMode": false,
"flushIntervalInSeconds": 30
},
"recordLoginAttemptSuccessfulInMillis": {
"count": 965,
"min": 0,
"max": 295,
"sum": 3066,
"avg": 3,
"distributionCounter": {
"1": 877,
"10": 0,
"100": 87,
"1000": 1,
"5000": 0
}
},
"recordLoginAttemptFailedInMillis": {
"count": 2,
"min": 25,
"max": 26,
"sum": 51,
"avg": 25,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 2,
"1000": 0,
"5000": 0
}
},
"updateLastLoginTimeInMillis": {
"count": 1349,
"min": 0,
"max": 151,
"sum": 14750,
"avg": 10,
"distributionCounter": {
"1": 827,
"10": 1,
"100": 520,
"1000": 1,
"5000": 0
}
},
"resetFailedLoginCountInMillis": {
"count": 0,
"min": 0,
"max": 0,
"sum": 0,
"avg": 0,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 0,
"1000": 0,
"5000": 0
}
},
"getOrLoadLastKnownLoginInfoInMillis": {
"count": 1932,
"min": 0,
"max": 5,
"sum": 89,
"avg": 0,
"distributionCounter": {
"1": 1929,
"10": 3,
"100": 0,
"1000": 0,
"5000": 0
}
},
"delegateRecordLoginAttemptSuccessfulInMillis": {
"count": 88,
"min": 29,
"max": 295,
"sum": 3062,
"avg": 34,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 87,
"1000": 1,
"5000": 0
}
},
"delegateRecordLoginAttemptFailedInMillis": {
"count": 2,
"min": 25,
"max": 26,
"sum": 51,
"avg": 25,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 2,
"1000": 0,
"5000": 0
}
},
"delegateUpdateLastLoginTimeInMillis": {
"count": 521,
"min": 19,
"max": 149,
"sum": 14692,
"avg": 28,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 520,
"1000": 1,
"5000": 0
}
},
"delegateResetFailedLoginCountInMillis": {
"count": 0,
"min": 0,
"max": 0,
"sum": 0,
"avg": 0,
"distributionCounter": {
"1": 0,
"10": 0,
"100": 0,
"1000": 0,
"5000": 0
}
},
"invalidateLastKnownLoginInfoCache": 940,
"flushDataToDBInMillis": {
"count": 422,
"min": 0,
"max": 248,
"sum": 8939,
"avg": 21,
"distributionCounter": {
"1": 250,
"10": 0,
"100": 154,
"1000": 18,
"5000": 0
}
},
"flushUserAttemptsInMillis": {
"count": 2,
"min": 0,
"max": 0,
"sum": 0,
"avg": 0,
"distributionCounter": {
"1": 2,
"10": 0,
"100": 0,
"1000": 0,
"5000": 0
}
},
"flushRecordedSuccessfulLoginAttemptsMillis": {
"count": 90,
"min": 0,
"max": 37,
"sum": 933,
"avg": 10,
"distributionCounter": {
"1": 59,
"10": 0,
"100": 31,
"1000": 0,
"5000": 0
}
},
"flushLastLoginTimesMillis": {
"count": 519,
"min": 0,
"max": 217,
"sum": 7914,
"avg": 15,
"distributionCounter": {
"1": 222,
"10": 0,
"100": 296,
"1000": 1,
"5000": 0
}
}
}
[JIRA-STATS] [GROUP-DAO-STATS]
ログイン中のユーザーおよびグループ キャッシュの更新に関連する stats です。
The interesting part of this stats in the context of JRASERVER-71483 is that when we are unable to find a request group in the group cache we assume the cache can be corrupted and reload this group from cache.
- findByNameOrNullCacheHit - キャッシュで見つかったグループのカウンター
- findByNameOrNullCacheMiss - キャッシュで見つからなかったグループのカウンター
- findByNameOrNullDBHitInMilliseconds - キャッシュで見つからなかったが DB で見つかった (それによってキャッシュを修正した) グループのタイマーとカウンター
- findByNameOrNullDBMissInMilliseconds - キャッシュで見つからず、DB でも見つからなかったグループのタイマーとカウンター
[JIRA-STATS] [GROUP-DAO-STATS] total stats: duration=PT3H5.678S, statsOverhead=n/a, data=
{
"eager": false,
"findByNameOrNullSkipRefreshOnNull": false,
"findByNameOrNull": 2680342,
"findByNameOrNullCacheHit": 2671125,
"findByNameOrNullCacheMiss": 0,
"findByNameOrNullDBHitInMilliseconds": {
"count": 0,
"min": 0,
"max": 0,
"sum": 0,
"avg": 0,
"distributionCounter": {
"1": 0,
"10": 0,
"50": 0,
"100": 0,
"500": 0,
"1000": 0,
"5000": 0,
"10000": 0
}
},
"findByNameOrNullDBMissInMilliseconds": {
"count": 0,
"min": 0,
"max": 0,
"sum": 0,
"avg": 0,
"distributionCounter": {
"1": 0,
"10": 0,
"50": 0,
"100": 0,
"500": 0,
"1000": 0,
"5000": 0,
"10000": 0
}
},
"findGroupsGenericValueInMilliseconds": {
"count": 0,
"min": 0,
"max": 0,
"sum": 0,
"avg": 0,
"distributionCounter": {
"1": 0,
"10": 0,
"50": 0,
"100": 0,
"500": 0,
"1000": 0,
"5000": 0,
"10000": 0
}
},
"groupAddFailed": 0,
"groupAddFailedUpdateSuccessful": 0,
"groupAddFailedUpdateFailed": 0
}