V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 外包信息请发到 /go/outsourcing 节点。
• 不要把相同的信息发到不同的节点
hao123yinlong
V2EX  ›  酷工作

各位帮忙讨论讨论这个有什么高效的实现方式

  •  1
     
  •   hao123yinlong · 2016-08-07 22:40:58 +08:00 · 2025 次点击
    这是一个创建于 3029 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景

    有 N 个 球 ( 百万个 )放在仓库 ,每次会有 M 个 (< 10 个) 同学会逐个进入操场中 ,这时候需要从仓库中取出球来给这些同学们玩 ( 每个同学完成各自指定量的球后,自动退场) , 每个球会给在场的同学们传递一遍(如果传球过程中,其中一个同学 之前传过这个球,就跳过这个同学,直接传给下一个同学),然后扔掉 ,并且记录下每个同学传过哪些球 。

    需求

    从仓库取球时 ,需要计算后,优先取出所有在场同学都没有玩过的球 ; 如果不存在在场同学都没玩过的球,则尽量取出没被在场同学玩过的球

    待完善方案

    Redis 存储

    • 存储所有的球用 SET , key 为 all_balls , value 为 ball_id ;

    • 存储 每个同学玩过的记录也各自用一个 SET , key 为 stu:idm:balls , value 为 ball_id 。每个同学传递过一次球后, SADD 一次 。

    当 id 为 1 同学进场时 ,在 Redis 中,执行

    SDIFFSTORE all_stu_can_play_balls all_ball stu:id1

    all_stu_can_play_balls 为 key 的 SET 用来存储在场同学都能玩的球集合

    当 id 为 m 的同学进场时 ,在 Redis 中,执行

    SDIFFSTORE all_stu_can_play_balls all_ball stu:idm:balls

    key 为 all_stu_can_play_balls 更新为 最新的能被所有在场同学试玩的球 id 的 SET

    当 id 为 m 的同学传递一次球后, 在 Redis 中 ZADD 一次

    当 id 为 m 的同学完成其指定的传递次数后,退场时 ,挨个用 all_balls 对在场同学的 stu:idm:balls 执行 SDIFFSTORE ,重新计算 all_stu_can_play_balls 。

    即 完成了取出能被所有在场同学玩的球 ,但是如果 all_stu_can_play_balls 被所有同学都试玩了后,如何取到 尽量多能被在场同学玩的球呢?

    Now

    上面这个不完整方案只是抛砖引玉,还请各位 v2er 完善或者提出更优完整的方案

    2 条回复    2016-08-25 10:01:34 +08:00
    hao123yinlong
        1
    hao123yinlong  
    OP
       2016-08-07 22:52:27 +08:00
    抱歉 ,编辑出错 ,应该是

    # 当 id 为 m 的同学进场时 ,在 Redis 中,执行
    <br/>
    SDIFFSTORE all_stu_can_play_balls all_stu_can_play_balls stu:idm:balls
    <br/>
    key 为 all_stu_can_play_balls 更新为 最新的能被所有在场同学试玩的球 id 的 SET
    Joan114
        2
    Joan114  
       2016-08-25 10:01:34 +08:00
    体育游戏?球 id 作为 key 放 redis , value 为已经传过该球的同学的 id ,每次把拿出来的球的 value 和当前在场的同学 id 比较一下,如果全部已经传过(看你们需求是重新获取一个球,还是这个球在场滚一圈下去,哈哈。。。),另外一种情况就是场上的同学包含没有传过该球的,那么按照你们需求(随机获取场景同学 id 进行传,或者场景同学的顺序传,巴拉巴拉。。。。),每当球经过一个同学的时候,记录一下 id ,这里有个优化点是,不用每当球发生变化就去及时更新 redis , redis 是单线程操作的,如果房间(就是你这里说的场景)开多了,就会出现性能问题,可以把 memory 利用起来啊,定时或者场景传递完毕后再往 redis 里面 flush


    巴拉巴拉的一大堆,不知道是不是你们想要的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1061 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:05 · PVG 03:05 · LAX 11:05 · JFK 14:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.