需要一些关于我当前正在使用的实现的反馈...
我创建了一个嵌入到我的网站的 javascript 文件,该文件每 3 秒向端点发送一个请求。此请求具有为每个新访问者创建的唯一标识符。然后,它使用一些键(如 site_123_unique_identifier)和 json 编码值 {"load_time":189225} 添加到 redis 中。密钥的过期时间为 5 秒,并且由于我为每个访问者使用唯一标识符,因此它不会重复访问者,只是增加了过期时间。
对于我们的实时仪表板,我们每隔几秒钟向后端发送一次请求,它会获取与 site_123* 匹配的所有键。然后,我遍历它返回的所有 redis 键,并对其运行json_decode并将值相加。
这是否适用于每天获得数百万次浏览量的网站?如果不是你推荐的解决方案,必须使用 ie7+[xmlhttp 而不是套接字]
架构
-
为每个访问者
HASH site:[siteId]:[visitorId]
一个哈希值,其中包含"loadt"、"onlinet"、"loc"、"avgSpeed"等字段...... -
ZSET site:visitors
全局 zset,其中siteId:visitorsId
作为成员,lastSeen_timestamp
作为值,用于手动键过期。 -
SET site:[siteId]
一组visitorId
siteId
礼物 -
SET site
(可选)一组所有siteId
优点
- 它有效,一切都生活在 Redis 中
- 借助
HASH site:[siteId]:[visitorId]
您可以为每个访问者存储/增加任意数量的属性
缺点
- 您将不得不自己管理过期。一个 cron(例如每 ~5 秒)必须通过以下方式检索即将过期
visitorId
:ZRANGE site:visitors (NOW()-5 seconds) -1
然后遍历所有成员并执行:
DEL site:(member_value)
然后从第一个成员中提取siteId并执行(每次从成员中提取visitorId
)
SREM site:[siteId] visitorId1 visitorId2 visitorId3
(请参阅下面我对 LUA 脚本的说明)
- 每次更新
HASH site:[siteId]:[visitorId]
中的值时,您将拥有
要执行:
ZADD site:visitors [siteId:visitorId] now()
SADD site:[siteId] [visitorId]
。以及HSET
或HINCRBY site:[siteId]:[visitorId] field value
你不需要
json_decode
.例如,如果您想检索特定网站上的当前访问者数量只需执行:SCARD site:[siteId]
如果您需要检索当前连接到
siteId
的所有访问者的平均加载时间,最好的方法是使用 LUA 脚本首先使用SMEMBER site:[siteId]
检索访问者 ID,然后循环visitorId
并使用HGET site:[siteId]:[visitorId] loadt
对数据求和,除以len(visitorIds)
,你就完成了:)
注意
- 你应该在lua中实现上述算法,以便在Redis中完成所有这些工作,只接收你需要的东西,参见EVAL。
这在唯一身份访问者较少时有效,访问者数量变大,您将在 Redis 中获得许多密钥,当您在 Redis 上执行密钥 site_123* 时,Redis 服务器将被阻止,直到命令完成,在此阻止期间,Redis 服务器将不会处理任何其他查询。
您是否正在计算每个访问者的在线时间?