madaima
V2EX  ›  PHP

PHP 在高并发下,怎么正确处理,才能保持数据的一致性?

  •  
  •   madaima · Mar 15, 2018 · 8646 views
    This topic created in 3161 days ago, the information mentioned may be changed or developed.
    
    //流程一
    class Factory
    {
        public static function get($item)
        {
            switch ($item->status){
                case 1;
                    return new a($item);
                case 2;
                    return new b($item);
                ...
            }
        }
    }
    
    //流程二
    class  a
    {
        public function aa($item)
        {
            //DB BEGIN
            //set status = 2
            //DB COMMIT
            //catch DB ROLLBACK
        }
    }
    

    首先我们排除使用悲观锁这种方法。

    如代码所示,现在处理数据时会先进入工厂类判断数据状态,然后到不同的类中去处理数据。

    但是在高并发下,流程二没走完的情况下,数据状态没更新,第二次请求还会走到流程二中去处理。

    这种情况 有什么好的方法去处理?

    36 replies  •  2018-03-16 10:07:44 +08:00
    jack010love
    jack010love
    Mar 15, 2018
    1
    PHP 的话,我们一般都是在 Redis 加个 flag。
    extreme
    extreme
    Mar 15, 2018
    3
    才疏学浅,坐等高人回答
    TIGERB
    TIGERB
    Mar 15, 2018
    4
    和语言无关吧

    方案 1: 串行操作
    方案 2: 锁
    vus520
    vus520
    Mar 15, 2018
    5
    高并发下,还用数据库的锁来实现,我感觉这是要炸啊,数据库的性能得多好?
    madaima
    madaima
    OP
    Mar 15, 2018
    6
    @jack010love 做类似乐观锁的操作吗?
    kimmykuang
    kimmykuang
    Mar 15, 2018❤️1
    7
    你的问题是要实时一致性还是最终一致性?现在高并发场景下一般都是舍弃实时一致性保证吞吐,借助队列或 redis 锁或幂等表等方式来实现最终一致性
    robinchina
    robinchina
    Mar 15, 2018 via Android
    8
    因为搞不定别的方法··········所以·锁表···········一锁解千愁·······
    puritania
    puritania
    Mar 15, 2018 via iPhone
    9
    Redis setnx 了解一下
    puritania
    puritania
    Mar 15, 2018 via iPhone
    10
    或者串行消息队列
    solaya
    solaya
    Mar 15, 2018
    11
    MVCC ?
    madaima
    madaima
    OP
    Mar 15, 2018
    12
    @l57t7q 谢谢你提供的资料 我一会研究一下。
    madaima
    madaima
    OP
    Mar 15, 2018
    13
    @vus520 对啊 所以问一下有没有其他好的实现方法学习一下。
    harborM
    harborM
    Mar 15, 2018
    14
    之前看了点文章,一般都是串行或者锁实现的,文件锁数据库锁在高并发情况下都挺粗糙的,可以用 redis 来锁,毕竟锁作为一个同步原语只要实现 acquire 和 release 理论上就成立了,而且 redis 本身可以分布式部署,应该是个可行的方案;串行的话对于部分语言有些难言之隐,php 的话如果回调形式返回结果有点难以主动推.只是我的一点思路
    dilu
    dilu
    Mar 15, 2018
    15
    加锁
    如果需要更高的性能 我才疏学浅 看别的大神怎么回答吧
    rqrq
    rqrq
    Mar 15, 2018
    16
    缓存加标志怎么弄都可以,并发了直接返回一个提示给用户,操作失败,让用户自己重试。
    数据库乐观锁有个好处是并发了会挂着等前面的处理完毕,然后自动再读取,只要不超时,用户只需要等待。
    看实际情况用哪种。
    这是我的理解,也不知道对不对,这也应该就是 @kimmykuang 说的实时一致性和最终一致性。
    rqrq
    rqrq
    Mar 15, 2018
    17
    我还没试过 redis 的锁是不是可以像数据库锁那样,如果可以肯定优先用 redis 来实现。
    madaima
    madaima
    OP
    Mar 15, 2018
    18
    感谢 楼上各位热心回复 我现在大概有个思路了 现在去实现下 试试效果。
    eslizn
    eslizn
    Mar 15, 2018
    19
    事务化,每次请求一个 id,然后这个请求中的任何原子操作,都需要额外具备确认(用于超时等情况下的重试)、回滚接口。不能确定的失败操作一律丢入队列进行重试、回滚或人工处理
    Junjunya
    Junjunya
    Mar 15, 2018
    20
    码一下, 等高人回答完了, 来学习
    onepunch
    onepunch
    Mar 15, 2018
    21
    Redis 锁,感觉 aa 应该被保护起来吧 ,如果并发很容易就达到 aa,那么数据库的压力还是很大的吧。

    战略 mark 下
    yao978318542
    yao978318542
    Mar 15, 2018
    22
    队列?我觉得可以吧
    RorschachZZZ
    RorschachZZZ
    Mar 15, 2018
    23
    目前我用队列来解决,坐等高手回答 码之
    lqtriks
    lqtriks
    Mar 15, 2018
    24
    Mark.
    prolic
    prolic
    Mar 15, 2018 via Android
    25
    redlock 了解一下
    kobe123
    kobe123
    Mar 15, 2018
    26
    异步 work
    Xrong
    Xrong
    Mar 15, 2018
    27
    楼主弄完,分享下方案撒。
    wekw
    wekw
    Mar 15, 2018❤️1
    28
    1. 分布式系统的核心功能是“队列消息传递”。
    2. 并发量不太高的时候,用原子化锁:redis 字段标记。
    3. 并发量太高的时候就得时间换性能了:用高性能消息队列。本质依然是原子化,不过将简单的标记又抽象成了队列数据存储+后期执行,实现了单机更高性能。
    4. 当单机消息队列都扛不住的时候就要上真正的分布式消息队列了,如 kafka
    90safe
    90safe
    Mar 15, 2018
    29
    @qfdk 来研究这个啊,整天研究速度优化有啥用
    youqiantu
    youqiantu
    Mar 15, 2018
    30
    高并发 redis 也不行啊。。。
    shisang
    shisang
    Mar 15, 2018
    31
    乐观锁
    liuxu
    liuxu
    Mar 15, 2018
    32
    要不楼主别两次 get,直接 case1 执行完后回调 case2?
    vtwoextb
    vtwoextb
    Mar 15, 2018
    33
    队列
    afeicool
    afeicool
    Mar 15, 2018 via Android
    34
    不知道是不是我的理解能力太弱,完全没看懂你的业务,如果只是改状态的话 完全可以用 set status=2 where status = 1, 何必又是这个锁那个队列,甚至跑到分布式上去了…
    madaima
    madaima
    OP
    Mar 16, 2018
    35
    @afeicool 这里只是举个大概的流程,每个流程里面有很多业务方法,单改变状态的话就没有这么复杂了。
    th00000
    th00000
    Mar 16, 2018
    36
    redis 串行
    否则 乐观锁 悲观锁
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4261 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 93ms · UTC 09:30 · PVG 17:30 · LAX 01:30 · JFK 04:30
    ♥ Do have faith in what you're doing.