Twitterのトレンドランキングサイトの「ツイータン」にPHPのfatal errorがでておりました。

表示されたエラー内容を見ると、「Allowed memory size of *** bytes exhausted」とあり、どうやらPHPのメモリエラーが発生しているようです。久々に見た気がします。

被リンク稼ぎにディレクトリ型検索エンジンが重宝されていた2000年初頭は、ディレクトリ型検索エンジンdtnに猛烈なアクセスが訪れて、PHPがエラーを吐くといったことがチョクチョクありましたが、この記事に辿り着いた方も存在すら知らない「ツイータン」ですので、アクセス数で落ちるといったことがあるはずもないので、何かしらPHPのバグだろうとは感じました。

エラーログから原因を調べてみると、DBに貯めているトレンドハッシュタグ、キーワードのレコード数を出していたあたりでエラーがでていたので、DBからPDOで全権取得するあたりでmemory_limitの容量を超えたということのようでした。レコード数が300万件を超えるほどたまっておりましたので、PHP側での処理には無理があるということのようです。

ということで、わざわざPHP側に持ってきてrowCount()をするなんてことはやめて、素直にSQL側でCOUNTするということで解決をいたしましたので、この記事ではその流れをご紹介したいと思います。




PHPのメモリ不足エラーが発生

Twitterのトレンドランキングを月別にご紹介しているサイト「tweetan」にPHPのfatal errorがでていました。

エラーを見るとAllowed memory size of *** bytes exhaustedとあるので、どうやらPHPのメモリエラーが発生しているようです。久々に見た気がします。エラーはtwitter APIから取得したログの全件数をカウントしている箇所ででていたので、DBからPDOで取得したデータ処理でmemory_limitの容量を超えたということのようです。

TwitterトレンドランキングサイトでPHPのメモリ不足エラーが表示されている
Twitterトレンドランキングサイトのデータ件数取得でエラー発生

memory_limitの容量

phpinfoで今のmemory_limitを確認してみたところ128MB設定になっていました。128MBあっても足りないというのも凄い感じですが、fatal errorを回避するために取り急ぎ倍に増やすことにしました。

DirectiveValue
memory_limit128M
レンタルサーバの規定値のまま

php.iniで容量アップしておく

VPSサーバでもないレンタルサーバですので、php.iniは管理画面からの設定となります。256MBに増やしたところ無事PHPが動くようにはなりました。

DirectiveValue
memory_limit256M
php.iniでmemory_limitを256Mに変更

データ件数取得処理でエラー

PDOのrowCount()でレコード数取得

エラーが発生していた全レコード件数のカウント処理を確認してみたところ、SELECT文で全件取得後にPDOのメソッドrowCount()を使ってPHP側でカウント処理をかけておりました。

一昨年末に10分おきにtwitter APIからトレンドデータを収集し始めたものの、当時はこれを年単位で継続するとどうなるかも全く想像せず作っていたので、こんな感じでやっつけてしまっていました。さすがに300万レコードを超えるとこれでは無理があるようです。

$SQL = 'SELECT id FROM log';
$prepare = $db->prepare($SQL);
$prepare->execute();
$count_log = $prepare->rowCount();

レコード数はSQLのcountで取得に変更

件数カウントをするためだけに300万件以上の結果セットをfetchしてPHP側で配列保持するのは意味がないので、おとなしくMySQL側でカウントをすることにしました。当然ながらレスポンスもこの方が劇的に良くなったので早く変えておけばよかったです。

$SQL = 'SELECT count(id) AS cnt FROM log';
$prepare = $db->prepare($SQL);
$prepare->execute();
$rows = $prepare->fetch();
$count_log = $rows["cnt"];

おわりに

先日の記事でもご紹介したように、2020年の一年間にtwitter APIで収集したデータ件数は2,500,000レコード程になりましたが、このレコード数程度であればMySQLは全く問題ないものの、使い方には気を付けないとダメということでした。

dtn.jp検索クエリログや泉アンテナの記事リストなど、長年やってきているだけに100万レコード超えのテーブルがいくつか他にもありますので、同じようにレコード数が増える想定もないままPHPで処理しているところがないか早めに見直しをしようと思いました。

ABOUT dtn.jp

この運営ブログをみてdtn.jpの運営サイトに興味をお持ちになった方は下記のリンク集からサイトをご参照ください。PHP・SQL・JS・HTML・CSSや様々なAPIでゼロから立ち上げたサイトを複数運営しています。

dtn.jp関連サイト

  • ディレクトリ型検索エンジンdtn大手は全てサービスを終了してしまい、中小でも運営を継続するところがほとんど無くなったディレクトリ型検索エンジンを、2002年から細々運営しております。今も申請されたサイトは実際に管理人が訪問して確認後に登録しています。是非登録どうぞ。
  • 猫ネコサーチエンジン猫・ペットサイト専用のディレクトリ型検索エンジンです。登録サイトはサイトのスクリーンショット付きでカテゴリに掲載をいたします。
  • 画像掲示板の泉画像・YouTube・ニコニコ動画・Tiktokの貼り付けが可能な匿名画像掲示板です。27ジャンルに分かれた掲示板に、それぞれ100スレッドまで立てることが可能です。
  • ツイータンTwitter APIを使って10分おきに収集したTwitterトレンドワード・人気ハッシュタグデータを、月別に集計してランキング形式で公開しています。年間トレンドワードも公開中。
  • Keyword Tool++Yahooショッピングや楽天のトレンドワードデータを日次収集し、EC系の人気キーワードをラインキング形式でご紹介しています。各ワードの検索ボリュームや関連語、24か月の検索ボリュームをグラフで確認が可能です。
  • 消費者金融の泉カードローン商品を取り扱う金融業者を一覧で比較可能としたサイトです。カテゴリ別、人気度別、限度額別、金利別に比較可能です。
  • TrendinGファッションブランドを人気アイテムヒット率でランキング化し、一覧でご紹介しているサイトです。

各サイトの開発方法などについて

各サイトの開発方法や運用トラブルについては、当ブログで不定期にご紹介しています。Twitterで新着記事のお知らせもしています。宜しければフォロー下さい。