性能&分布式&NewLife.XCode对无限数据的支持
上周发布了《改进版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内存少了些)
网站建立时间:20天
每日访问量:14000IP 12000PV
IIS CPU:0(因为网站的缓存命中率极高)
IIS 内存:200,000k * 3(3个进程)
MSSQL
CPU:0(数据整理子系统写入,网站读取)
内存:500,000k
重要表个数:400(表结构一致,因为数据量大才分表)
重要表数据量:20,000,000(20M*400=8B?80亿?)
数据增长速度:每2小时1万条
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应用程序池回收所致,设为固定时间回收就可以了。
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个对应的连接字符串,重载实体类的查询方法,查询之前动态修改连接名。至于该使用哪一个连接名,就看自己实现的算法了,最简单的就是轮询或者随机。这样子就很轻易的实现了简单的分布式。新版本内置了分布式的提供者,可以根据权重随机分发查询,还可以把数据同时写入到多个目标数据库中去,而这些,都不需要修改业务实现代码。
- Gridview行上下移动自己做的一个小例子(第一种方法)
- Hadoop伪分布式集群安装部署
- sql 表有没有自增列,插入自增列值
- jsp中的JSTL与EL表达式用法及区别(二)
- WPF 给控件添加复制事作
- wpf RoutedUICommand 绑定
- jsp中的JSTL与EL表达式用法及区别(一)
- java线程池模型
- lock小记
- HTML布局的基本要点
- Building a Middle Tier Component using NHibernate and Spring.NET
- Linq 和DefaultView两种方法去掉DataTable 里的重复行
- MySQL事务autocommit自动提交
- wcf webHttpBinding Post 大数据量提交 ios c#客户端
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Keras 切换后端方式(Theano和TensorFlow)
- python 字符串的驻留机制及优缺点
- php微信公众号开发之翻页查询
- php 中phar包的使用教程详解
- php微信公众号开发之快递查询
- Scrapy框架介绍之Puppeteer渲染的使用
- Keras设置以及获取权重的实现
- Java自动化测试(Android app界面元素 33)
- 太厉害了,这款开源类库可以帮你简化每一行代码
- Linux ps和pstree命令知识点总结
- CentOS7上以rpm方式安装JDK8
- linux DMA接口知识点详解
- Linux中使用crond工具创建定时任务的方法
- Linux which命令的具体使用
- Linux安装Python3.8.1的教程详解