一个瞬间并发量比较大的投票网站的构架。

木川瓦兹 发布于 2013/12/22 16:01
阅读 4K+
收藏 28

基本需求是每个ip一小时限制投票一次。投票用量约500万票以上。投票的瞬间峰值能达到1000票以上。只有一台服务器。不讨论刷票问题。 

其实主要问题在于一小时一个ip只能投票一次的问题上,因ip不固定(尤其有刷票机存在的情况下),在投票前期,投票记录可能在万级以下,这时候把拿到的ip去数据库里比对,速度还是能跟上的,比对此ip超过 一小时了就可以投票了,倒是当记录到达百万级别后,每次select的时间都会变长,加之投票量很大,随时都有可能拖垮服务器,后来我在数据库前面加了memcached,将ip+投票id md5后作为键,值随意进去,然后将数据有效期设为1小时,这样验证ip的任务就交给了memcached,而且到期后数据会自动失效,一举两得。在没设置此应用方案前,投票并发量大约100左右,而且机器资源占用率接近100%,资源大户是mysqld,应用后并发量能达到1000以上,且机器资源占用没有超过50%。 

当然,这个是我遇到的情况,我是这么做的,仅做分享,肯定还有更好的方案,勿喷我。 

后来我分析了一下,其实都是无良的刷票公司干的,一个劲的发请求,而且因http本身机制原因,对方其实每次发投票请求时都可以很方便的改自己的ip。有人说我为啥不加验证码,因为领导想着让刷票,这样票数好看。:-[:-D。后来在程序端加了个逻辑,就是某个ip如果总是请求就直接跳出逻辑,不在进多执行任何代码,但是有时候刷票严重的时候会一直发http请求,导致在看top的时候,满屏的httpd,后来没办法就让程序和系统交互了,把太疯狂的ip直接加到iptables里。但是毕竟系统已经接到请求了,最好的还是在路由器那里写规则禁。如果还不行就得考虑分布式了。 

个人愚见,就当讨论的料吧。大家有什么好的经历以及解决方案,欢迎讨论!

加载中
0
EugeneQiu
EugeneQiu

为啥不加验证码,因为领导想着让刷票,这样票数好看.

hehe.同是苦逼程序员  TAT

0
NealFeng
NealFeng
估计用cookie可以吧。。。不要依赖客户端提供的ip。即使查ip,把每次访问的ip和时间记下来,ip这个字段加索引,查表然后算一下时间,这样应付不来吗? 
fzxu_05
fzxu_05
回复 @飞翔的猴子 : 用缓存。redis memcache ,这点量绝对能扛得住。cookie的东西可以伪造,不要依赖他
木川瓦兹
木川瓦兹
程序上没问题,但是数据库在数据量很大的情况下撑不住
0
星爷
星爷
缓存肯定是要加的,投票通常会涉及到排序,用redis就很方便了
0
朱宏青
朱宏青

设置请求过滤,频繁请求的直接拦了.

将投票的那个页面缓存上,票数也缓存进去,每过一段时间写入一次数据库

用的什么服务器?架构是?


0
温佐镜
温佐镜
缓存(redis)+请求队列
0
蟋蟀哥哥
蟋蟀哥哥

增加javascript token。。机器是没法识别javascript的。

列队,然后批量插入数据。。一次投票,插一次。。太耗性能了

蟋蟀哥哥
蟋蟀哥哥
回复 @edit : token配合session生产,验证用
你是错的我恒对
你是错的我恒对
javascript token 是如何实现的啊 前辈?
木川瓦兹
木川瓦兹
嗯 是滴 也可以考虑多条数据一次性插入
0
光石头
光石头
重写sessionid生成方式即可,ip+小时时间+是否投票。
0
纠结名字
用js多做些校验,拦截,但是就是不给提醒,让他投,伪装提交。
0
水木

用下百度的RANK,有惊喜。

===========================================

单说你这个项目,个人觉得以下几点可做适当优化,由简单到复杂:

1.优化前台,增加JS防止本地频繁刷新,控制时间,防止本地重复提交
(大部分机器是不禁用JS的,不放心可以先对你的目标用户机器做JS调查)

2.增加COOKIE验证,记录机器ID,这样就不存在来回更换IP的问题了,不放心也可做COOKIE调查,和JS一样(绝大部分机器是不禁用JS的,禁用的直接都给他灭了)

3.优化代码,数据结构,可以再把更多的压力丢给MC,
PS:这点东西做的好可以不用数据库,简单点的投票直接在MC里面都给办了,数据库只起一个防雪崩的作用

4.更换数据库,处理投票这样的事务关系型数据库劣势明显,换用NOSQL会有很好的效果。
PS:我觉得这样的应用数据库是毫无压力的,数据全部在MC里面定时写入数据库,也不存在任何读取压力,按照时间周期去读,MC里面做个CACHE。

以上几步做完,提高两个数量级应该不是问题。数据库应该毫无压力,500万的投票,写数据超过5000次就算败了,除非你要详细的LOG记录。

===========================================

按照你目前的架构,只要增加COOKIE,修改MC结构两项,一小时投掉500万票应该不是问题,做个测算,
1个小时投掉500万票,每秒是1388票,按照每有效票被刷10次,累计就是15277每秒的并发,不到2万的并发单台机器绝对扛得住的。

以上数据测算的数量级业务我都做过,唯一没有验证的就是memcached,我不知道memcached到2万并发会不会跑崩掉。

木川瓦兹
木川瓦兹
嗯 写的真不错,方法也可以尝试。下次再有机会我试试。
返回顶部
顶部