双色球有人中了5.7亿,各种怀疑的声音也此起彼伏。有人说停售到开奖直播中间有一段时间是在算出现概率。我对是否在算并不感兴趣,我倒是想知道,如果在算要用什么样子的服务器
,会有多大压力。实际值2012072期销售349310588元,共174655294注。我用一台很老的dell 2850 来试验,双核3.2主频的单cpu,4G内存,ide接口硬盘。 Centos 5.4 64位系统,mysql5。
写个脚本产生随机数来模拟彩票投注。根据投注号产生MD5码,取MD5的前两位作为分表依据。
需要速度,所以开始用C来作,因学艺不精,C写的东西速度很慢,并且也没有找到原因,我将c的代码放在最后,如有朋友能帮忙解决烦请告知。最后还是用python来做。通过初步试验,
产生100万数据并入库需要3分多钟,如果产生1.8亿需要12个多小时。最后决定只产生一张表的数据,一张表数据100万。取MD5前两位,如果每张表都是100万,总共能产生2.56亿注,这个值
可以满足测试要求。
产生表的SQL如下:
CREATE TABLE `dt_00` ( \
`Id` int(11) NOT NULL AUTO_INCREMENT, \
`CreateUnixTime` varchar(13) NOT NULL, \
`RedBlue` varchar(21) DEFAULT NULL, \
`HashValues` varchar(32) DEFAULT NULL, \
`SaleId` int(11) DEFAULT NULL, \
PRIMARY KEY (`Id`), \
KEY `i_RedBlue` (`RedBlue`), \
KEY `i_HashValues` (`HashValues`) \
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
产生投注的脚本如下,因为开始考虑到要放到256张表里,所以就没有做成批量入库,而是做成生成SQL语句,5000条提交一次。:
#!/bin/env python
# ----------------------------------------
# Filename: rand.py
# Revision: 1.0
# Date: 2012-06-24
# Web: http://www.simonzhang.net
# Author: simonzhang
# Email: simon-zzm@163.com
# ----------------------------------------
import random
import time
import MySQLdb
import hashlib
def mysql_run(sql):
try:
db = MySQLdb.connect(host = '192.168.1.41', user = 'double', passwd = 'ball', db = 'doubleball')
cursor = db.cursor()
except MySQLdb.Error, e:
print "Error %d:%s" % (e.args[0], e.args[1])
exit(1)
try:
result_set = ''
cursor.execute('%s' % sql)
result_set = cursor.fetchall()
cursor.close()
db.close()
return result_set
except MySQLdb.Error, e:
print "Error %d:%s" % (e.args[0], e.args[1])
cursor.close()
db.close()
def create_sql():
z = 0
_tmp_di = []
while (z < 6):
red = random.randint(1, 33)
count_rand_di = 0
if len(_tmp_di) > 0:
for i in _tmp_di:
if red == i:
count_rand_di += 1
if count_rand_di == 0:
_tmp_di.append(red)
z += 1
_tmp_di.sort()
blue = random.randint(1, 16)
_result_di = ''
for j in xrange(6):
if j == 1:
_result_di = "%s" % _tmp_di[j]
else:
_result_di += " %s" % _tmp_di[j]
_get_md5 = hashlib.md5("%s+%s" % (_result_di, blue)).hexdigest()
if _get_md5[0:2] == "00":
_create_sql = "INSERT INTO dt_00(CreateUnixTime,RedBlue,HashValues) VALUES (\'%s\',\'%s+%s\',\'%s\');" % (int(time.time()), _result_di, blue, _get_md5)
else:
_create_sql = ""
return _create_sql
def write_time():
_open_file = open("history.txt", "ab")
get_time = time.localtime()
_open_file.write("%s-%s-%s %s:%s:%s\n" % (get_time[0], get_time[1], get_time[2], get_time[3], get_time[4], get_time[5]))
_open_file.close()
def main():
_get_sql = ''
for i in xrange(1000000):
_loop_status = 0
while _loop_status == 0:
_tmp_sql = create_sql()
if len(_tmp_sql) >2:
_loop_status = 1
_get_sql += _tmp_sql
if i % 5000 == 0:
print i
mysql_run("%scommit;" % _get_sql)
_get_sql = ''
if __name__ == "__main__":
write_time()
main()
write_time()
运行完毕使用sql分组统计,查看分组和排序结果SQL如下,运行一次用时6.693秒。
SELECT
count(*) AS c,
RedBlue,
HashValues
FROM
dt_00 d
GROUP BY
d.HashValues
ORDER BY
c DESC
结论:因为要保证速度和稳定,所以购买系统应该是各省有各省的一套系统,然后准实时向中心汇数据,所以汇总需要的时间基本可以忽略。统计是按照分表的方式进行计算,然后在合
并结果,从计算效率来看,如果使用Dell R420高配的服务器,即使只有一台,系统也可以在3-5分钟产生出所有的分析报表(这个是估算,因为不知道需要多少统计表,也不知道需要统计的
逻辑)。如果是用oracle数据库应该会更安全快速。
我写失败的C代码:
#include
#include
#include
/*快速排序*/
void quickSort(int a[],int left,int right)
{
int i,j,temp;
i=left;
j=right;
temp=a[left];
if (left>right)
return;
while(i!=j)
{
while(a[j]>=temp && j>i)
j--;
if(j>i)
a[i++]=a[j];
while (a[i]<=temp && j>i)
i++;
if(j>i)
a[j--]=a[i];
}
a[i]=temp;
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
void main()
{
int i,z;
int red,blue;
int count_rand_di;
int di[6];
char result_di[30]="";
z=0;
while(z<6)
{
srand(time(0));
red=1+(int)(33.0*rand()/(RAND_MAX+1.0));
count_rand_di=0;
for(i=0;i
编译命令:
gcc rand.c -o rand -Wall
参考资料:
http://baike.baidu.com/view/19016.htm