• 热点账户问题-转


    https://blog.csdn.net/laoxilaoxi_/article/details/80963905

    一、热点账户

            热点账户就是高频进行扣款、入账的账户,也就是热点账户该条数据为热点数据,会被频繁更新。一般热点账户分为两种,一种是频繁扣款的热点账户,另外一种是频繁入账的热点账户。

    二、热点账户常见问题

            1、性能瓶颈问题

            2、数据库压力问题

            3、成功率问题

    三、纯修改余额方式及其特点

           1. 乐观锁

            操作方式:

                    查询账户数据:

                            SELECT  BALANCE, STATUS, VERSION, … FROM ACCOUNT WHERE ID = ?

                    计算余额:

                            POST_BALANCE = BALANCE + AMOUNT

                            或者

                            POST_BALANCE = BALANCE - AMOUNT

                    更新账户余额:

                            UPDATE …. BALANCE = POST_BALANCE,VERSION = VERSION +1 WHERE ID = ? AND VERSION = ?

                            更新返回1,更新成功,返回0,更新失败,需抛出异常,回滚事务

                    插入账户历史:

                            INSERT … 

            优点:

                    不会存在阻塞,响应时间快;

                    数据库没什么压力;

                    在内存里可以完成很多复杂操作;

            缺点:

                    成功率不高,真的存在并发时,失败的请求比较多;

                    有效的性能依然不高;

            一般应对方案:

                    采用重试的方式,立即重试三次,以提高成功率

            个人看法:

                    这种重试在真正的有量的时候基本没啥作用,相反会徒增数据库的请求量,鄙人觉得这种重试只能解决请求量较小的时候的并发,比如突然同时进来两笔同一个账户的请求,处理失败的话进行重试是可以解决问题的;但是一瞬间进来200笔,甚至更多的话,这种重试没啥作用了。

                

           2. 悲观锁    

            操作方式:

                    查询账户数据:

                        SELECT BALANCE … FROM ACCOUNT FOR UPDATE WITH RS

                     计算余额:

                            POST_BALANCE = BALANCE + AMOUNT

                            或者

                            POST_BALANCE = BALANCE - AMOUNT

                    更新账户余额:

                            UPDATE …. BALANCE = POST_BALANCE,VERSION = VERSION +1 WHERE ID = ? 

                    插入账户历史:

                            INSERT …

            优点:

                    成功率高;

                    性能好;

                    在内存里可以完成很多复杂操作(余额签名);

            缺点:

                    会存在阻塞,响应时间长;

                    数据库压力大;

            一般应对方案:

                    采用信号量做热点账户资源使用限制,可以控制数据库压力,为数据库分压,且保持在一个客观的性能水平。

            个人看法:

                    这种方式能解决大部分的热点账户问题,也是本人之前采取的方式,不过偶尔会存在的超时问题也仅仅是一两笔,其余的都会被信号量拒绝了。

            

            3.数据库行级锁1

            操作方式:

                   更新余额:

                        入账:

                                UPDATE BALANCE = BALANCE +AMOUNT WHERE ID = ?

                        扣款:

                                UPDATE BALANCE = BALANCE - AMOUNT WHERE ID = ? AND BALANCE > AMOUNT

                   读取账户数据:(读取数据是为了在账户历史插入的时候保留发生后余额)

                                SELECT * FROM ACCOUNT WHERE ID = ? WITH CS 

                   插入数据

                                INSERT ...

            优点:

                    成功率高;

                    性能好(相对于2);

                    数据库压力也会小(相对于2);

                    相应时间也小(相对于悲观锁);

            缺点:

                    一些复杂的操作无法在内存完成了(余额签名)

            一般应对方案:

                    复杂的操作异步化,延迟也就是毫秒级别,或者舍弃签名

            个人看法:

                    这种方式与悲观锁相比好了很多,数据库压力小,性能高了,许增加上单账户限流或者信号量,防止单账户暴涨的量把数据库压爆。

            4.数据库行级锁2

            操作方式:

                    更新余额:

                        入账:

                                UPDATE BALANCE = BALANCE +AMOUNT WHERE ID = ?

                        扣款:

                                UPDATE BALANCE = BALANCE - AMOUNT WHERE ID = ? AND BALANCE > AMOUNT

                    插入数据

                                INSERT …

                    异步更新发生后余额:(或者根据业务情况不需要该步骤)

                                UPDATE  ACCOUNT_HISTORY SET POST_BALANCE = ? WHERE  ACCOUNT_ID =?

            优点:

                    成功率高;

                    性能好(相对于3);

                    数据库压力也会小(相对3);

                    相应时间也小(相对3);

            缺点:

                    代码复杂度高,需要异步化一些处理;

            个人看法:

                    一些非核心部分的修改及操作,不需要就去掉,需要的话那就异步处理下。

                

        以上为本人一些粗浅的看法及实践,如有错误或者不恰当处,还望海涵,帮忙指出,也欢迎留言讨论,邮箱地址laoxilaoxi@foxmail.com,下次一起讨论一下更新余额方式之外的热点账户的一些看法。

        环境:Spring + Mybatis + DB2
    ---------------------
    作者:laoxilaoxi_
    来源:CSDN
    原文:https://blog.csdn.net/laoxilaoxi_/article/details/80963905
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    苹果远程推送测试
    iOS 模糊化效果 ANBlurredImageView的使用
    VS2015中正确添加GIF的方式
    十大经典排序算法
    Windows Error Code(windows错误代码详解)
    C++捕获系统异常(VS2015设置)
    Qt5 error LNK2019 无法解析的外部符号的解决办法
    Linux常用命令大全(非常全!!!)
    利用MFC Picture Control控件 加载bmp,png
    在C++中如何实现文件的读写
  • 原文地址:https://www.cnblogs.com/coolgame/p/10034047.html
Copyright © 2020-2023  润新知