PHP7で、APCuを使っている時に困ったことがあったので、ご質問させていただきます。
■環境
・CentOS 7
・Apache 2.4.6
・PHP 7.0.3
・APCu 5.1.3
APCuを使ってみようと、リファレンスを見ながら自前でWebアプリケーション内の情報をapc_storeで保存したり、apc_fetchで取り出したりするところまでは来ました。
具体的な使い方は、MySQLから取得したデータのキャッシュのみにしているのですが、MySQL側の情報が更新された時にはAPCuのキャッシュもクリアするように、UPDATE後にapc_clear_cacheするようにしていました。
※UPDATEした情報は何種類かのクエリで呼び出されるため、UPDATE直後に呼び出し時と同じSELECTをかけてstoreしなおすのではなく、クリアしてしまう方が簡単だと思ってそうしています。
すると、下記のようなエラーログが発生しました。
apache
1*** Error in `/usr/sbin/httpd': double free or corruption (fasttop): 0x00007f73250a1a50 *** 2======= Backtrace: ========= 3/lib64/libc.so.6(+0x7d023)[0x7f7323053023] 4/etc/httpd/modules/libphp7-zts.so(zend_hash_apply+0x11b)[0x7f7316e3f99b] 5/etc/httpd/modules/libphp7-zts.so(zend_ini_deactivate+0x46)[0x7f7316e48c36] 6/etc/httpd/modules/libphp7-zts.so(+0x2f64a5)[0x7f7316ec24a5] 7/etc/httpd/modules/libphp7-zts.so(+0x2f6f6e)[0x7f7316ec2f6e] 8/usr/sbin/httpd(ap_run_handler+0x40)[0x7f7324b17270] 9/usr/sbin/httpd(ap_invoke_handler+0x69)[0x7f7324b177b9] 10/usr/sbin/httpd(ap_internal_redirect+0x5c)[0x7f7324b2b5fc] 11/etc/httpd/modules/mod_rewrite.so(+0x4dec)[0x7f731e0cddec] 12/usr/sbin/httpd(ap_run_handler+0x40)[0x7f7324b17270] 13/usr/sbin/httpd(ap_invoke_handler+0x69)[0x7f7324b177b9] 14/usr/sbin/httpd(ap_process_async_request+0x20a)[0x7f7324b2bb3a] 15/usr/sbin/httpd(+0x50870)[0x7f7324b28870] 16/usr/sbin/httpd(ap_run_process_connection+0x40)[0x7f7324b20840] 17/etc/httpd/modules/mod_mpm_event.so(+0x69f2)[0x7f731bb3e9f2] 18/lib64/libpthread.so.0(+0x7dc5)[0x7f73235a2dc5] 19/lib64/libc.so.6(clone+0x6d)[0x7f73230cc28d] 20======= Memory map: ======== 217f71e7a00000-7f71e7c00000 rw-p 00000000 00:00 0 227f71e7d62000-7f71e7e00000 rw-p 00000000 00:00 0 237f71e7e00000-7f71e8a00000 rw-p 00000000 00:00 0 247f71e8a26000-7f71e8c00000 rw-p 00000000 00:00 0 257f71e8c00000-7f71e9800000 rw-p 00000000 00:00 0 267f71e9826000-7f71e9a00000 rw-p 00000000 00:00 0 27 28 : 29 : 30#省略 31 : 32[Mon Mar 14 22:40:03.390429 2016] [core:notice] [pid 20017:tid 140132513228864] AH00052: child pid 13763 exit signal Aborted (6)
調べたところ、メモリの二重解放のエラーだそうで、おそらくAPCuをクリアするところで同時実行などがされてしまっているのではと思いました。
そこで、クリアを任意でせずに、UPDATE時はその日時を別途記録し、apc_fetchの前に取り出したい値のLast Modifiedの値と比較して、古い場合はデータを取り直してstoreすれば良いのではと考えました。
しかし、apc関数の中には、特定のキーのLast Modifiedを取得するものは無いようです。
php
1//$acp_key_name:取得したい値のキー名 2function get_apc_modified( $acp_key_name ) { 3 $userCache = apc_cache_info('user'); 4 foreach ( $userCache['cache_list'] as $k => $cl ) { 5 if ( $cl['info'] === $acp_key_name ) { 6 return $cl['mtime']; 7 } 8 } 9}
たとえば、こんな関数で任意のキーの値のLast Modifiedを取得できるのかなと思いましたが、
常に全キャッシュのループを回してチェックするのは、キーの総数が増えていくと重くなっていってしまう気がしています。
APCキャッシュの値を更新したいときは、どのようにするのが普通なのでしょうか。
APCについては、インストールするところまでの情報はよく見つかるのですが、その後の使い方についてはあまり見かけなかったので、そもそもの使い方のお作法についても、もしアドバイスいただければ幸いです。
回答1件
あなたの回答
tips
プレビュー