性能&分布式&NewLife.XCode对无限数据的支持

Coordinator
Apr 15, 2011 at 2:16 AM

    上周发布了《改进版CodeTimer及XCode性能测试》展示了NewLife.XCode在性能上的表现。实际上NewLife.XCode是一个很平凡的ORM,只是在分页和缓存方面多下点功夫,注意每一个细节,才能保证在数据量大、业务繁忙的环境中得以保持良好的性能。

    NewLife.XCode所经历过的比较忙的一个系统是一个网吧行业的核心系统,为五千家网吧,一百万客户端提供服务,每天大概有十几万会员多次登录客 户端。当然这一百万客户端不可能同时全部登录。因为业务需要,每个客户端每隔一段时间(几秒)Ping一次服务端,刷新在线记录。只有一台服务器运行服务 端,windows2003,双核CPU,4G内存,自组装共花费7kRMB。因为担心TCP链接数限制,没有采用TCP通讯,而直接使用 WebService+IIS。开了三四个IIS站点,缓存全开的情况下,每个进程占用200M到500M内存。数据库是 windows2008R2+MSSQL2008,四核CPU,32G内存,自组装共花费14kRMB,MSSQL进程占了10G多内存。

    这次的主角是一位个人站长使用NewLife.XCode做的系统(采集+整理+网站),我们先看现状

服务器配置(国外,64位平台,2G内存少了些)

image

网站建立时间:20天

每日访问量:14000IP  12000PV

IIS CPU:0(因为网站的缓存命中率极高

IIS 内存:200,000k * 3(3个进程)

wps_clip_image-26021

MSSQL

CPU:0(数据整理子系统写入,网站读取

内存:500,000k

wps_clip_image-26436

重要表个数:400(表结构一致,因为数据量大才分表

重要表数据量:20,000,000(20M*400=8B?80亿?)

数据增长速度:每2小时1万条

wps_clip_image-7463

SQLite

重要表个数:7

重要表数据量:20,000,000

数据增长速度:每1小时2万条

 

    1,采集子系统,采集到的数据写入一个SQLite,采集过程中也需要查询

    2,数据整理子系统,分析整理SQLite中的数据,归档到MSSQL中

    3,网站根据用户的查询,读取MSSQL中的数据来展现

 

    这个系统是个什么样的规模?昨天站长告诉我,截止下午四点,当天广告收人173刀。

    现在才不到一个月,数据还是很少的。站长所苦恼的地方在于:如何存储这些会无限增长的数据?

 

    以下是站长目前使用的手段:

    1,拆分表。XCode有个武艺(详见《充血模型的ORM能做什么?——ORM组件XCode(十八般武艺)》), 可以动态改变实体类所映射的表名。于是根据数据类别来分表,重载实体类的数据操作方法,查询和写入前,根据当前数据类别计算表名并修改,实现了一个实体类 对应多个相同结构的数据表。并且,如果该名称的数据表不存在,XCode的反向工程会自动创建。使用者一点都不用关心,上层使用代码就跟使用单表一样。

    2,采集和网站数据库分离,开始的时候采集也是写入MSSQL,显然,这会让MSSQL变得很忙,并且会带来因采集而导致网站不正常的风险。

    3,缓存。网站对数据的实时性要求不高,采集而来的数据,可以在一两个小时之后才反映到网站上来。因此,网站打开一级缓存,缓存时间可以设置为1小时。一 级缓存这里不能设为永久,否则就再也拿不到采集到的新数据了,除非进程重启。期间也遇到缓存经常失效的问题,经查是IIS应用程序池回收所致,设为固定时 间回收就可以了。

image

static void TestLog()
{
NewLog log = new NewLog();
log.Action = "Test";
log.Category = "SystemLog";
log.Save();

log = new NewLog();
log.Action = "Test";
log.Category = "UserLog";
log.Save();
}
class NewLog : Log<NewLog>
{
public override int Insert()
{
Meta.TableName = Category;
return base.Insert();
}
}

    这么做,几千张表,每张表两千万的数据,应该是没有问题的了。

    当然,这其中还是有一些问题的

    1,SQLite写入频繁,偶尔发生多线程冲突,XCode中的SQLite提供者增加了失败重试机制,降低了冲突几率,大概万分之一

    2,SQLite数据增长过快,显然,这个问题很严重,但也不是不能解决,XCode除了能动态改变表名,还能动态改变连接名,也就是说,跟拆分表一样,能够轻易的实现拆分库。

    3,拆分库又会带来IO的问题,这个时候,只能使用更多的数据库服务器。

    4,如果网站使用的MSSQL成为瓶颈怎么办?可以使用多个MSSQL服务器,假如10个,配置文件中配置10个对应的连接字符串,重载实体类的查询方 法,查询之前动态修改连接名。至于该使用哪一个连接名,就看自己实现的算法了,最简单的就是轮询或者随机。这样子就很轻易的实现了简单的分布式。新版本内 置了分布式的提供者,可以根据权重随机分发查询,还可以把数据同时写入到多个目标数据库中去,而这些,都不需要修改业务实现代码。

 

    不要怪我们狠(臃肿?),因为我们是充血模型!

 

    http://xcode.codeplex.com/

Jun 4, 2011 at 4:09 AM

非常不错。

Coordinator
Jun 9, 2011 at 3:30 AM
zhujiechang wrote:

非常不错。

谢谢支持,刚上传了大部分X组件的源码!

Jul 23, 2011 at 2:51 AM

谢谢楼主的分享。最近在看XCode

Coordinator
Jul 23, 2011 at 2:52 AM
freshfish wrote:

谢谢楼主的分享。最近在看XCode

希望对你有用!

BTW:欢迎加入我们的群10193406

Jul 29, 2011 at 7:09 AM

已加,我是新手,希望多多学习

Aug 12, 2011 at 3:55 AM

在这里找到了同胞 感动 加油

Coordinator
Aug 12, 2011 at 3:56 AM

欢迎欢迎,加群10193406!