wangliran1121 最近的时间轴更新
wangliran1121

wangliran1121

V2EX 第 418540 号会员,加入于 2019-06-04 10:44:39 +08:00
wangliran1121 最近回复了
35 天前
回复了 glaz 创建的主题 程序员 单用户余额高并发支出收入有啥好方案?
@wxf666
1 、对于这种交易场景,对账是必须存在的过程,这是一种风控手段,T+1 只是举例子,也可以 T+1min ,所以用户看到的余额清算是稍微不准确的,有些延迟的,这点业务上一般可以接受;
2 、另外,另一种风控要求就是政策和法律,每一笔入账可能都要经过企业内部的风控模型审核完后才能入账,可以是机审,也可以是人审,总之无论政策还是企业都会有这样的要求(换句话说,企业必须要有能力判断一笔账是否异常)
3 、你担心正确性,一般事务性可以保证,但是应付一些极端问题,你通过对账也能修正回来
4 、题目意思就是单个商户高并发读写的场景,因此按照你的设计,只能是串行,设计思路可行,但是于题意而言,不太符合场景;
5 、你测试的只是写请求,但是按照你 45 楼的设计思路,实际上一次入库是需要经历一次完整的读写的,你不读上一笔流水的余额,怎么计算下一笔流水的余额呢?另外,你也不支持并发读,意味着你整套读写过程是串行的,代价十分高昂
36 天前
回复了 glaz 创建的主题 程序员 单用户余额高并发支出收入有啥好方案?
@wxf666 补充一点,高并发的思路是尽可能少串行化。
36 天前
回复了 glaz 创建的主题 程序员 单用户余额高并发支出收入有啥好方案?
@sujin190 是的,redis 会引入更大的系统复杂度和风险,如果业务真这样,其实不需要考虑成本问题,其实金融级别的分布式数据库可以解决这些潜在的事务问题,比如 TiDB 之类的
36 天前
回复了 glaz 创建的主题 程序员 单用户余额高并发支出收入有啥好方案?
@wxf666

1. 为啥不直接在用户表里,记录实时余额呢?是因为 支出次数 <<< 收入次数,写压力小,还满足风控吗?
--------
我理解,直接用用户表也是需要一个对账过程,增加 T+1 的限制,仅仅是因为给对账留足冗余时间。因此每日或者说定时从明细流水中计算余额这一步操作(对账操作),实际上是不可少的。

2. 23:00 时,用户查看余额,你要汇总当天 1.66 亿条流水,计算余额吗?
--------
定时汇总,自然不必每次都汇总查询当天所有流水,因为 T+1 的限制,只需要查 balance 字段就可以知道余额了,当然实际业务不一定是 T+1 ,这里只是举例子,可以是 10min 延迟,可以是 1min 延迟,看业务可接受度。

3. @sujin190 的思路,在有支出时,user_balance 也是不变的。而是每笔支出,都查 (SELECT SUM(amount) + 该笔支出 FROM user_transaction WHERE uid = ... AND create_time >= 今天) 是否 <= balance 。
--------
每次汇总查在应付大并发读的场景下,肯定不太合适,我理解 @sujin190 他说的尽可能保证正确性的同时再考虑性能优化,首先不可否认,从明细中查询余额的做法,正确性是可以保障的

4. 你觉得 45 楼,流水表里记录实时余额,完全免除额外写压力,思路如何?
--------
这种思路也是可行的,但是要求是数据绝对串行,流水务必一条一条入库,这样最新一条流水即可表示最终余额,如果放到大并发写场景下,也不太合适,总之一切,“看菜吃饭”
36 天前
回复了 glaz 创建的主题 程序员 单用户余额高并发支出收入有啥好方案?
顺着 @sujin190 的思路,我捋捋

简化的思路,设计两张表,具体做不做 sharding 这里且不讨论

表 1:user_balance ( uid, balance )
表 2:user_transaction (uid, amount , type, create_time)

假定业务接受 T+1 结算余额,那么意味着每日零点会对历史流水做一个汇总计算,汇总结果写入 user_balance 表字段 balance 。

user_balance 表 balance 字段存的是截止至今日的余额,那么意味着今日的支出无论如何都不能大于 balance (用户只能使用当日 0 点以前的余额,接受 T+1 意味着当日一切进账皆被冻结)

接下来收入和支出具体逻辑就是这样的:

收入:
1 、无脑写表 user_transaction

支出:
1 、检查 balance 是否和支出金额相匹配,支出金额不能超过 balance ;
2 、如果支出金额没有超过 balance ,则原子扣减 balance ,扣减后 balance 如果是大于等于 0 ,则写支出流水,以上,扣减和写流水再同一个事务里;

简化思路是这样,但是如果遇到大并发量如何考虑优化方向?

1 、首先支持事务性高性能的 db ,可以首先排除 mysql ,有条件可以往分布式数据库方向选型;
2 、条件有限,考虑将 balance 抽离到 redis ?事务性如何保障?这些细节可以后面考虑
select for update
84 天前
回复了 supuwoerc 创建的主题 程序员 请教分布式下如何用锁确保更新不丢失?
我倾向于 @csys 的方案 3 ,本身你这个业务场景要上锁就很难理解。。。
@vueli 我也遇到过,黑产来的
2023-01-13 09:49:30 +08:00
回复了 zhiouzhou 创建的主题 广州 要想在广州买房,至少得有多少钱?
@think2011 哪里找远程工作
2022-11-04 18:04:46 +08:00
回复了 xt1990xt19900 创建的主题 Apple ventura 建议升级吗
@IslandOwnerHuang 你升级之后卡顿吗?
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1788 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms · UTC 16:38 · PVG 00:38 · LAX 08:38 · JFK 11:38
Developed with CodeLauncher
♥ Do have faith in what you're doing.