memcached

Fatal error: Allowed memory size of 402653184 bytes exhausted (tried to allocate 4294964625 bytes)

phpを5.6.27から5.6.28にあげた際に以下のerrorが発生しました。

Fatal error: Allowed memory size of 402653184 bytes exhausted (tried to allocate 4294964625 bytes) in /home/ap2/public_html/ero/toukei_kaiseki/index.php on line 20

line 20には
session_start();
と書いてあります。

コマンドラインから実行しても以下のとおりでした。

$ php -r "session_start();"
PHP Fatal error:  Allowed memory size of 402653184 bytes exhausted (tried to allocate 4294965058 bytes) in Command line code on line 1

Fatal error: Allowed memory size of 402653184 bytes exhausted (tried to allocate 4294965058 bytes) in Command line code on line 1

環境は以下のとおりです。

CentOS 6
php56w-5.6.28
php56w-pecl-memcache-3.0.8-2

結論から書くと、php56w-pecl-memcache-3.0.8をやめてphp56w-pecl-memcached-2.2.0にしました。


session.save_handler をmemcachedからfileにするとerrorが消えたので、memcached周りの問題だと思いました。
phpを5.6.27に戻すとerrorが消えるので5.2.28の問題かと思いました。

verを元に戻すには、以下のとおりyum downgradeコマンドを使いました。
依存しているパッケージをすべて選択しています。
# yum downgrade php56w php56w-common php56w-cli php56w-snmp php56w-process php56w-xmlrpc php56w-pdo php56w-soap php56w-opcache php56w-ldap php56w-devel php56w-xml php56w-mbstring php56w-gd php56w-pgsql

標題の文句でググると以下のBug報告がひっかかりました。
https://bugs.php.net/bug.php?id=73497
https://bugs.php.net/bug.php?id=73539

パッチをあてるか、
memcacheの3.0.8のリリースを待たないといけないようでしたので、同じ機能を持つ
memcachedに乗り換えることにいたしました。

https://bugs.php.net/bug.php?id=73497によるとThis bug can also be reproduced with php 7.0.13 and memcache 3.0.9-devとのことです。

PHPのセッションデータの保存先をmemcachedにする場合の設定について

以下の文書は各ソフトが以下のverのものです。
  • memcached-1.4.15-2.el6.remi.x86_64
  • php55w-pecl-memcache-3.0.8-2.w6.x86_64

実現したいことは以下の通りです。

192.168.0.1と192.168.0.2の両方にPHPのセッションデータを保存して、どちらかが落ちても、どちらに接続してもセッションが保たれるようにしたい。


実現したい理由は以下の通りです。

ErogameScapeのPHPのセッションの保存先は各サーバーのHDDのみでした。
セッションの保存先が各サーバーのHDDのみですと以下の問題を抱えます。
  1. ユーザーさんからのサーバーの接続先を切り替えた場合、切り替え先はユーザーさんのセッション情報を持っていないので、ユーザーさんがログインした状態だった場合にサーバーを切り替えると強制的にログアウトされた状態になる。具体的には長文感想を1時間かけて書いて登録ボタンを押したら、ログイン画面に飛ばされる等の被害がでます。
  2. 高負荷時、または定常的にロードバランスしたい場合、あるユーザーさんが最初に接続したサーバーが192.168.0.1、次に接続した場合は192.168.0.2だった場合、セッションが引き継げないためログアウトした状態になる。
    ※ロードバランスをIPアドレスベースでやればIPアドレスがかわらない限り問題ないじゃないか!と思う方もいらっしゃると思いますが、スマホ等からの接続の場合、接続のたびにIPアドレスがころころかわります。
    結果、1.で書いた具体例が起こる可能性があります。
現用系のサーバーから待機系サーバーに切り替えると各ページのキャッシュがないため2時間ほど高負荷となることが確認されました。この対策として、常にキャッシュを更新し続けるのがベストであると思いました。
常にキャッシュを更新し続けるには、定常的にロードバランスするのが手間がかからないなと思いました。

定常的にロードバランスするため、192.168.0.1と192.168.0.2の両方にPHPのセッションデータを保存することとしました。
 

memcachedのインストールと/etc/php.iniと/etc/php.d/memcache.iniの設定について

以下の文書がよいと思います。

はまったのは
;Redundancy : When enabled the client sends requests to N servers in parallel
;memcache.redundancy=1
;memcache.session_redundancy=2
memcache.session_redundancyを3と設定しないといけないことでした。
 
2のままだと、
session.save_path="tcp://192.168.0.2:11211,tcp://192.168.0.1:11211"
と書いても、192.168.0.1の方にしかセッションデータが記録されません。

ちなみに
session.save_path="tcp://192.168.0.2:11211"
と書くとちゃんと192.168.0.2にセッションデータが書き込まれます。

memcache.session_redundancyのパラメータが追加されたのはphp-pecl-memcacheのVerが3系になってからですので、3系を使う場合は気をつけましょう…

ここらへんは英語になりますが
に書いてあります。
※ぐぐっても私と同じようにはまった日本語の文書が全然なくて(やっぱり3系はbetaだから使われていないのでしょうか…)解決に3時間くらいかかりました…プログラマーに必要な言語は英語だとよく言ったものだと思います…

記事検索