ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

热点账户处理

2022-04-23 17:35:16  阅读:284  来源: 互联网

标签:商户 处理 数据库 账户 更新 并发 热点


热点账户(数据)处理

 

 

关于程序员技术面试,高并发、高可用是肯定躲不过的知识点,面试官不会直接这么问,而是嵌入到某些具体场景中。

比如,让你设计一个促销活动,紧俏的商品;或者发放优惠券,某事某刻发1000张5.5折优惠券等等。

 

这类题目一是考察你的整体架构设计能力,二是看你的回答中有没有高并发高可用的实现。

 

还可以再直接一些,比如有个商户账户,会频繁的更新,如何去实现?

 

这三类问题,不管是秒杀商品库存还是打骨折的优惠券,亦或是商户账户,最根源的在于热点账户(数据)在高并发下如何正确的处理问题。

 

下面就试着给出这些问题的一个标准答案。

 

 

一、理解业务,确定业务类型。

 

你可能会问,业务不是很清楚的了,秒杀啊,热点商户更新啊,还怎么确定业务?

 

这里要确定的是更新哪些数据?哪些是热点数据?热点数据是加还是减少。

 

比如秒杀,数据库中一条商品数据是频繁更新的数据,操作是做减法,业务上不允许出现商品为负数,也就是出现“超卖”的结果。

 

优惠券呢,和商品几乎一样,优惠券的数量是热点数据,同样是做减法,不能出现负值。

 

热点商户余额呢,有些不一样,客户余额的减少,引起商户余额增加,也可以是相反,客户增加,商户减少,总之是客户的操作引起的商户热点数据更新,可加可减,当然也不能出现负值。

 

说了这么多,业务的关键出现了,这就是热点商户的更新是否接受某些延迟。

 

比如优惠券和库存,不接受延迟,数据比如是实时的,而商户的热点账户,没有必要追求高的实时性,延迟个几秒,也是可以接受的,最终一致性必须保证就OK了。

 

所以,这一步很关键,业务的梳理决定了后续的你有哪些高并发高可用的“武器”来用。

 

 

二、“实时性”要求高的解决方案

 

面对秒杀和打折扣的优惠券类活动,我想说的第一点是,如果有条件,首先做到“隔离”。

 

隔离的目的是为了保护,不要因为促销活动将整个系统搞挂。

 

可以单独的数据库,单独的服务部署,尽量做到不影响核心流程。

 

我们知道,单机不管多牛的程序员写出多牛的程序,瓶颈是很容易达到的,其中各种组件中,数据库又是木桶中“最短”的那块,所以很多的业务操作都是围绕着数据库来展开。

 

热点数据,放到数据库就是一条条的更新操作,排着队等着被执行,高并发情况下,数据库层面其实就是串行化操作,不管是多牛的update Sql,也必须排着队等着,性能的瓶颈就出现在这。

 

有什么好办法?

 

在单条热点数据,数据库层面可以有两种方案进行优化。

 

单条数据库执行慢,主要是因为并发操作,冲突多,如果能让数据库在最理想的状态下才能达到他的最优秀,而现实呢,不断地有请求进入,已经超过了他的承受范围,永远的高负荷运转,性能能好吗?

 

两种优化方案:

 

一是,在数据库层面进行排序,让数据库在保持最佳状态下执行SQL 语句;

 

二是,“批量”,较少更新语句,给数据库减压。

 

这两种方案,其实是很多大厂才有能力去做的,像阿里巴巴,在MySQL 内核下进行优化,从而提高数据库能力。

 

不过想批量,后面可以去讲一下,不一定是在数据库层面上去解决。

 

多说两句,在数据库层面上关于库存不能超卖,也有几个小窍门;

 

1.利用事务更新数据,如果数据更新为了负数,进行回退;

2.可以将库存设置为无符号的整数,不可能为负值。

3.where 条件下做优化,库存必须大于要减少的值。

 

很多公司不会像阿里那样有能力在数据库内核下,也有其他手段。

 

热点账户往往是因为更新集中在一条,那么如果有多条不就能分担其压力了?

 

确实是这样的,我们可以将热点账户进行拆分,拆分成多条,同时将库存数分布到众多子账户上,这样高并发情况下,可以达到分流的效果,性能也就上去了。

 

不过拆分热点账户也有很多副作用,如果需要库存整理,当某些账户快要为空时,其他账户库存还有很多;还有最后各账户的库存很少,不能满足下单需求,需要整理众多子账户进行汇总。

 

这些都是拆分子账户带来的副作用,当然了,副作用还是能比如热点账户,还是简单多了。

 

我们再极端一下,拆分子账户当然不能太多,不然带来的麻烦比好处还多,子账户一定时,如果并发还是比较高,又形成了新的热点账户,问题回到了原点,此时该如何?

 

这时候,传统的数据库已经被压榨到了极限,我们需要外援了。

 

nosql该上了,比如redis,我们完全可以将库存数量放到Redis缓存上,一是Redis的并发能力在万的级别,二是其单线程,恰恰是库存更新最好的特性,所以很多公司的活动依靠Redis的颇多。

 

当然了,Redis同样具有副作用,数据存在多份,Redis一份,关系型数据库一份,数据库的一致性问题需要去保证。

 

Redis不代表着容易丢失,只不过相对于数据库来讲差一些,所以会用数据库娄底,不管是以数据库为准还是以缓存,数据都需要保证一致性。

 

讲到这,对于实时性要求比较高的秒杀活动,我们可以使用数据库层优化、拆分子账户、使用缓存等手段进行改进优化。

 

那么对于商户类,可以接受一定延迟的热点数据我们又能怎么办?

 

三、“接受延迟”的热点数据处理方案。

 

先说结果,上面使用的手段,在此同样适用。

 

我们还可以增加两种新方案:异步和批量。

 

只要能接受延迟的,首先想到的就是异步化。

 

对于商户的余额更新,我们可以先将操作记录下来,剩下的慢慢更新,这就是异步。

 

高并发的情况下,我们原来需要实时的进行update这条这点账户,我们可以将一条update语句,变成insert语句,另起线程,将insert语句,进行账户操作。

 

这样的话,插入没有热点,异步将被动变为主动,性能上也上去了。

 

再加上一招:批量。

 

我们可以将多条更新语句,进行合并,例如200条更新合并成100条,瞬间讲操作减少了一半,性能可想而知。

 

几个关键字:拆分子账户、缓存、异步、批量就够了。

 

本文完。

 

 

 

标签:商户,处理,数据库,账户,更新,并发,热点
来源: https://www.cnblogs.com/myf008/p/16182980.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有