2012-06-01 2 views
0

나는 수백만 명의 사용자가있는 사이트를 가지고 있습니다 (실제로는 아직 없지만 상상해 봅시다). "지난 한 시간 동안의 로그인"과 같은 통계를 계산하고 싶습니다. 같은실시간 통계를 계산하는 방법은 무엇입니까?

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

(물론 다른 조건이 통계를 신청할 수 : http://highscalability.com/blog/2008/4/19/how-to-build-a-real-time-analytics-system.html

는 가장 간단한 방법은이 같은 선택을하는 것입니다 :

문제는 여기에 설명 된 것과 유사 국가 별 로그인) 물론 이것은 수백만 (또는 심지어 수천)의 행이있는 경우 주로 느리게 발생하며 페이지가 표시 될 때마다이 쿼리를 수행하려고합니다.

어떻게 데이터를 요약 하시겠습니까? (mem) 캐시에 무엇을 가야합니까?

편집 : 데이터를 비정형 화하거나 캐시를 최신 상태로 유지할 방법을 찾고 있습니다. 예를 들어, 누군가가 로그인 할 때마다 메모리 내 변수를 증가시킬 수 있지만 "지난 1 시간 동안의 로그인"이 아닌 총 로그인 양을 알 수 있습니다. 희망은 지금 더 분명합니다.

+1

이 태그는 .net으로 태그되었습니다. IIS에서 호스팅한다는 의미입니까? 그렇다면 Microsoft의 AppFabric 프레임 워크를 확인해보십시오. 미리 만들어진 모니터링 기능에 대한 배관을 제공합니다. –

+0

@ 500-InternalServerError AppFabric의 멋진 이름과 멋진 팁 – Paparazzi

답변

0

나는 Esper/NEsper을 사용하여 종료했습니다. 또한 Uri의 제안은 유용합니다.

Esper를 사용하면 얻은 데이터의 실시간 통계를 계산할 수 있습니다.

1

데이터베이스가없는 경우 신경 쓰지 마세요. 나는 수백만 명의 사용자를 보유하고 있지는 않지만 백만 초가 걸리는 로그온 테이블과 1 초 미만의 간단한 통계를 가지고있다. 백만 행은 데이터베이스에 그다지 많은 행이 아닙니다. 중복을 가질 수 있으므로 날짜를 PK로 만들 수 없습니다. 최소한의 조각화와 삽입 속도를 위해 날짜를 클러스터되지 않은 고유 한 인덱스 오름차순으로 지정합니다. 데이터가 들어오는 방식입니다. DB가 있지만 MSSQL에서는 가능합니다. 색인 user_id는 테스트 할 항목입니다. 그렇게하면 조각화 될 색인 인 삽입 속도가 느려집니다. 테이블 스캔이 상당히 단단한 시간 범위를 찾고 있다면 괜찮을 것입니다.

왜 로그인이 아닌 로그인을 구분합니까?

매 x 초마다 쿼리를 실행하는 속성 만 있습니다. 매 초라도 캐시 된 대답을보고합니다. 200 쿼리가 1 초에 해당 속성에 도달하면 200 개의 쿼리가 필요하지 않습니다. 통계가 지난 1 시간 동안의 정보에 대해 1 초 동안 유효하지 않은 경우에도 유효한 통계입니다.

+0

+1 예정된 통계 계산에 +1. 많은 사람들이 요청이 실행될 때 호출자가 계산을 수행 할 필요가 없다고 생각하지 않습니다. 이러한 쿼리를 5 초 또는 10 초간 캐시해도 바쁜 시스템에서 성능이 크게 향상됩니다. – Chris

2

IMO 더 정확한 접근법은 메모리의 관련 카운터를 보유하는 연속 계산을 구현하는 것입니다. 사용자가 시스템에 추가 될 때마다 여러 가지 방법으로 처리 할 수있는 이벤트를 실행하고 지난 1 시간, 마지막 날 또는 전체 사용자 카운터를 업데이트 할 수 있습니다. 이러한 종류의 처리를 수행 할 수있는 훌륭한 프레임 워크가 있습니다. Twitter Storm은 그 중 하나이며 또 다른 하나는 GigaSpaces XAP입니다 (면책 조항 - 저는 GigaSpaces에서 작동합니다). 특히 this tutorialApache S4GridGain입니다.

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; 
} 

단순히

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

현재 모든 사용자에 대해 조회 할 캐시에 만기 (TTL)를 구성, 24 시간 후에 퇴거를 지원하기 : 로그인 기록을 가정

이 같이 보입니다 로그인 :

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

로그인 수 및/또는 활성 사용자 수를 쿼리하려면 지난 시간 :

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에서 일하고 있습니다. 이 게시물에 표현 된 의견 및 견해는 본인 소유이며, 반드시 고용주의 의견이나 견해를 반영하지 않습니다.

관련 문제