功能点
因为这是公司的一个项目,不方便透露具体题目。有一个功能点大体上是这样的,这个功能会经常被用户用,我需要做的是每次用户使用我都要对其计数
性能问题
每次访问都需要对其计数+1,多个任务竞争同一条数据,会引起事务行级锁,造成性能及其低下
优化策略及其原理
1、异步处理。
可以对计数操作进行异步处理,考虑到这种情况下会引起大量等待行级锁,用异步处理方式可以优化性能。我使用ActiveMQ处理,但是大家知道,MQ会消息重发出现问题。(这个业务场景下其实不用处理,因为并不需要那么精确的数字),常用的消息重发解决方案是给消息一个编号,已经处理过的编号不再处理
2、分表
很多人可能会问,数据量又不大,分表有什么用?
分表解决这种方案的原理是相当于分摊压力。
来一条请求随机选择一张表进行操作,这样就可以分摊压力。
最后统计结果只需要将各表的数据加起来即可。
3、服务端处理(创建存储过程)
虽然都不太赞成存储过程的使用(不可控性),但这也是一种较好的优化方案
我们来分析一下性能主要浪费在哪儿,如图:
这条业务是这样的:首先我会进行一个数据库查询操作,拿到数据库查询结果之后才要对其进行计数
其中,在客户端去请求查询数据和数据库查询操作,然后等待返回结果才去执行计数操作,这其中就有了大量的网络延迟(据说北京-上海大约需要20ms,如果有1k个并发用户的话时间都很长),可以考虑采用存储过程去进行优化
4、在导师以及组内大佬的建议下,我改用了redis进行处理。大致思路如下:在redis中计数(redis单线程),计数增长到一定数量(比如10000)进行入库。统计时只需要将redis中的值与库中的值进行相加即可