一个字段金额,一秒可能要更新上百次,就会卡顿死锁,应该怎么处理比较好

放内存或者 redis ,定期写入数据库

时序数据库或不可变数据库?反正用插入替代修改应该就能解决。

  1. 放内存或者 redis 。不过保持数据一致性需要额外开销
  1. 数据库存储用本地高速磁盘,比如 NVME
  2. 如果是 pgsql 数据库
    3.1 字段 FILLFACTOR 设定很小值(比如 1 )提高写入性能
    3.2 关闭 full page write 开关(需要磁盘磁层有相应的安全措施,比如 ZFS 文件系统)
    3.3 关闭 sync 同步写入(需要磁盘磁层有相应的安全措施,比如 UPS 、阵列卡电池)

    我建议是修改业务逻辑,标准的读写分离:

  3. 、update 改为 insert ,插入数据同时更新 redis 。
  4. 、增加 redis ,提供读服务

这样不会有问题,即使突然挂了,数据还在数据库里,重启初始化 redis 就行了。

感谢大佬们 我试着调整下

有没有大佬解释下为什么 1 秒更新上百次就会卡顿死锁

现在的问题是数据库更新并发太高,数据库负载扛不住;楼上已经给出了问题相关解决方案,我抛砖引玉总结下楼上解决方案思路。

  1. 从降低并发负载角度来看,常规是采取削锋,控制数据库并发流量,例如可以使用消息队列处理,控制好消费流量即可。
    2.从提高并发负载角度来看,使用内存缓存替代传统关系型数据库或内存缓存作为中间层.
    3.从提高数据库行锁并发角度来看,业务策略调整,用写入替代更新,数据量会飙升,后续是否考虑分表或者定时清理数据。
  2. 提升机器配置。

    可不可以请假下是什么业务场景,怎么压力都堆到 DB 来了?

    #8 oops 粗心打错,“请教下”

    一个购票系统

    #10 购票系统,单行,RPS 数百,类型为金额,这是动态定价吗家人😂

但价格频繁变动,用户需要支付的金额也会变化,这场景太抓马了

确实没见过这种,这种高频数据写入场景只在物联网中遇见过,用的也是时序数据库。。。

这不跟交易系统一样了,已经不适合用 mysql 实时存储了,都是放内存数据库,再延时落地 mysql 。

抢锁等待更新,占用数据库链接

楼上大佬给的方案已经足够多,但是刚又想到一种。如果价格是可预知的,提前生成出来所有可能的值应该也能解决。具体的最好能把场景贴的太详细一点

热点账号的问题。
rds 范畴内: 分散更新,合并读取;追加记录,合并更新;如下:

  1. 多个账户,增加资金时哪个空闲用哪个;扣除资金如果不够,还是要锁全部账户。
  2. insert 记录,作为待结算数据,然后再批次更新回主记录。

非 rds 范畴:

  1. 不考虑用 rds 了,上 redis 等非关系数据库。
  2. 如果怕 redis 丢数据,用 in-memory + kafka ,in-memory 就是直接 java ( rust 也许更快)内存维护最新状态(本地内存可比 redis 快多了),kafka 记录变动流水( kafka 容量可比 redis 大多了)。

    这个靠谱

    写内存不好保持一致性吧。 如果内存突然挂了,交易丢失是很严重的事故。 不是很懂,望讨论。

    可以维护一个 token 池子 这个池子的 token 可以一次性生成, 可以随时补充, 每个 token 对应一个价格, 然后预扣, 最后统计池子中没用的 token 余额加回就好了..

    #18 既然是写内存,那这种数据肯定是允许丢失的,比如 1s 中变化上百次的字段,丢失其中第 99 次的数据并不影响什么,因为系统恢复后,马上又会收到最新的数据。
    如果发生交易,那交易记录是从内存中获取实时价格,然后记录本身要入持久化数据库的(而不是写内存)。

    设计的就有问题,为啥都要并发修改在数据库层面,正常不是缓存层面加锁控制数量金额等,业务交互在数据库之前走完了,数据库只是记录最终结果。然后再改数据库,而不是直接操作数据库,任何性能问题都是架构层面的问题,不是改个啥代码能解决的,除非屎山代码