web-dev-qa-db-ja.com

より効率的なものは何ですか-SQLデータベースまたはファイルにログを保存しますか?

Cronによって頻繁に読み込まれるスクリプトはほとんどありません。現在、ログを保存していないので、スクリプトの読み込みに失敗した場合、結果が表示されるまでそのことはわかりません。結果が正しくないことに気付いても、何もできないので失敗したスクリプトを知る。

ログを保存することにしましたが、どのように保存するかまだわかりません。だから、私の質問は-SQLデータベースまたはファイルにログを保存する-より効率的なものは何ですか?

私のmysqlデータベースに「ログ」テーブルを作成して、各ログを別々の行に保存するか、phpのfile_put_contentsまたはfopen/fwriteを使用してログを別々のファイルに保存できます。

私のスクリプトは、作業中に1分あたり約5つのログ(合計)を追加します。何が速いかを判断するためにいくつかのテストを実行しました-fopen/fwriteまたはmysqlの挿入。 「挿入」ステートメントを3000回ループして3000行を作成し、fopen/fwriteを3000回ループしてサンプルテキストを含む3000ファイルを作成しました。 Fwriteは、SQLの挿入より4〜5倍速く実行されました。 2番目のループを作成しました-「select」ステートメントをループして文字列に3000回割り当てました-「fopen」を使用して3000個のファイルを開き、結果を文字列に割り当てました。結果は同じでした-fopen/fwriteはタスクを4〜5倍速く完了しました。

だから、すべての経験豊富なプログラマにとって-ログを保存した経験は何ですか?何かアドバイス?

// 04.09.2011 EDIT-回答ありがとうございました。彼らは馬を助けてくれました。各投稿は貴重だったので、1つの回答のみを受け入れるのは非常に困難でした;-)

24
biphobe

同じログインスタンスにアタッチされたライターの概念をネイティブにサポートする Zend_Log などのコンポーネントを使用できます。このようにして、ロギングコードを変更する必要なく、同じメッセージを1つ以上の異なる場所に記録できます。また、いつでもコードを変更してログシステムを置き換えるか、簡単な方法で新しいログシステムを追加できます。

あなたの質問については、ログメッセージを読む必要があるのがあなた(開発者)だけである場合、ファイルへのログ記録はより単純で適切であると思います。

他の人がWebインターフェースでログを読む必要がある場合、またはログを検索する機能が必要な場合は、代わりにdbにログを記録してください。他の誰かが並行性の問題も指摘しているように、多くのユーザーがdbにログインしている場合は、より適切にスケーリングできます。

最後に、ログの頻度が1分あたり5メッセージの場合、アプリケーションのCPUはほとんど必要ないため、パフォーマンスを心配する必要はありません。あなたの場合、私はログファイルから始めて、必要条件が変わる場合は変更します(またはライターを追加します)。

10
Fabio

ファイルを使用したログの方が効率的ですが、データベースに保存されたログはリモートからでも読みやすくなっています(たとえば、必要に応じてWebフロントエンドを作成できます)。

ただし、データベースへの行の接続と挿入はエラーが発生しやすい(データベースサーバーがダウンしている、パスワードが間違っている、リソースが不足している)ことに注意してください。

13
trojanfoe

調査結果へのコメント。

ファイルへの書き込みに関しては、おそらく正しいでしょう。
読書に関して、あなたは完全に間違っています。

データベースへの書き込み:

  1. MyISAMは挿入時にテーブル全体をロックし、ロックの競合を引き起こします。行ロックのあるInnoDBを使用します。
  2. 1.とは対照的です。ログで全文検索を実行する場合。 MyISAMを使用してください。フルテキストインデックスをサポートしています。
  3. 本当に高速になりたい場合は、memoryエンジンを使用できます。これにより、テーブルがRAMに書き込まれます。 CPUの負荷が低いときに、データをディスクベースのテーブルに転送します。

データベースからの読み取り

これが、データベースが真に優れている場所です。
さまざまなエントリのあらゆる種類の情報を組み合わせることができます。これは、フラットファイルから行うよりもはるかに高速かつ簡単です。

SELECT logdate, username, action FROM log WHERE userid = '1' /*root*/ AND error = 10;

