V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
slomo
V2EX  ›  程序员

求助: 大批量数据同时更新问题

  •  
  •   slomo · 2022-04-01 17:25:52 +08:00 · 1870 次点击
    这是一个创建于 977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    情景

    • 数据量在百万左右
    • 需要保证用户看到最新的数据
    • 实时性要求高
    • 由于可配置规则的原因, 百万条数据的更新并不是同一规则, 即可能需要每一条或一批数据查到内存中单独计算
    • 计算完成后需要调用其他服务进行同步更新

    暂时想到的方案

    • 提前计算, 例如 00:00 需要更新, 则 23:50 开始定时任务提前计算, 计算好的数据放在 redis 中, 00:00 开始由另一个定时任务告知程序从 redis 中读取最新值. 对 23:50 至 00:00 之间产生的脏数据进行 mark, 00:00 重新计算.
    • 00:00 定时任务, 某一节点从 redis 中读取 clean 的最新值并发送到 MQ, 其余所有节点接受消息并写库

    球球各位大佬出出方案, 谢谢! Orz!

    14 条回复    2022-04-02 20:18:05 +08:00
    laozhoubuluo
        1
    laozhoubuluo  
       2022-04-01 18:26:55 +08:00
    没看懂是增量数据应用新规则还是全量数据应用新规则。

    我感觉可以在节点维护一个数据结构用来表示当前版本的规则数据,考虑到规则数据需要提前运算可能需要下发 Redis 库 IP 之类的信息。
    改完之后相当于下发时间和切换时间解耦了,下发时间可以任意(比如 10 分钟后生效),节点到点切换规则就可以。

    当然这么玩需要下面的机器配置 NTP 服务器保证时钟基本一致,否则还得清理脏数据。
    hannibalm
        2
    hannibalm  
       2022-04-01 18:52:32 +08:00
    直接说说这个需求的背景
    wukuai
        3
    wukuai  
       2022-04-01 19:15:20 +08:00
    2PC
    MoYi123
        4
    MoYi123  
       2022-04-01 19:57:51 +08:00
    可以在用户查询的时候实时计算吗?
    THESDZ
        5
    THESDZ  
       2022-04-01 21:38:51 +08:00
    1.同时是指同一个事物?或者说用户的感知是这一百万条数据是一个事务更新的?
    2.实时性是指?1.百万数据同步到数据库的时间间隔?,2.用户从发起更新开始~阅读到最新的数据间隔

    1.假设说是真.实时,那就要拓展机器,队列+消费者,数据要强
    - 1.1.给我狠狠地堆性能
    2.假设是假实时,那就包装起来,模拟各种数据库落盘的分层操作和记录日志做合并
    - 2.1.最近看到的一个 SLM-DB ,只看其实现原理即可
    - 2.2.参考 es 近实时策略
    - 2.3.考虑垂直切分数据+alias
    - - 2.3.1.用户直接查询 alias,alias 映射作为动态的
    - - 2.3.2.可以减少缓存压力
    slomo
        6
    slomo  
    OP
       2022-04-02 11:42:44 +08:00
    @laozhoubuluo 会保证计算时间内没有规则的新增和更改. 规则本身是确定的, 只是不同批量的数据需要对应不同规则去计算
    slomo
        7
    slomo  
    OP
       2022-04-02 11:44:30 +08:00
    @hannibalm 百万会员在年终进行等级重算. 不同等级对应不同重算规则. 需要更新成长值积分(另一个服务). 因为等级关联打折等情况, 所以如果算的慢, 就会造成经济损失
    slomo
        8
    slomo  
    OP
       2022-04-02 11:45:20 +08:00
    @MoYi123 嗯嗯, 这个是想到的补偿方案. 就是脏数据重算那里
    slomo
        9
    slomo  
    OP
       2022-04-02 11:50:55 +08:00
    @THESDZ
    1. 不需求同一事物, 之前数据量比较小, 所以用单机器 ForkJoinPool 去跑的.
    2. 实时性主要指用户以及其他服务可见的实时性, 写库不需要高实时性, 这也是为什么想先放在 redis 中
    laozhoubuluo
        10
    laozhoubuluo  
       2022-04-02 13:49:05 +08:00
    @slomo 如果是这样的需求的话,不如考虑给用户等级查询这块改一下,存储的时候用户等级伴随有效期,读取的时候判断是否有效,无效的话按照新规则重算。

    举例:用户 A 的数据在去年 12.31 23:59:59 失效,01.01 00:00:00 时用户 A 请求用户等级接口的时候,服务判断 2021 年数据为脏数据之后自动调用规则判断 2021 年全年消费数据生成新规则并写入,有效期到今年年底。另外安排一个服务在低峰期对未调用接口的用户主动进行重算,避免有些直接取数据库的地方有误差(例如数仓)。
    slomo
        11
    slomo  
    OP
       2022-04-02 13:59:52 +08:00
    @laozhoubuluo 嗯嗯, 惰性更新这块是肯定要做的~
    请问另一个请求在低峰期去请求接口这块, 大佬有什么好的实现思路吗? flink 时间窗口统计接口请求, 低于某值发送消息触发这样可行吗? 但是感觉复杂度又高了不少
    laozhoubuluo
        12
    laozhoubuluo  
       2022-04-02 14:05:48 +08:00
    @slomo 您说的会更智能,不过一年跑一两次的话,看下流量曲线就能知道大致的低峰期了,完了在大致的低峰期内按照合适的频率给接口打请求或者塞到消息队列里完事。比如一般的业务 2-5 点低峰,那就 2:00-3:00 完成按最后登录或者什么其他指标排序的前 1/6 ,3:00 - 5:00 完成 2/3 ,5:00-6:00 完成最后 1/6 。
    slomo
        13
    slomo  
    OP
       2022-04-02 14:11:26 +08:00
    @laozhoubuluo 嗯嗯, 其实还是因为我说的只是极端情况. 目前等级的有效期有自然年, 相对天, 月, 年这些. 主要用到的是自然年. 所以等级重算这个任务每天都要去跑, 只是在年终的时候, 数据量会很大~
    感谢大佬提供思路~
    hannibalm
        14
    hannibalm  
       2022-04-02 20:18:05 +08:00 via Android
    感觉没必要集中一起刷新等级。就在客户主表上打标记,下次客户发起任何交易自动先刷新等级
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1548 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:13 · PVG 01:13 · LAX 09:13 · JFK 12:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.