CNode

处理redis+mysql处理高并发的问题

问答
Jjiangliqin发布于10 年前最后回复10 年前20 回复28466 浏览0 收藏

我们的业务是:用户向我们平台下订单时,需要在redis中更新用户余额,我们是中间平台,上游处理用户的订单返回通知我们,这时我们根据成败来更新mysql余额和redis。 问题来了~~,在高并发下,订单总额与用户的余额有很大出入,原因是在频繁更新redis,存在前后不同步的现象! 请教大神们,对于这种问题怎么处理比较好啊?

查看回复

回复 (20)

J
jiangliqin#1·10 年前

client.getAsync('freeze' + orderObj['customer_id']).then(result => { //1.从redis中读取值 if (result) { async.parallel({ updateRedisfreeze: function(done) { //2.更新reids client.incrbyfloatAsync('freeze' + orderObj['customer_id'], '-' + orderObj['order_fee']) }, updateCustomer: function(done) { //3.更新数据库记录 customer.update({ customer_feezed_balance: freeze }, { where: { id: orderObj['customer_id'] } }) }, createOrder: function(done) { //4.数据库创建新记录 order.create(orderObj) }, deleteOrder: function(done) { client.delAsync(orderNo); /5./删除redis一条记录 } }, function(err, result) { console.log('one:', result.updateRedisfreeze); console.log('two:', result.updateCustomer); console.log('three:', result.createOrder); console.log('four:', result.deleteOrder); }) 在高并发下,怎么做到以上几步类似于数据库事务的操作,保证每次的执行具有原子性?

Q
qimenxiaozi#2·10 年前

其实对于业务来说,钱最重要,我们的解决方案是只要牵涉钱的,都去加排他锁,保证更新金额不出现脏读.

C
chloe#3·10 年前

一律排队处理,处理完一个再去处理下一个

J
jiangliqin#5·10 年前
B
bing6#6·10 年前

不做update操作不行吗?只做insert就可以了啊,保存一份交易记录。 余额读取的可不是有redis?

C
chloe#7·10 年前
引用 jiangliqin@chloe ,用消息队列吧!?

@jiangliqin 用消息队列的话可以用rabbitmq

J
jiangliqin#9·10 年前
引用 chloe@jiangliqin 用消息队列的话可以用rabbitmq

@chloe ,其实不一定用消息队列,只要是能控制并发就行,比如async.queue,bagpipe等

Y
yakczh#10·10 年前

保持处理速度均匀,多高的并发都不怕

J
jiangliqin#12·10 年前
引用 yakczh保持处理速度均匀,多高的并发都不怕

@yakczh ,这处理速度真不是自己能控制的,尤其是有上下游的情况

C
coordcn#13·10 年前

@jiangliqin 不明白为什么要用async.parallel?

如果相关操作存在先后关系,parallel并不确定谁先执行,谁后执行,几个操作执行顺序是不确定的。

J
jiangliqin#14·10 年前
引用 coordcn@jiangliqin 不明白为什么要用async.parallel? 如果相关操作存在先后关系,parallel并不确定谁先执行,谁后执行,几个操作执行顺序是不确定的。

@coordcn ,呵呵,上面操作其实是有问题,后来改了。至于你说的parallel是不关联的并行这是对的,我上面也不存在先后关系。没讲明白,让你误解了。。。

I
im-here#15·10 年前

问下楼主,这问题后来怎么处理的?

J
jiangliqin#16·10 年前
引用 im-here问下楼主,这问题后来怎么处理的?

@imhered 主要靠redis,后来再批量插进数据库,避免频繁操作数据库

I
im-here#17·10 年前
引用 jiangliqin@imhered 主要靠redis,后来再批量插进数据库,避免频繁操作数据库

@jiangliqin 你的问题不是redis里的数据脏读了么? 怎么解决脏读的?

J
jiangliqin#18·10 年前
引用 im-here@jiangliqin 你的问题不是redis里的数据脏读了么? 怎么解决脏读的?

@imhered 我上面描述的问题很复杂,对于出现脏读的部分,我们用redis-lock解决的啊

参与回复
登录后即可参与回复。登录