LoginSignup
4
1

More than 3 years have passed since last update.

sessionアラートが倒せない

Last updated at Posted at 2019-12-08

まえがき

おはこんばんにちは。
株式会AncarのWebエンジニアをしている、unaと申します。
この度は「株式会Ancar ~Advent Calendar 2019~」 8日目を担当させていただきます。

弊社は安心・安全な移動体験を届けるをモットーに

当記事では、そのサービス運用時に発生したWarningの対処を共有させていただきます。

3行まとめ

  • PHP Warning: SessionHandler::read(): Unable to clear session lock recordが3件/日ぐらい発生
  • どうやらセッションロック周りが怪しい → n度修正 → 鳴り止まないアラート
  • memcachedからredisを移行させた結果、直った(嬉しい

セッションアラートが3件/日

mackerelというサーバー管理システムから、頻繁にアラートがあがるようになった。
内容はPHP Warning: SessionHandler::read(): Unable to clear session lock record
アラートが増加している上に、SEOにも影響が出ている可能性が高まってきたため、対処に動いた。

当時の環境

  • PHP7.1
  • memcached3.0.3(elasticache)
  • nginx/1.10

原因はセッションロックにあり....?

アラート内容でグーグル先生にきいてみたところ、セッションロック周りが怪しいと判明。

セッションデータは、同時書き込みを防ぐためにロックされるため、 ある時点であるセッションの処理ができるスクリプトは、1つだけです。
https://www.php.net/manual/ja/function.session-write-close.php

つまり、セッションロックがかかっている状態で、セッションに再度書き込みをし、エラーとなっていると推測。

また、先のアラートが発生しているのは本番サーバーのみなので、テストサーバーと比較した。
本番サーバー
image.png
テストサーバー
image.png
はい、ギルティ!!
memcached.sess_lockのタイムがテストサーバーは短い!!
状況証拠は揃えた、いまからガサ入れや!!

意気揚々と/etc/php/7.1/fpm/conf.d/25-memcached.iniの中でsess_lockをテストサーバーと同じタイムに設定。
さらばアラートよ....(と思っていた時期が私にもありました)

結果、アラート発生....
ここから私とアラートの熾烈な戦い(ワンサイドゲーム が始まる。

ロックタイムだけでは不十分.....?

先の戦いでは少し先走りすぎた。
泥臭く地取りを行っていこうぜ と決意し、issueを漁り始めた。
こちらのissueなどを参考に設定をこねた。

session.lazy_write = Off;
memcached.sess_lock_wait_min = 100;
memcached.sess_lock_wait_max = 150;
memcached.sess_lock_retries = 30;
memcached.sess_lock_expire = 45;

しかし、元気よくアラートは鳴っている。
むしろ、少し増えた。
そうか、慈悲はないのか....

issueを漁り始めて気づいたのは、この問題は意外と根深いということ。
先の修正で直るケースもあれば、逆もしかり。
PHP7.1以前とmemcachedの組み合わせで多発しており、PHPのバージョン問題である可能性も高い。

実際にn度目の設定変更を通して、憎きアラートへの対処は適切ではないと痛感している。
有効打と思われるのは下記だ。

redisへの移行

サービスへの影響を考えるとPHPの更新は、作業・リスクがリターンに見合わんので断念。
結果、redis移行へと路線変更を決意。
同時に、憎むべき対象から宿敵(ライバル へ昇格したアラート氏。

移行の懸念点

  • redis移行で問題が本当に解決するのか
    • 打ち手: redisにして解決したソースあり
    • 打ち手: 本番2号機サーバーで確認
  • 移行後にmemcachedに戻れるのか
    • 打ち手: エンドポイントをredisに向けて対応(memcachedの設定を上書き)
    • 打ち手: テスト環境で双方向(memcached ↔ redis)の行ききをし、後戻りできることを確認
  • redis移行で他に問題が起きないのか
    • 打ち手: テスト環境で確認
    • 打ち手: 本番2号機サーバーで検証

影響範囲が大きいため、打ち手と手順を考えて実行した。
1. テスト環境で実装した後、動作確認。
2. 本番環境の冗長構成のサーバーを間借りして、動作確認。
3. 本番に完全移行。

redis移行の手順

残念ながら、ElastiCache上でMemcachedからRedisへの自動移行はサポートされていない
https://aws.amazon.com/jp/elasticache/faqs/

  1. elasticacheでredisを作成
  2. ELBのセキュリティグループにredisポート(6379)を追加
  3. サーバー内部でpecl install redisを実行
  4. /etc/php/7.1/fpm/php.iniextension=redis.soを追記
  5. /etc/php/7.1/fpm/php.inisession.save_handler, session.save_pathを追記
session.save_handler = redis
session.save_path = ****.cache.amazonaws.com:6379

6 . phpinfoで確認
ちゃんとサーバーに反映されているか、phpinfoで確認
image.png
image.png

沈黙したアラート

先の懸念を潰しながらredisの完全移行を行い数日。
未だ、宿敵は現れず....
数時間に1回はひょっこりするやつが、数日も顔を出さないとは....
これにて、勝利宣言をさせていただく。

余談

アラート氏を監視している際にapach bench(以降ab でmemcachedとredisの負荷テストを行った。
負荷テストを行う環境で結果はかわるので、いくつか場所を変えて行う必要あり。
また、AWSはペネトレーションテストの事前申請がなくなったらしい。

Macはabが標準搭載されているが、サーバーで行う場合はインスコ要。
sudo apt install apache2-utils //abのパッケージのみを入れる

ab負荷テスト実行

redisの方が速い...!!

1秒間のリクエスト処理比較 memcached redis
ab -n 1000 -c 100 //10回×100人 41.93/sec 41.53/sec
ab -n 10000 -c 100 //100回×100人 42.79/sec 41.65/sec

推測

memcached・redisにセルフDoSさながらの負荷をかけてもアラートが上がらなかった。
以上から、sessionが増えれば発生するアラートではないということがわかる。
総数の増大による発生ではなく、セッションの書き込みができないことによるものだからか?
サイトのPV数とセッションのアラート増加は時期的に関連しているように見えるが、根っこが未解明のまま。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1