基本的にデータの保存にはMySQLを使っているのですが、
1テーブルにログを蓄積していくと膨大になり、処理に影響が出る事を懸念しています。
自分で調べた解決策として
(A)ログは月ごとにファイルを作成し、アクセスがある毎に追加書き込みする。出力時は、日付を選択して対象ファイルを読み込み、一括出力。
(B)SQLiteを使い、ユーザ毎に専用のDBを作成してそこに書き込む
(C)MySQLのパーティショニングを使用する
現在はAで対処しているのですが、ログを検索したい時、DB構造ではないので困難です。
CはMySQLのバージョンに依存する為、出来れば使いたくないです。
Bの方法が良いとも思いましたが、はてなの過去ログを調べるとオススメ出来ないとの意見がありました。
そこで質問ですが、膨大化するデータを扱い、出力・検索する事を目的とした場合、
どのような方法を用いればよいのでしょうか?
こちらの環境はLAMPでPHP5.1.6とMySQL5.0.66を使っています。
MySQLを使いテーブル末尾に _YYYYmm と年月情報を付加して、テーブルを月別に分ける処理を作ったことがあります。
個人的には悪くない処理方法だと思っています。
一般論として、アクセスログや操作ログは、更新ではなく追加のみのデータです。また、一般ユーザーに利用させる性質のものでもないので、トランザクションが増えたり応答速度(検索性能)が要求されるものでもありません。さらに、アクセスログや操作ログをユーザー毎に分離することによって、当該ユーザーの行動が明らかになりますので、個人情報に準じた扱いが求められます(「経済産業分野を対象とする個人情報保護ガイドライン等について」参照)。
よって、MySQLやSQLiteといったセキュリティ面では強くないDBMSを適用するより、セキュリティ対策を施したテキストファイルとして格納することが検討候補となります。
機能的にはシングルスレッド処理になるはずなので、検索条件に適したインデックスファイルを作っておけば、単純テキスト検索でもDBMSに匹敵する速度を実現することが出来ます。
いずれにしても、機能要件として以下を整理すべきかと存じます。
回答されているのは、私が質問で挙げた「A」の方法に近いと思います。
ただ、「検索条件に適したインデックスファイル」という説明が少しわかりません。
私の場合、
log/ユーザID/(日付).log
というような構造で、ログを保存しています。
ファイル内はカンマ区切りでアクセス者のホスト名やブラウザ情報などを保存しています。
pahooさんのおっしゃる「インデックスファイル」というのは、検索対象とする要素(ホスト名やブラウザ情報)なども別ファイルにすると言う事でしょうか?
ちなみに「テキスト検索」がそこまで早いという実感がないです。1度ファイルをすべて読み込んで、それぞれ検索対象(カンマ区切り毎)に配列に代入しているからなのかも知れませんが。
#2のコメント:
ただ、「検索条件に適したインデックスファイル」という説明が少しわかりません。
たとえば、検索条件がユーザーIDと年月日だけなら、"log/ユーザID/(日付).log" というファイル構造それ自体がインデックスの役割を果たすので、インデックスファイルは不要と考えます。
もし、ユーザーIDや年月日は問わずに、ブラウザの種類だけを検索条件にするということでしたら、".log" ファイルとは別に、どのブラウザのアクセスログはどの ".log" ファイルにあるかを示す(インデックスする)ファイルが必要だということです。
インデックスファイルも追加するのみですので、cronを仕掛けてCPU付加が少ない時間帯に追加更新すればよいでしょう。
ちなみに「テキスト検索」がそこまで早いという実感がないです。1度ファイルをすべて読み込んで、それぞれ検索対象(カンマ区切り毎)に配列に代入しているからなのかも知れませんが。
私が想定している処理フローは、".log"の頭から末尾に向かって検索を行い、ヒットした情報のみを変数に代入していくものです。今回は戻り検索(途中で末尾から頭に戻る)は無いはずなので、それほど遅くなるとは思えません。
ただ、dev_zer0 さんがコメントしているように、また、私が#2ご回答したように、データ要件が分からないと適切なアドバイスが出来ませんし、そもそも設計ができないはずです。
業務用ならもちろんのこと、たとえ私的なシステムであっても、アクセスログ+操作ログという準個人情報を扱う仕組みですから、きちんとした設計をすべきかと存じます。バッファオーバーフローを起こしてログが外部流出するようなことになったら、ただでは済まされません。
もし、ユーザーIDや年月日は問わずに、ブラウザの種類だけを検索条件にするということでしたら、".log" ファイルとは別に、どのブラウザのアクセスログはどの ".log" ファイルにあるかを示す(インデックスする)ファイルが必要だということです。 |
つまり、私がカンマ区切りで1ファイルに記述している内容を、別ファイルにする事で、”検索条件に適したインデックスファイル”が出来るというわけですね。
ファイル数が増えますが、その方が汎用性が高いのなら、ひとつの手として考えます。
ただ、dev_zer0 さんがコメントしているように、また、私が#2ご回答したように、データ要件が分からないと適切なアドバイスが出来ませんし、そもそも設計ができないはずです。 |
コメントにも記述しましたが、ある程度の想定は出来ています。しかしながら、質問しているのは皆様の”経験則を教えて欲しい”わけですから、設計の考え方と共に「○○万件のデータを扱った場合、××になったので、インデックスファイルに分けました」というようなお話しが聞きたかったです。(質問の仕方が悪いかも知れませんが…)
質問に「膨大化したデータを扱い~」としているわけですから、回答者様毎の”膨大化”と捉える範囲があるのではないでしょうか。
過去の質問からこちらで「○件を対象にしています」としても、「それなら1テーブルに入れるだけでよい」という回答だけのものがあり、先の事を想定出来ないので、あえて条件を指定しませんでした。
MySQLのテーブルを分けるという事は考えていませんでした。
ログ専用のデータベースを作り、そこにおっしゃる方法でログ専用のテーブルを作成するのもありですね。
参考にさせていただきます。