where句で使用されているフィールドにインデックスがある場合、結果はほぼ即座に返されます。フラットファイルでそれを試してください。

SELECT username, count(*) as error_count 
FROM log 
WHERE error <> 0 
GROUP BY user_id WITH ROLLUP

テーブルが正規化されていないという事実を気にしないでください。これは、フラットファイルで行うのがはるかに遅く、困難になります。
それは本当に簡単なことではありません。

スピードがすべてではありません。はい、ファイルへの書き込みは高速ですが、データベースにある場合、ログで必要なものを見つけるのははるかに高速です。数年前、私はCMSをファイルベースのログからMysqlテーブルに変換しました。テーブルが良いです。

2
Charlie

ログのサイズと同時実行レベルによって異なります。最新のため、テストは完全に無効です-サイトに100人のユーザーがいて、10個のスレッドが同じファイルに書き込む場合、fwriteはそれほど速くありません。 RDBMSが提供する機能の1つは、同時実行制御です。

これは、実行したい分析の要件とロットの種類によって異なります。レコードを読み取るだけでも簡単ですが、定義された期間にわたって一部のデータを集計するのはどうでしょうか。

大規模なWebサイトでは、ログの書き込みに Scribe のようなシステムを使用しています。

ただし、毎分5つのレコードについて話している場合、これは負荷が非常に低いため、主な問題は、それらをどのように読み取るかです。ファイルがニーズに適している場合は、そのファイルを使用してください。一般に、追加のみの書き込み(通常はログの場合)は非常に高速です。

2

データベースにログを保存することは良い考えではないと思います。ファイルを介してデータベースにログを保存することの長所は、SQLの機能を使用してログをはるかに簡単に分析できることです。ただし、短所は、データベースの保守に多くの時間を費やす必要があることです。ログを保存するために別のデータベースサーバーをセットアップすることをお勧めします。そうしないと、ログINSERTが多すぎて、データベースのパフォーマンスが本番環境で使用できなくなる可能性があります。また、ファイル(logrotateなど)と比較して、移行、データベースへのログのアーカイブは簡単ではありません。

今日では、ログを処理するために特別な機能が豊富なログシステムを使用する必要があります。たとえば、logstash( http://logstash.net/ )にはログコレクター、フィルターがあり、外部にログを保存できます。ログを視覚化および分析するための美しいフロントエンドと組み合わされたelasticsearchなどのシステム。

参照:

1
Xiao Hanyu

ファイルシステムの書き込みは常に高速である必要があります。

ただし、それはあなたの懸念事項です。単純な挿入とファイルシステムへの書き込みは、どちらも迅速な操作です。心配する必要があるのは、データベースがダウンしたときに何が起こるかです。私は個人的に両方に書き込むのが好きなので、何か問題が発生した場合は常にログが存在しますが、データベースから検索するのも簡単です。

1
Tom Squires

個人的には、ログファイルを好むので、2つの関数を作成しました。

<?php
function logMessage($message=null, $filename=null)
{
    if (!is_null($filename))
    {
        $logMsg=date('Y/m/d H:i:s').": $message\n";
        error_log($logMsg, 3, $filename);
    }
}

function logError($message=null, $filename=null)
{
    if (!is_null($message))
    {
        logMessage("***ERROR*** {$message}", $filename);
    }
}
?>

定数を1つまたは2つ定義し(ACTIVITY_LOGとERROR_LOGは両方とも同じファイルに設定されているので、2つのファイルを並べて参照して実行の全体的なビューを取得する必要はありません)、必要に応じて呼び出します。また、専用のフォルダー(/ var/log/phplogs)を作成し、作成する各アプリケーションには独自のログファイルがあります。最後に、ログをローテーションして、顧客が参照できる履歴をいくつか持っているようにします。

上記の関数を自由に使用できるということは、アプリの実行をかなり簡単に追跡できることを意味します。

0
DaveyBoy

エラーログは、私の考えではファイルに限定するのが最善です。データベースに問題がある場合でも、ログに記録できるからです。エラーロギングでデータベースへの接続が必要な場合、これはオプションではありません。

ただし、一般的なロギングはデータベース内に残したものですが、これは、監査証跡などのロギングを大量に実行している場合にのみ当てはまります。

0
gamesmad