session_startでWarningが出る
[PHP] E_WARNING: session_start(): Unable to clear session lock record
[PHP] E_WARNING: session_start(): Failed to read session data: memcached
というアラートがたまに発生する。(上記2つはセットで吐かれる)
session_start()でセッション復元時に発生している。
環境
- Apache 2.4.6
- php 7.1.14
- memcached 1.4.24 (ElastiCache)
原因(推測)
ここにあるように
セッションデータは、同時書き込みを防ぐためにロックされるため、 ある時点であるセッションの処理ができるスクリプトは、1つだけ
らしいので、ロック取得できなかった場合に発生しているっぽい。
参考)該当箇所のMemcachedソース
改善策
ロック取得リトライ回数(memcached.sess_lock_retries)はデフォルト5。
リトライ回数を1から10これを1ずつ増やしてWarning発生回数が下がるか確認してみる。
確認コマンドは、 ab -n 1000 -c 4 -H'Cookie: 〜'https://〜〜
で。
設定は、ini_set('memcached.sess_lock_retries', 10);
をコードに挿入
sess_lock_retries | ErrorCount | Req/Sec |
---|---|---|
1 | 22 | 9.33 |
2 | 10 | 7.57 |
3 | 4 | 7.33 |
4 | 2 | 8.00 |
5 | 0 | 7.52 |
6 | 0 | 6.90 |
7 | 2 | 7.42 |
8 | 0 | 7.53 |
9 | 0 | 6.44 |
10 | 0 | 6.10 |
結論
sess_lock_retriesをデフォルトの5から10に変えてみると発生が抑えられた。
その代わり、スループットは落ちてる。。けど、機能要件優先で。
PHP Warning: Unknown: Unable to clear session lock record in
↑ 他の対処法(リトライ回数増やすのではなく、リトライ間隔で改善する方法)もあります。ご参考までに
ちなみに、memcached.sess_lock_retriesはなぜがphpinfo()には出てこない。
なぜだろ?
追記(2018/03/07)
さらに改善するために、リトライ回数と間隔、合わせ技でチューニングした結果、効果あった。
最終的な設定値(php.ini)の内容は以下。
[memcached]
memcached.sess_lock_wait_min = 100;
memcached.sess_lock_wait_max = 1000;
memcached.sess_lock_retries = 30;
ちなみにデフォルト値は以下。
memcached.sess_lock_wait_min = 1000;
memcached.sess_lock_wait_max = 2000;
memcached.sess_lock_retries = 5;
そもそもデフォルトのロック待ちが1秒ってのが長いと思う。
チューニングの結果、システム全体の平均レスポンスタイムも10%ほど改善した。(当社比)