Performance 如何计算实时统计数据?

Performance 如何计算实时统计数据?,performance,memcached,scalability,Performance,Memcached,Scalability,我有一个拥有数百万用户的网站(好吧,实际上它还没有用户,但让我们想象一下),我想计算一些统计数据,比如“过去一小时内登录” 该问题与此处描述的问题类似: 最简单的方法是进行如下选择: select count(distinct user_id) from logs where date>='20120601 1200' and date <='20120601 1300' 选择计数(不同的用户id) 从日志 其中date>='20120601 1200'和date如果您没有db

我有一个拥有数百万用户的网站(好吧,实际上它还没有用户,但让我们想象一下),我想计算一些统计数据,比如“过去一小时内登录”

该问题与此处描述的问题类似:

最简单的方法是进行如下选择:

select count(distinct user_id) 
from logs
where date>='20120601 1200' and date <='20120601 1300' 
选择计数(不同的用户id)
从日志

其中date>='20120601 1200'和date如果您没有db,则无需担心。我没有数百万的用户,但我有一个登录时间长达一年的表,它有一百万行和类似于亚秒的简单统计数据。对于一个数据库来说,一百万行并不是那么多。您不能将日期设置为PK,因为您可以有重复的日期。为了最小化碎片和插入速度,请将日期设置为聚集的非唯一索引asc,这就是数据的输入方式。不确定是否有DB,但在MSSQL中可以。索引用户id是需要测试的。这样做会减慢插入速度,因为插入是一个将被分割的索引。如果您正在寻找一个相当短的时间跨度,那么可以进行表格扫描

为什么不同的用户id而不是登录名是登录名


具有仅每x秒运行一次查询的属性。即使每秒钟一次并报告缓存的答案。如果一秒钟内有一个或200个页面访问了该属性,那么您肯定不需要200个查询。如果统计数据在过去一小时内的信息过时了一秒钟,这仍然是一个有效的统计数据。

如果你没有数据库,那没关系。我没有数百万的用户,但我有一个登录时间长达一年的表,它有一百万行和类似于亚秒的简单统计数据。对于一个数据库来说,一百万行并不是那么多。您不能将日期设置为PK,因为您可以有重复的日期。为了最小化碎片和插入速度,请将日期设置为聚集的非唯一索引asc,这就是数据的输入方式。不确定是否有DB,但在MSSQL中可以。索引用户id是需要测试的。这样做会减慢插入速度,因为插入是一个将被分割的索引。如果您正在寻找一个相当短的时间跨度,那么可以进行表格扫描

为什么不同的用户id而不是登录名是登录名


具有仅每x秒运行一次查询的属性。即使每秒钟一次并报告缓存的答案。如果一秒钟内有一个或200个页面访问了该属性,那么您肯定不需要200个查询。如果统计数据在过去一小时内的信息过期一秒钟,但仍然是有效的统计数据。

IMO,更正确的方法是实现一个连续计算,将相关计数器保存在内存中。每次用户添加到您的系统时,您都可以启动一个事件,该事件可以以多种方式处理,并更新最后一小时、最后一天甚至用户总数计数器。有一些很棒的框架可以做这种处理。是其中之一,另一个是(免责声明-我为GigaSpaces工作),具体来说,也是

IMO这里更正确的方法是实现一个连续计算,将相关计数器保存在内存中。每次用户添加到您的系统时,您都可以启动一个事件,该事件可以以多种方式处理,并更新最后一小时、最后一天甚至用户总数计数器。有一些很棒的框架可以做这种处理。是其中之一,另一个是(免责声明-我为GigaSpaces工作),具体来说,也是

我最后使用了。还有Uri的有用建议

Esper允许我在获取数据时计算数据的实时统计数据

我最后使用了。还有Uri的有用建议


Esper允许我在获取数据时计算数据的实时统计数据

如果您刚刚用完了日志,您可能需要查看类似Splunk的内容

通常,如果您希望在内存中快速(实时)存储这些数据,您可以创建一个分布式的登录数据缓存,并在24小时后逐出,然后您可以在该缓存中查询过去一小时内的登录

假设登录记录如下所示:

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
                                        + " or lastSeenTime > " + oneHourAgo);
int numActive = cache.keySet(query).size();
(有关查询的更多信息,请参阅。所有这些示例都来自Oracle Coherence。)


为了充分披露,我在甲骨文公司工作。这篇文章中表达的观点和观点都是我自己的,并不一定反映我雇主的观点或观点。

如果你的日志快用完了,你可能想看看Splunk之类的东西

通常,如果您希望在内存中快速(实时)存储这些数据,您可以创建一个分布式的登录数据缓存,并在24小时后逐出,然后您可以在该缓存中查询过去一小时内的登录

假设登录记录如下所示:

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
                                        + " or lastSeenTime > " + oneHourAgo);
int numActive = cache.keySet(query).size();
(有关查询的更多信息,请参阅。所有这些示例都来自Oracle Coherence。)


为了充分披露,我在甲骨文公司工作。这篇文章中表达的意见和观点是我自己的,不一定反映我雇主的意见或观点。

你把它标记为.net-这是否意味着你在IIS中托管?如果是这样,您可能想查看Microsoft的AppFabric框架-它为您提供了一些预先构建的监视内容的管道。@500 InternalServerError关于AppFabric的酷名称和不错的提示您将其标记为.net-这是否意味着您在IIS中托管?如果是这样,您可能想查看Microsoft的AppFabric框架-它为您提供了一些预先构建的监视内容的管道。@500 InternalServerError cool name和AppFabric+1上有关计划统计计算的详细提示。很多人甚至从未停下来认为加尔各拉