0

私は何百万人ものユーザーがいるサイトを持っています(実際にはまだありませんが、想像してみてください)。「過去1時間のログイン」などの統計を計算したいと思います。

問題はここで説明されているものと似ています:http://highscalability.com/blog/2008/4/19/how-to-build-a-real-time-analytics-system.html

最も簡単なアプローチは、次のような選択を行うことです。

select count(distinct user_id) 
from logs
where date>='20120601 1200' and date <='20120601 1300' 

(もちろん、国ごとのログインなど、他の条件が統計に適用される可能性があります)もちろん、これは、主に数百万(または数千)の行がある場合、非常に遅くなります。ページが表示されるたびにこれを照会したいと思います。表示されます。

データをどのように要約しますか?(mem)キャッシュには何を入れるべきですか?

編集:データを非正規化する方法、またはキャッシュを最新の状態に保つ方法を探しています。たとえば、誰かがログインするたびにメモリ内変数をインクリメントすることはできますが、それは「過去1時間のログイン」ではなく、ログインの総数を知るのに役立ちます。それが今より明確になることを願っています。

4

4 に答える 4

2

ここでのIMOのより正確なアプローチは、関連するカウンターをメモリに保持する連続計算を実装することです。ユーザーがシステムに追加されるたびに、複数の方法で処理できるイベントを起動し、過去1時間、最終日、または合計ユーザーカウンターを更新できます。この種の処理を行うための優れたフレームワークがいくつかあります。Twitter Stormはその1つであり、もう1つはGigaSpaces XAP(免責事項-私はGigaSpacesで働いています)、特にこのチュートリアル、そしてApacheS4GridGainです。

于 2012-06-03T14:33:50.217 に答える
1

あなたがデータベースを持っていないなら、気にしないでください。私には数百万のユーザーがいませんが、数百万の行と1秒未満のような単純な統計を持つ1年分のログオンのテーブルがあります。データベースの場合、100万行はそれほど多くありません。重複する可能性があるため、日付をPKにすることはできません。断片化を最小限に抑え、挿入の速度を上げるために、日付をクラスター化された非一意のインデックスascにします。これにより、データが取得されます。DBがあるかどうかはわかりませんが、MSSQLでは可能です。インデックスuser_idはテストするものです。それは断片化するインデックスであるため、挿入を遅くします。かなりタイトな期間を探している場合は、テーブルスキャンで問題ない可能性があります。

ログインではなく、別個のuser_idがログインである理由。

x秒ごとにのみクエリを実行するプロパティがあります。毎秒、キャッシュされた回答を報告したとしても。または200ページが1秒間にそのプロパティにヒットした場合、200クエリが不要であることを確認してください。また、過去1時間の情報の統計が1秒古くなっている場合でも、それは有効な統計です。

于 2012-06-01T23:14:32.897 に答える
0

私はEsper/NEsperを使用することになりました。また、有用な場合はUriの提案。

Esperを使用すると、取得中のデータのリアルタイム統計を計算できます。

于 2012-06-07T03:07:43.563 に答える
0

ログが不足しているだけの場合は、Splunkのようなものを見たいと思うでしょう。

一般に、このメモリ内で高速(リアルタイム)が必要な場合は、たとえば24時間後にエビクションを使用してログインデータの分散キャッシュを作成し、そのキャッシュに過去1時間以内のログインなどを照会できます。

ログインレコードが次のようになっていると仮定します。

public class Login implements Serializable {
    public Login(String userId, long loginTime) {..}
    public String getUserId() {..}
    public long getLoginTime() {..}
    public long getLastSeenTime() {..}
    public void setLastSeenTime(long logoutTime) {..}
    public long getLogoutTime() {..}
    public void setLogoutTime(long logoutTime) {..}
    String userId;
    long loginTime;
    long lastSeenTime;
    long logoutTime;
}

24時間後の削除をサポートするには、キャッシュに有効期限(TTL)を設定するだけです。

<expiry-delay>24h</expiry-delay>

現在ログインしているすべてのユーザーを照会するには:

long oneHourAgo = System.currentTimeMillis() - 60*60*1000;
Filter query = QueryHelper.createFilter("loginTime > " + oneHourAgo
                                        + " and logoutTime = 0");
Set idsLoggedIn = cache.keySet(query);

過去1時間のログイン数やアクティブユーザー数を照会するには、次の手順に従います。

long oneHourAgo = System.currentTimeMillis() - 60*60*1000;
Filter query = QueryHelper.createFilter("loginTime > " + oneHourAgo
                                        + " or lastSeenTime > " + oneHourAgo);
int numActive = cache.keySet(query).size();

(クエリの詳細については、 http://docs.oracle.com/cd/E15357_01/coh.360/e15723/api_cq.htmを参照してください。これらの例はすべてOracle Coherenceによるものです。)

完全に開示するために、私はOracleで働いています。この投稿で表明された意見や見解は私自身のものであり、必ずしも私の雇用主の意見や見解を反映しているわけではありません。

于 2014-02-14T19:20:49.227 に答える