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上有关计划统计计算的详细提示。很多人甚至从未停下来认为加尔各拉