请教最近 60 秒用户在线人数存储方案 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lianghui
V2EX    程序员

请教最近 60 秒用户在线人数存储方案

  •  
  •   lianghui
    whiteclover 2015-11-14 13:38:22 +08:00 4300 次点击
    这是一个创建于 3697 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近一个要求实时的用户人数在线曲线,展示最近 60 秒每一秒在线用户人数,维度大概是全国 400 个市级城市。

    因为使用了多机写入数据 redis ,如果分城市优先队列现在我们产品有近 100 个,也就是需要 100*400=4w 个 redis list , 如果将产品所有城市合并成一条记录只需要 400 个 list 。

    但问题是我们是分布式多机写入,不能保证多台服务同时写入数据是时序 push 进入 redis queue 。

    如果使用 key 过期机制,做 key/value 存储,又会因为 web 服务的时间矫正很难保证到秒级别,而可能在展示出最近 60 秒数据后,每秒请求实时一秒数据时因为系统服务的时间而可能无法找到数据。

    不知道大家又没什么遇到过此类问题。多多指教。

    17 条回复    2015-11-15 02:33:42 +08:00
    vietor
        1
    vietor  
       2015-11-14 13:48:11 +08:00 via Android
    没有绝对精确的,延时 60 秒也没什么。所有这些数据都是以曲线形式展示,所以追求所谓的精确没人 care
    msg7086
        2
    msg7086  
       2015-11-14 13:56:11 +08:00
    单独开一台机器做统计,其他的都甩锅给这台来做。
    canesten
        3
    canesten  
       2015-11-14 14:04:53 +08:00
    量有多大?只有 60 秒这一个需求吗? 60 秒外的数据都可以不要吗?
    likexian
        4
    likexian  
       2015-11-14 14:08:45 +08:00
    关键看你实际的在线人数有多少以及在全国各地的分布情况,适量的误差是必然的。
    ericls
        5
    ericls  
       2015-11-14 14:12:46 +08:00
    time series 可以用 influxdb 看看
    lianghui
        6
    lianghui  
    OP
       2015-11-14 14:25:28 +08:00
    @vietor 我们现在能做到延迟 5 秒左右的数据,但是总是要展示最近 60 秒的数据的
    @msg7086 是个好办法,问题现在架构可能改成这个代价有点高。
    @canesten 是的,只要看最近 60 秒, 每分钟的统计我们直接放数据库了。

    @ericls 感谢
    canesten
        7
    canesten  
       2015-11-14 14:31:36 +08:00
    量不大的话就单独一个 redis
    key=用户 id
    60 秒过期
    每次请求过来 keys *一下
    量不大的话 keys 也可以用用的
    简单实用
    noman
        8
    noman  
       2015-11-14 14:31:41 +08:00
    用 zset ,不用用 list ,分数是时间戳
    noman
        9
    noman  
       2015-11-14 14:33:32 +08:00
    用 zset ,不用用 list ,分数是时间戳
    出于性能考虑可以写一个 redis lua 小函数,复制删除并插入
    noman
        10
    noman  
       2015-11-14 14:33:56 +08:00
    复制-》负责,笔误
    beneo
        11
    beneo  
       2015-11-14 15:45:27 +08:00
    为啥不弄台机器,搞一个 table ,用户 id 映射到 table index 上面

    上线,异步消息, table[index] = 1, 下线,异步消息, table[index] = 0

    60 秒做一次 table 计数
    beneo
        12
    beneo  
       2015-11-14 15:46:36 +08:00
    此外,就算弄个假的,或者延时的,也是可以的嘛。

    看上去是那个样子,差不多数据就好了

    逃~
    msg7086
        13
    msg7086  
       2015-11-14 15:49:41 +08:00
    @lianghui 只是在请求的时候往某一特定服务器发个消息而已啊,应该不算太过分吧。
    如果服务器很多的话,服务器上放一个服务指向单一 redis 服务器然后序列化发 query 也是个办法。
    直觉上应该不会太麻烦吧……?

    再过激一些的, nginx 上插一个 lua 往 redis 里直接写 http 请求数据,然后开个脚本 loop 读了发也行。
    都不算太过侵入的。
    airyland
        14
    airyland  
       2015-11-14 15:57:32 +08:00   1
    @ericls influxdb 0.9 以上都是坑,现在的版本连 backup 都操作不了
    lianghui
        15
    lianghui  
    OP
       2015-11-14 16:21:12 +08:00
    @noman 用 zset 藐视不错,可以解决多机写的问题。
    @msg7086 确实可以,仔细看了现有的架构确实可以聚集到单机再写入,以便前端展示。
    @beneo 我们是以日志时间精确秒做 bucket 块一次性做并发更新用户状态,最后得到是一个产品全国个城市每秒在线人数计数。 可以延迟几秒出,但作为商用系统,是不能造假的。
    iwannaflytomoon
        16
    iwannaflytomoon  
       2015-11-15 01:42:53 +08:00
    就算你统计精确到秒级,你数据库统计的准了,客户网络也会有延迟啊,用浏览器打开你们后台页面看数据也会有延迟啊,要说差 5 秒都不能接受我很想知道你们的客户准备拿你们这个系统来做什么?
    msg7086
        17
    msg7086  
       2015-11-15 02:33:42 +08:00
    @iwannaflytomoon 国内数据延迟不过 0.1 秒
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2661 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 44ms UTC 09:07 PVG 17:07 LAX 01:07 JFK 04:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86