sql >> データベース >  >> NoSQL >> Redis

PHPアプリケーションからのページリクエストデータをログに記録するスケーラブルな方法は?

    それは確かにさまざまな方法で実行可能です。リストされている各オプションといくつかの追加の解説について説明します。

    1)NGinxで実行できる場合は、許可します。私はApacheだけでなく、JBOSSとTomcatでもそれを行います。次に、syslog-ngを使用してそれらを一元的に収集し、そこから処理します。このルートでは、解析と読み取りが容易になるため、タブ区切りなどの区切りログメッセージ形式をお勧めします。 PHP変数をログに記録することについてはわかりませんが、ヘッダーとCookie情報をログに記録することはできます。 NGinxロギングを使用する場合は、可能であればこのルートをお勧めします-なぜ2回ログを記録するのですか?

    2)「後日日付を照会する機能の欠如」はありません。詳細は以下を参照してください。

    3)これはオプションですが、それが役立つかどうかは、データを保持する期間と、書き込むクリーンアップの量によって異なります。詳細は以下をご覧ください。

    4)MongoDBは確かに機能する可能性があります。クエリを作成する必要がありますが、それらは単純なSQLコマンドではありません。

    次に、データをredisに保存します。私は現在、前述のようにsyslog-ngを使用してログに記録し、プログラムの宛先を使用してデータを解析し、Redisに詰め込みます。私の場合、vhostやクラスターなど、いくつかのグループ化基準があるため、構造が少し異なる場合があります。最初に対処する必要がある質問は、「このデータからどのデータが必要か」です。その一部は、交通量などのカウンターになります。一部は集計になり、さらに「人気順にページを並べ替える」などになります。

    これを簡単にredisに戻す(したがって元に戻す)ためのいくつかのテクニックを紹介します。

    まず、時間の経過に伴うトラフィックの統計について考えてみましょう。まず、粒度を決定します。 1分あたりの統計が必要ですか、それとも1時間あたりの統計で十分ですか?特定のURLのトラフィックを追跡する1つの方法は次のとおりです。

    この並べ替えられたセットのキー「traffic-by-url:URL:YYYY-MM-DD」を使用して、並べ替えられたセットにデータを保存します。zincrbyコマンドを使用して、メンバー「HH:MM」を指定します。たとえば、「r」がredis接続であるPythonの場合:

    r.zincrby("traffic-by-url:/foo.html:2011-05-18", "01:04",1)
    

    この例では、5月18日の午前1時4分にURL「/foo.html」のカウンターを増やします。

    特定の日のデータを取得するには、キーでzrange( "" traffic-by-url:URL:YYYY-MM-DD ")を呼び出して、人気の低いものから人気の高いものへと並べ替えられたセットを取得します。トップ10を取得するにはたとえば、zrevrangeを使用して範囲を指定します。Zrevrangeは逆の並べ替えを返し、最もヒットするのは一番上になります。さらにいくつかの並べ替えられたsetコマンドを使用すると、ページネーションなどの優れたクエリを実行できます。最小スコアなどによる結果の範囲。

    キー名を変更または拡張するだけで、さまざまな一時ウィンドウを処理できます。これをzunionstoreと組み合わせることで、より詳細でない期間に自動的にロールアップできます。たとえば、1週間または1か月ですべてのキーを結合し、「traffic-by-url:monthly:URL:YYYY-MM」のような新しいキーに保存できます。特定の日にすべてのURLで上記を実行することにより、毎日取得できます。もちろん、1日の合計トラフィックキーを取得して、それを増やすこともできます。これは主に、データをいつ入力するかによって異なります。ログファイルのインポートを介してオフラインにするか、ユーザーエクスペリエンスの一部として使用します。

    実際のユーザーセッションでは、ユーザーがそれを体験するのにかかる時間(およびサーバーの負荷)が長くなるため、多くのことを行わないことをお勧めします。最終的には、トラフィックレベルとリソースに基づいた呼び出しになります。

    ご想像のとおり、上記のストレージスキームは、必要な、または決定した任意のカウンターベースの統計に適用できます。たとえば、URLをuserIDに変更すると、ユーザーごとの追跡が可能になります。

    ログをRedisに生で保存することもできます。これは、JSON文字列として保存している一部のログに対して行います(キーと値のペアとして持っています)。次に、それらを引き出してデータを処理する2番目のプロセスがあります。

    生のヒットを保存するために、ランクとしてエポック時間を使用してソートされたセットを使用し、zrange/zrevrangeコマンドを使用して時間ウィンドウを簡単に取得することもできます。または、ユーザーIDに基づくキーにそれらを保管します。ソートされたセットと同様に、セットはこのために機能します。

    私が説明しなかった別のオプションですが、データの一部にはハッシュとして保存することが役立つ場合があります。これは、たとえば、特定のセッションに関する詳細情報を保存する場合に役立ちます。

    データベース内のデータが本当に必要な場合は、RedisのPub / Sub機能を使用して、データを区切り形式に解析してファイルにダンプするサブスクライバーを用意してください。次に、copyコマンド(またはDBの同等のコマンド)を使用して一括インポートするインポートプロセスを実行します。あなたのDBはあなたに感謝します。

    ここでの最後のアドバイス(おそらくすでに十分な精神的時間を取っています)は、expireコマンドを賢明かつ自由に使用することです。 Redis 2.2以降を使用すると、カウンターキーでも有効期限を設定できます。ここでの大きな利点は、自動データクリーンアップです。上で概説したようなスキームに従っていると想像してください。有効期限コマンドを使用すると、古いデータを自動的に削除できます。おそらく、最大3か月間の時間ごとの統計が必要であり、その後は毎日の統計のみが必要です。 6か月間の毎日の統計、その後は毎月の統計のみ。 3か月後に1時間ごとのキーを期限切れにし(86400 * 90)、毎日6時に期限切れにする(86400 * 180)だけで、クリーンアップを行う必要はありません。

    ジオタグ付けのために、私はIPのオフライン処理を行います。 IPを要素として使用し、上記のzincrybyコマンドを使用して、IPごとのトラフィックデータを取得する「traffic-by-ip:YYYY-MM-DD」というキー構造を持つソートされたセットを想像してみてください。これで、レポートで、ソートされたセットを取得し、IPのルックアップを実行できます。レポートを作成するときにトラフィックを節約するために、IPを目的の場所にマップするハッシュをredisに設定できます。たとえば、キーとして「geo:country」、保存された値として国コードを使用したハッシュメンバーとしてIPを使用します。

    追加する大きな注意点は、トラフィックレベルが非常に高い場合は、Redisの2つのインスタンス(またはトラフィックによってはそれ以上)を実行することをお勧めします。 1つ目は書き込みインスタンスで、bgsaveオプションは有効になっていません。トラフィックがかなり多い場合は、常にbgsaveを実行します。これは私が2番目のインスタンスをお勧めするものです。これは最初のスレーブであり、ディスクへの保存を行います。スレーブに対してクエリを実行して、負荷を分散することもできます。

    それがあなたにいくつかのアイデアや試してみることができることを願っています。さまざまなオプションを試して、特定のニーズに最適なものを確認してください。トラフィックの多いウェブサイト(およびMTAログ統計)で多くの統計をredisで追跡しており、美しく機能します。DjangoとGoogleのVisualization APIを組み合わせると、非常に見栄えの良いグラフが得られます。



    1. mongodbのネストされた配列を更新しています

    2. MongoDBおよびその他のNoSQLDBでのPIIマスキング…

    3. MongoDBでJSONを使用していますか?

    4. AzureRedisキャッシュ-GET呼び出しのタイムアウト