我们的业务比较繁琐,下面举一个简单但是类似的例子说明:
投票
好多投票选项,目前同时触发10w个线程,去做投票,而且都是投的同一个选项,
数据库内容假设为:
”不同意“-----》 此选项有一个字段是 获得投票数。
目前我们是用互斥锁锁住 共享数据库连接 然后去做+1操作,可是,10w的并发线程,测试时发现操作花去了15分钟以上才结束(可能我们在+1前还做了查询大表导致)。
想问问同行,对于这种问题,有没有更加高效合理的建议呢?
最高效的就是在内存中统计
这个肯定不行的,不安全吧,这些数据肯定必须要做持久化的。
@不要理我: 又没说不让你持久化,你可以1s存一次结果。或者1分钟存一次。反正系统不会崩。如果真崩了,那是设计问题
@angelshelter: 嗯,在我这个业务环境下是不允许一次夯机导致数据丢失的,另可业务不发生,也不允许业务发生,但是没有持久化。你的建议倒是一个好建议。
@不要理我: 如果数据很重要,那你就在网站的入口,记住是入口。用日志记录每一个请求。不过这样做要复杂得多。
@angelshelter: 其实我们是有记录的,然后再去做数据纠正是吧,目前有这样子的考虑。但是还是速度太慢的问题。数据的安全和正确性现在没有问题。
造成这个问题的原因是对数据库连接的锁,导致对数据的访问排队。而在系统中,对数据库的访问是一个耗时的操作。解决这个问题,建议在访问数据库前加一个缓存层,节省对同一个对象的数据库查询时间,同时缓冲对数据库的写操作。
这个肯定估计是不行的,读取缓存层,必然导致读脏数据。可能情况是缓存期间一直是1(脏数据)+1 -----》2持久化。
1楼的方法好,在内存中统计,定时写入数据库~
内存记录 ,定时更新到数据库 或者 放到队列,检测队列长度 达到多少时更新一次
嗯,感觉都是一个思路,谢谢大家啊。
试试 disruptor.net 设计用来做在线股票交易的 号称每秒钟处理600万交易