刷投票脚本 pick王菊?作为“菊外人”的程序员能做点什么?

11/28 06:19:17 来源网站:辅助卡盟平台

当采用以上的update语句时刷投票脚本,基本可以满足简单的票数的递增。但是,一旦有高并发场景的话,就无法满足了。因为多人同时执行这个语句的时候,就会有的人的更新结果丢失。

这时候,就需要引入锁机制来处理。比如我们增加乐观锁,改进后的update语句如下:

1update table_user_polls set polls = polls +1 where user_id = "1000" and polls = 1000000;

在更新table_user_polls表的polls字段的时候,我们先把表中当前的polls值取出,然后作为乐观锁来控制更新,如果发生并发,只会有一个请求可以更新成功。其他请求就会更新失败。

但是,紧接着又有两个问题来了。

数据量太大 ?

如果数据量太大怎么办?比如这场“全民Pick王菊”的行动,参与的用户可能有很多很多,而我们要对每个用户的投票数据都持久化下来。这就涉及到一旦数据量过大,就会导致数据库的读写性能急剧下降。

传统的做法是进行分库分表,把投票表按照一定的维度进行拆分。比如这种投票的场景,我们可以按照投票的用户的userId拆分,对userId取模,根据结果存储到不同的表中。如把所有投票数据拆分到8个库128张表中,路由规则就是userId8。

其实,这种单纯的分库分表还有一个另外的问题,虽然投票场景中可能涉及不到。1、热点数据问题。如多个热点用户的数据都分到了同一个库甚至同一张表中,就会又给数据库带来巨大压力。2、数据的二次分表问题。一旦分表数量不够了,就要再次分表。比如把128张表扩展到256张表,这就麻烦了,需要对原来的1287张表中的数据重新进行拆分,数据迁移到新的256张表中。

访问量太大 ?

通过分库分表之后,我们暂时解决了数据量大的问题,那么如果遇到访问量大的问题怎么办。无论是我们的应用、服务器还是数据库等,能承受的QPS(TPS)都是有限的。如果峰值的qps超过了限制,就有可能导致整个系统瘫痪。

那么如何提高一个服务或者接口的QPS呢,其实一个最简单的方法就是降低响应时间(RT)。当然RT和QPS的关系还会受最佳线程数等影响,但是降低RT也是一个比较有效的办法。如果一个请求,在执行过程中,什么都不需要需要等待,每个操作都可以快速执行(如单纯的在内存中取数、计算等),那么RT就会低很多。

在程序中,导致请求阻塞的愿意可能有很多,数据库操作可能是其中比较重要的一部分。虽然我们通过分库的方式增加了数据库的连接数,但是直接操作数据库还是有很大的性能损耗的。

这时候,就要考虑在持久化存储前面增加缓存了。在访问数据库之前先访问缓存,如果缓存中没有的话再访问数据库。这样可以减少请求的响应时间,从而提高QPS,进而承载更大的访问量。

这样做有很大的好处,但是也不是完美的方案。比如这种投票系统,计数更新是非常频繁的,所以要经常失效缓存在重新缓存,缓存和数据库之间的数据一致性问题就体现出来了。

以上,是通过MySql来进行计数的方案,总结一下:

优点:便于理解、学习成本低、开发成本也低。 缺点:对大数据量和高并发量支持不友好。

基于Redis计数

Redis 是目前 NoSQL 领域的当红炸子鸡,它象一把瑞士军刀,小巧、锋利、实用,特别适合解决一些使用传统关系数据库难以解决的问题。

如果我们使用Redis来实现计数器的话,就相对来说简单一些了。因为Redid提供了一个INCR命令,其使用方法如下:

1redis> SET wangju_polls 20
2OK
3
4redis>
INCR wangju_polls
5(integer) 21
6
7redis>
GET wangju_polls  
8"21"

    暂无相关资讯
刷投票脚本 pick王菊?作为“菊外人”的程序员能做点什么?