Web サイト上の画像のヒット数と元の IP を追跡するヒット カウンター スクリプトを作成したいと考えています。インプレッションは 1 日あたり数十万以上であるため、カウンターは 1 秒間に何度も増分されます。
シンプルな自己ホスト型の方法 (php、python スクリプトなど) を探しています。これを追跡するためにMySQLを使用することを考えていましたが、もっと効率的な方法があると思います. カウンターを維持する良い方法は何ですか?
魅力的な題材。カウンタのインクリメントは、シンプルかもしれませんが、トランザクションでなければなりません... つまり、意味をなさないほど長い間 DB 全体をロックアウトする可能性があります!-) システム全体のボトルネックになる可能性があります。
厳密に正確な数が必要だが、それらをすぐに最新にする必要がない場合、私のお気に入りのアプローチは、カウント可能な情報をログに追加することです (データの鮮度を保つために、必要に応じてログを切り替えます)。ログが閉じられると (カウント可能な数千のイベントが含まれる)、スクリプトはそれを読み取り、単一のトランザクションで必要なすべてを更新できます。直感的ではないかもしれませんが、数千の単一ロックよりもはるかに高速です。
次に、統計的に正確なだけの非常に高速なカウンターがありますが、そのような不正確さが許容できるとは言わないので、これ以上詳しく説明するつもりはありません。
誰かがあなたのサイトを訪問した正確な瞬間にデータを手元に置く必要がない場合に備えて、Web サーバーのアクセス ログ(Apache: access.log) を取得し、何度も評価することができます (cronjob)。
通常、access.log はとにかく生成され、要求されたリソース、時間、日付、およびユーザーの IP が含まれます。この方法では、php-script を介してすべてのトラフィックをルーティングする必要はありません。無駄のない、意地悪な計数機。
間違いなく、Redis はこの問題に最適です。セットアップとインストールに約 1 分かかり、アトミック インクリメントをサポートし、信じられないほど高速で、python と php (および他の多くの言語) 用のクライアント ライブラリがあり、耐久性があります (スナップショット、ジャーナル、レプリケーション)。
各カウンターを独自のキーに保存します。次に、単に
INCR key
非常に簡単な方法が 2 つあります。
オプション 1 は、市販のツールで動作します。オプション 2 では少しプログラミングが必要ですが、トラフィックが急増した場合 (直接の mysql の場合など) に失敗することなく、リアルタイムの更新に近いものが得られます。
精度が重要な場合は、MySql で少し遅くすることができます... カウンター値を格納するための HEAP / メモリ テーブルを作成します。これらは非常に高速なメモリ内テーブルです。間隔を置いて通常のテーブルにデータを書き込むことができます。
アプリ エンジンのアイデアに基づいて、カウンターの一時的なストアとして memcache を使用できます。memcache カウンターのインクリメントは、MySql ヒープ テーブルを使用するよりも高速です (と思います)。5 秒または 10 秒に 1 回、memcache カウンターを読み取り、その数値を DB に書き込むことができます。
私は同じような規模で非常に似たようなことをしました(複数のサーバー、数百のドメイン、1時間あたり数千のヒット)。ログファイルの分析は間違いなく進むべき道でした。(また、ヒット率をチェックし、ファイルタイプごとに重み付けし、リクエストが多すぎる場合はファイアウォールでIPアドレスをブラックリストに登録しました。その目的は、単なるカウンターではなく、不正なボットを自動ブロックすることでしたが、カウントはそれの本質的な部分。)
Webサーバープロセス自体に追加の作業を行わないため、パフォーマンスへの影響はありません。また、定期的に更新されるヒットカウントを、ロックせずに1分/5分/100ヒット/何でもサイトのデータベースに挿入することで簡単に公開できます。すべてのヒットで関連する行/テーブル/データベース(使用中のロックメカニズムによって異なります)。
Redisを使用できます。これは、アトミック インクリメントをサポートする非常に高速なキー値ストレージです。必要に応じて -- カウント データを複数のサーバー間で簡単に分割できます。
それがあなたの好みかどうかはわかりませんが、AppEngine は構築するのに非常に優れたプラットフォームです。DataStore とトランザクションを使用してカウンターを構築するために使用できるサンプル コードについては、http ://code.google.com/appengine/docs/python/datastore/transactions.html で説明しています。
たまたま PHP ルートに行く場合は、SQLiteデータベースを使用できますが、MySQL はその情報を保存するための完全に合理的な方法であり、通常は (少なくとも私が見たものから) それがどのように行われるかです。
IP アドレスやその他の情報を保存したくない場合は、単純な数値をテキスト ファイルに保存することもできます。