上节回顾:
上节 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五) 中,
介绍了 秋色园QBlog 在性能优化方面,从技术的优化手段,开始步入数据库设计优化,并从数据的使用情况上进行了分析,从而将文章内容进行分离,得到新的分表,由于内容比较大,进而分了库,达到一种基础减压。
本节内容:
描述说明:
在进行上了上节的分库方案后,虽然感觉一度秋色园QBlog的访问速度是花拉拉的。
[PS:当然国际线路引起的丢包或DNS域名解析缓慢就另一回说了,特别是最近ping www.cyqdata.com 经常性超时,我很纠结;
另外:有些地区在域名解析上也出现访问速度慢的,所以特别增加了IP访问方式,于是现在用IP也可以直接访问秋色园了。]
但是,花拉拉的速度,那仅是外在的表现,在晚上三四点优化好方案后,感觉花拉拉,终于可以安心入睡了。
第二天早上10点多,睡梦中,带着一丝忧心,用手机访问了一下秋色园QBlog,发觉竟然访问不了。
于是一下子又从床上跳了起来,赶紧开机,进vps,一看:QBlog.ldb文件产生了,黄金4K的ldb文件产生了。
而且看样子似乎已经N小时不退了,那个纠结,仅有重启IIS,短暂性的解决了这问题,接下来又得忙碌了。
对于秋色园QBlog的当前情况,我们可以进行以下的想象:
当内存回收时:[就算用户访问不多,搜索引擎也会来访问,而且是到处抓的]
根据秋色园QBlog的方案,将产生很多读取access数据库的操作:比如:
A:失去缓存的抵抗,虽然首次访问有静态html挡着,但是,后台线程产生新的界面生成的随机概率增大了,也即时说,后台线程操作数据库的开始频繁了。
B:有部分页面是没有设置生成静态页面的,因此,直接就产生数据库的操作。
C:用户计数器和文章点击计数器,也在不时的概率性更新着数据库。
于是:当这些操作集中发生在一很小的时间段的时候,小小的access将同时产生很多的并发操作。
再于是:4K的QBlog.ldb文件产生了,内部死锁解不开了。
于是的于是:纠结的悲剧的一幕产生了,秋色园QBlog打不开了。
于是的于是的结果:又再一次悲催着优化的步伐,你得继续优化。
Access并发极限的分析
在写此文前,我做了一个小小的代码测试,通过这个小测试,终于解惑了我对access究竟支持的是怎样的并发和黄金4K的.ldb文件的概念。
这个测试很简单:
1:每Open打开一个Access链接后,我就让它Sleep100秒:就是打开就不关闭了。
2:开多个线程,同时去Open链接:模拟并发请求。
3:观看产生的.ldb文件:结论靠观察。
终于,我看到了一个直观的过程:
1:打开1个链接时,产生一个.ldb文件,而且这个.ldb文件大小是64个字节。
2:打开2个链接时,产生一个.ldb文件,而且这个.ldb文件大小是128个字节。
3:打开3个链接时,产生一个.ldb文件,而且这个.ldb文件大小是192个字节。
......省略......
4:打开64个链接,产生一个.ldb文件,而且这个.ldb文件大小正是黄金4K。
5:打开65个链接,报错了,再往后,全错了。
如果这是access单个数据库极限并发的答案,总结就是:
access最大支持同时打开64个链接,每个链接产生64个字节,看到黄金4K的.ldb文件,说明极限到了。
而且,这是一个数据库的极限,因此,你想获得更大的并发数,不是分表,而是分库。
以上是对一个数据库的最大极限测试,那会不会对数据库的单个表存在着最大极限并发?
带着些许疑问,我又把示例稍为改了一下,进行单表的最大并发测试:
1:产生64个线程,即同时打开最大的数据库并发链接。
2:每个链接,都内建死循环,while中不断的更新着同一条记录。
3:观看有没有异常产生,同时数据库记录是不是正常更新着。
终于,我又看到了一个直观的过程:
1:没有异常产生。
2:记录在正常被更新着。
如果这是access单个表极限并发的答案,总结就是:
PS:如果一个链接内,再开N个线程去更新,结论又会是怎样呢?这问题似乎不太重要,有需要知道的大伙自己写示例了。
写到这里,大伙能理解access了吧,你想象一下:
1:一个页面从上到下,那得open几个链接?当然,如果没忘了关链接,一般是顺序下来的算1个。
2:能支持同时并发打开几个页面呢?1个页面算1个,最大64个?是64个,但这个不是1秒,而是取决于1个页面的执行时间,如果你5秒打开1个页面,基本就是64/5=13了。
4:那些没完没了的搜索引擎,也是和正常用户一样不断的请求的,你别忘了?除却搜索引擎,你还剩下几个请求?如果同时来了6家搜索引擎,那就剩下13-6=7,也就是有8个人访问,你就挂了。
当然了,瞎扯扯就这么算并发,实际也没算的这么准。
所以,用access的基础策略是:
1:静态化:特别适合实时性不强的,一次生成终生不变的。
2:特别适合单用户的:因为就一个人发信息,不可能产生并发写问题,加上前面静态化,很合适。
3:特别情况-缓存技术:一般用access的都会弱化用户统计或文章统计,因为这个更新,意味着占用一个链接,多来几个也会挂,因此文章统计和用户访问统计,要么关闭,要么得花点心思动点手脚。
4:分库策略:能增加并发最大数,1个64,我用100个,就是64*100了,团结就是力量啊,当然这么大个军团,不好管理,需要一定的管理策略和算法。
5:其它的你自己想了......
秋色园QBlog的超级分库分案:
先看一张图片,看一下秋色园QBlog 现在有几个access数据库:
说明:
数了一下,有8个,常用的基本都是一个表一个数据库,不常用的就还在一起一个数据库。
其实,秋色园QBlog 的分库,都是在写这篇文章之前分的,也就是说,当初分库的时候,我并不知道access的最大极限。
虽然我曾一度的百度及google过access的并发数或性能上限,但是,出来的网页结果,都没有我要的答案,于是我仅靠猜。
每次我见到秋色园QBlog打不开时,我都可以清楚的见到qblog.ldb文件,黄金4K的ldb文件,一开始我以为是4个并发锁住了。
于是我也曾搜索去找到ldb的相关答案,可惜,仍找不到我要的答案,但是我知道黄金4K的ldb文件这个问题很严重。
于是,在秋色园QBlog 那个漫长的过程中,我是一步一步的分的库,因为缺少真实的理解,我靠想象与猜测是某个表产生了死锁引起的,因此我的第一理念,是把某个表分离出来。
因此,虽然现在你看到有8个库,但这不是一次分出来的:
实际是某当qblog.mdb这个主库遇到黄金4K最大锁时,我就在怀疑某个表,然后就把某个表分出一个库出来;
然后感觉又好了,再过不久,又出来黄金4K最大锁,我又在怀疑是不是某表又锁了,又分出了一个库;
于是过了好长时间的如此如此般的重复,才最终形成这样的分库结果。
PS:在发布的CYQ.Blog(QBlog) V3.0 单用户版本中,虽然发布的是一个数据库,但是,隐藏着更高性能的分库功能,即是说,如果想再提升性能,你还可以分库,然后分一个库补充1个链接即可。不过单用户版本,V3.0的性能已经够强悍了,而且同时还支持着多种数据库。
分库的功臣,Access链接表
在分库的过程中,不得不提到Access的链接表,如果没有它,分库真的难以想象的复杂。
复杂在何处?当然是代码的修改了,你能想象分布在两个数据库间的表链接查询?
分库步骤(示例分库用户表Blog_User):
1:新建一数据库:qbloguser.mdb。
2:打开qbloguser.mdb,菜单:文件->获取外部数据->导入,选择qblog数据库,将用户表导进来,完成表的分库转移。
3:打开qblog.mdb,删除用户表,然后菜单:文件->获取外部数据->链接表,从qbloguser.mdb中将用户表链接过来。
OK,1分钟内完成分库并链接表,至此,并没有代码逻辑的修改,但是,仅是这样的分库,是无意义的。
因为并有没散链接,操作用户表时,还是操作的qblog.mdb数据库,压力并没有分散。
代码调整,分散单表操作的压力
代码还是需要调整,首先将表枚举分出来:
public enum U_QBlogUserEnum
{
Blog_User,
}
因据 CYQ.Data 的多数据库应用的约定,此表的数据库链接将转向配置项为QBlogUserConn项。
因此,仅需要多配置多一条数据库链接指向qbloguser.mdb即完成了。
当然了,原来TableNames.Blog_User语句,批量替换成U_QBlogUserEnum.Blog_User就可以了。
再当然的话,代码也不可能只改动这么小,因为,必须兼容一个库的情况,比如CYQ.Blog(QBlog) V3.0发布时,
实际是支持分库操作的,但是最终发布是一个库发布的,因此,兼容的链接也必须处理。
再有一个提示,就是CYQ.Data 的ResetTable切换表操作功能,由于链接取的上一个,因此在分库的情况下,每个表都是不同的链接,因此ResetTable的表操作,必须独立出来操作。
强大的 CYQ.Data 数据框架(新提示:V4.0 以下版本免费且开源),仅靠提取表枚举头部,就能自动切换数据库,达到多数据库应用。
于是,秋色园 QBlog 的Super分库的策略,由此轻松的完成了。
最终形成的数据库链接如下:
压力分散是什么情况:
1:单表操作,分散到独立的数据库链接中,如qbloguser.mdb。
2:多表操作,直接操作的qblog.mdb的链接表。
3:每个库都能同时支持64个并发链接。
总结
虽然秋色园 QBlog 整个的分库策略,是长时间一步一步分的库,由于原理是一致的,因此此文就一次性上齐了。
而且写此文前进行的示例测试,有效的为自己和大伙解开access的并发上限之惑,
同时也解答了,多数库分库的确带来并发上的好处。
然而分库再怎么厉害,一个库也是支持最大64个链接并发打开。
虽然:CYQ.Data 用Lock锁住插入/更新/删除,这些步骤,使的同一时间只出现一个链接打开。
但是,通过今天的示例,发现了,读取,也是要打开链接的。
因此,优化并没有止步,本系列还在继续,请继续关注。
顺路一提:秋色园已增加了博客绑定一级域名(顶级域名)功能,欢迎感兴趣的try 1 try.
绑定顶级域名教程:http://www.cyqdata.com/qblog/article-detail-41316
历史文章回顾:
1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用
2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程
3: 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三) --介绍如何实现无后缀URL
4: 秋色园QBlog技术原理解析:UrlRewrite之URL重定向体系(四) --介绍URL如何定位到处理程序
5: 秋色园QBlog技术原理解析:Module之页面基类设计(五) --介绍创建基类和自定义生命周期
6: 秋色园QBlog技术原理解析:Module之页面基类-生命周期流程(六) --介绍基类生命周期内部业务
7: 秋色园QBlog技术原理解析:Module之基类生命周期-页面加载(七) --介绍界面html加载原理
8: 秋色园QBlog技术原理解析:Web之页面处理-内容填充(八) --介绍html的内容是如何填充
9: 秋色园QBlog技术原理解析:独创的多语言翻译机制(九) --介绍html多语言翻译原理
10:秋色园QBlog技术原理解析:页面内容填充及多语言翻译流程演示示例(十) --总结演示示例代码
11:秋色园QBlog技术原理解析:页面Post提交机制(十一) --介绍如果Post提交数据
12:秋色园QBlog技术原理解析:性能优化篇:字节与缓存与并发(十二) --介绍性能优化:字节,并发及缓存
13:秋色园QBlog技术原理解析:性能优化篇:全局的SQL语句优化(十三) --介绍全局掌握SQL,进行针对性优化
14 :秋色园QBlog技术原理解析:性能优化篇:缓存总有失效时,构造持续的缓存方案(十四) --介绍二次缓存方案
15:秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五) --介绍内容分库减压
附章:
1:秋色园QBlog技术原理解析:博客一键安装工具技术实现[附源码下载] --开源秋色园安装工具原理
PS:秋色园QBlog下载地址:http://www.cyqdata.com/download/article-detail-427