多线程读取表数据,如何保证不重复读 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pming1
V2EX    问与答

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

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

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

    21 条回复    2020-10-10 16:40:26 +08:00
    E2gCaBAT5I87sw1M
        1
    E2gCaBAT5I87sw1M  
       2020-10-09 11:12:25 +08:00
    我也想知道
    E2gCaBAT5I87sw1M
        2
    E2gCaBAT5I87sw1M  
       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     Solana     5912 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 02:22 PVG 10:22 LAX 19:22 JFK 22:22
    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