V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
pming1
V2EX  ›  问与答

多线程读取表数据,如何保证不重复读

  •  
  •   pming1 · 2020-10-09 11:08:49 +08:00 · 2833 次点击
    这是一个创建于 1539 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个表里有 100 条记录,5 个线程同时去随机读,如何保证这 100 条记录比较平均地被这 5 个线程读取,而且互相不重复?(前提,不增加 redis 等额外基础设施或工具)

    21 条回复    2020-10-10 16:40:26 +08:00
    winnie2012
        1
    winnie2012  
       2020-10-09 11:12:25 +08:00
    我也想知道
    winnie2012
        2
    winnie2012  
       2020-10-09 11:12:44 +08:00
    PG 好像有读取行锁
    lxk11153
        3
    lxk11153  
       2020-10-09 11:14:32 +08:00
    row number % 5 ???
    dddd1919
        4
    dddd1919  
       2020-10-09 11:16:04 +08:00
    用表读锁 /行读锁
    firethehole
        5
    firethehole  
       2020-10-09 11:18:49 +08:00
    表里的数据在读的时候,会增加吗,还是已经固定了
    wakzz
        6
    wakzz  
       2020-10-09 11:24:55 +08:00
    要看你的耗时逻辑是读取本身,还是读取后数据的处理逻辑。常见的处理方法是生产消费模式,即由一个生产者从表中获取记录 ID (偏移量)推送到队列中,然后由几个消费者线程竞争消费队列中的推送记录,然后通过记录 ID (偏移量)读取记录后再逻辑处理。
    egglin
        7
    egglin  
       2020-10-09 11:41:42 +08:00
    saturn 分片
    Aliencn
        8
    Aliencn  
       2020-10-09 12:12:38 +08:00
    再开一个线程去调度
    InkAndBanner
        9
    InkAndBanner  
       2020-10-09 12:16:49 +08:00
    @wakzz 你说的这个方案是是针对耗时发生在处理上 的解决方案是嘛?
    kop1989
        10
    kop1989  
       2020-10-09 12:22:40 +08:00
    如果从程序层面解决的话,可以把 5 线程,分别取 5 随机行转换为单线程(或 5 线程的队列)取随机 25 行,然后分发。
    但这有个前提,即你 5 个线程的读取时机要严格同步。(不过如果不同步,又要取没有交集的数据,好像有点奇怪)
    boyhailong
        11
    boyhailong  
       2020-10-09 12:26:12 +08:00
    逻辑层去分配,划分下任务比如第一个线程 1-20,以此类推,当然逻辑层也要做去重。
    wysnylc
        12
    wysnylc  
       2020-10-09 12:28:35 +08:00
    别读同个分区的数据,分区规则自己定义
    jptx
        13
    jptx  
       2020-10-09 12:32:00 +08:00
    一个很传统而且简易的方式是按 id 取模,假如表里有 id 之类的纯数字,那么第一个线程扫数据库的时候条件加上 where id % 5 = 0,第二个线程是 where id % 5 = 1,以此类推。但这种方法局限性很大,比如查询效率低,每个线程需要知道自己的编号,无法动态快速扩容,分布不一定均匀等。但如果想简单的话,这种方式的确很有效
    Xusually
        14
    Xusually  
       2020-10-09 13:06:36 +08:00
    select ... for update
    试试看?
    xsm1890
        15
    xsm1890  
       2020-10-09 13:58:05 +08:00
    随机生成 100 个 id,分成四组?
    wakzz
        16
    wakzz  
       2020-10-09 14:00:12 +08:00
    @InkAndBanner 对,是针对耗时发生在业务处理上的解决方案
    pming1
        17
    pming1  
    OP
       2020-10-09 15:49:10 +08:00
    @firethehole 会增加。
    pming1
        18
    pming1  
    OP
       2020-10-09 15:50:06 +08:00
    @jptx 表数据是会增加的,线程数并非固定,具体看数据量而动态变化的,甚至可能 1 个程序 5 个线程,然后部署多个这样的程序。
    lower
        19
    lower  
       2020-10-09 16:18:41 +08:00
    读完 设置 一个 已读的状态,线程每次只从过滤 状态后的数据取?
    lower
        20
    lower  
       2020-10-09 16:19:24 +08:00
    @lower 行记录上加个 状态 列字段……
    bleoo
        21
    bleoo  
       2020-10-10 16:40:26 +08:00
    forupdate 锁一下?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3580 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:29 · PVG 12:29 · LAX 20:29 · JFK 23:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.