9

次のクエリを使用して、MySQLDBのページビューを追跡しようとしています。

"UPDATE $table SET pageviews = pageviews + 1 WHERE page_id = 1"

これは、低から中程度のトラフィックには問題ありません。ただし、トラフィックが多い場合、DBへの書き込みが頻繁に行われると、読み取り/書き込みの競合が発生し、最終的にDBがダウンします。

Stackoverflowやその他の場所でいくつかのQAを読んだことがありますが、代わりにMongoDBが提案されています。ただし、その選択肢は利用できないため、MySQLに固執する必要があります。さらに、私はエンジン(MyISAMまたはInnoDB)を制御できません(MyISAMの場合のように、テーブルではなく行ベースのロックにより、InnoDBのパフォーマンスが向上します)。

上記のシナリオを考慮して、DBを(DBまたは他の何かで)スラッシングせずにページビューを追跡するための最良の方法は何ですか?出発点としてコードフラグメントを提供する回答を本当にいただければ幸いです(可能な場合)。

ところで、私はPHPを使用しています。

更新:@fireにはここで良い解決策があります。ただし、me​​mcacheを使用する必要があります。私は、特定のインフラストラクチャを必要とせずに簡単に実装できるものを探しています。これは、さまざまなホスティング環境で仮想的に使用できるモジュール用です。考え直してみると、ある種のCookieまたはファイルログベースの実装が頭に浮かびます。そのような実装が実際にどのように機能するかはわかりません。それ以上の入力は大歓迎です。

4

3 に答える 3

16

memcachedを使用してカウントを保存し、それをcron上のデータベースと同期します...

// Increment
$page_id = 1;
$memcache = new Memcache();
$memcache->connect('localhost', 11211);

if (!$memcache->get('page_' . $page_id)) {
    $memcache->set('page_' . $page_id, 1);
}
else {
    $memcache->increment('page_' . $page_id, 1);
}

// Cron
if ($pageviews = $memcache->get('page_' . $page_id)) {
    $sql = "UPDATE pages SET pageviews = pageviews + " . $pageviews . " WHERE page_id = " . $page_id;
    mysql_query($sql);
    $memcache->delete('page_' . $page_id);
}
于 2012-11-29T15:16:54.010 に答える
1

私はあなたが利用できる最速の書き込みエンジンで生のヒットを集めることを検討したいと思います:

INSERT INTO hits (page_id, hit_date) VALUES (:page_id, CURRENT_TIMESTAMP)

...次に、定期的なプロセス(場合によってはcronコマンドラインスクリプト)を実行します。このプロセスは、必要なページ数の概要を1時間ごとまたは1日ごとにカウントして保存します。

INSERT INTO daily_stats (page_id, num_hits, day)
SELECT page_id, SUM(hit_id)
FROM hits
WHERE hit_date='2012-11-29'
GROUP BY page_id

(クエリは単なる例であり、ニーズに合わせて調整します)

もう1つの典型的な解決策は、古き良きログ解析であり、AWStatsのようなスクリプトにWebサーバーのログをフィードします。

明確化:私の最初の提案は@fireの提案とかなり似ていますが、ストレージの詳細については触れませんでした。重要な点は、大量の処理と最小限の生情報を最速の方法で遅らせることです。

于 2012-11-29T15:26:02.207 に答える
0

このテーブルへの読み取りまたは書き込み速度を指定していません。インデックス作成を最小限に抑え、行サイズを小さくすれば、MySQLは通常非常にうまく機能します。ページIDとカウンター列を持つテーブルは、ほとんどの場合非常に高速である必要があります。

InnoDBも問題ないはずです。MyISAMは、大量の書き込みアクティビティ中にシステムがクラッシュしたり電源が切れたりした場合に、最悪の方法で爆発する可能性があり、ジャーナルに記録されず、常に回復できるとは限りません。InnoDBははるかに堅牢です。

InnoDBから最大のパフォーマンスを得るには、標準のガイドラインに従ってサーバーを調整し、サーバーを積極的にベンチマークして、正しく機能することを確認する必要があります。各OSには癖があります。適切な設定を行わないと、パフォーマンスが2倍向上することを見逃してしまうことがあります。

追跡データベースが小さい場合は、RAMディスクでバックアップされたインスタンスを作成し、それを通常のHDで別のサーバーに複製することをお勧めします。非常に高い書き込みアクティビティが予想されるため、システムクラッシュなどの最悪の状況でデータのわずかな損失に耐えることができる場合は、mysqldumpこのデータベースを定期的にスナップショットすることができます。100万行でもメモリでバックアップされたデータベースをダンプするのにかかる時間はわずか1分で、MVCCが原因で書き込みが中断されることはありません。

于 2012-11-29T15:51:55.607 に答える