代码改变世界

.Net架构网站遇到大表该怎么办?

2009-06-12 09:16  周国选  阅读(555)  评论(2编辑  收藏

最近做的web2.0网站本身遇到一个大表(千万rows左右),因为对于performance,web本身可用性的考虑,必须想办法boost perf.

这种情况应该都用partition来搞定了,这也符合分治等算法的思想,想办法降低问题本身的复杂度,然后在一个一个解决。

mysql中一般到100万操作就有点麻烦了,index要好好的做。这里还遇到了一个文本检索问题,MyIASM storage engine里面有个full-text index,但是不知道

它对于中文支持如何,而且不清楚它是怎么分词的,不大清楚后台逻辑,Mysql这种index limitation很多,很难scalable,所以基本上直接考虑用search engine那一套。直接上了lucene+solr+solrsharp.小表like还可以忽悠忽悠,大点就慢的如老牛....

Partition通过了解发现解决方案倒是不少,结合了以前做过一点这方面知识储备。

对hivedb,hscale等都没想过要尝试,发现.net在使用open source很多都不是很舒服。

最开始尝试了mysql partition,一开始听起来方法这种方案很Perfect!是mysql解决horizontal partioning的很好方案,等document看完了,发现

5.1版本的partion limitation太多了,只能适合某些特性的场景,例如按照用户id做split;普通那种非unique key,primary key是很难搞定的,简单方法是给表本身

不添加任何主键,自己来实现主键生成机制。这样仿佛可以了,但是通过explain partitions来做下analysis,发现结果定位具体parition不好,这就很难降低IO本身的高成本了。没有通过具体测试不知道可能是explain partition本身不准确原因还是。。。

mysql partition还有一个很大的弊病,就是很难跨机器,当然如何能够把Mysql存储做成分布式,也还好,但是这个技术代价都上了不少档次,risk过高了,只能算是下下策了,备用好了。这些不爽的地方导致偶们直接抛弃了这种方案,直接用手工切分来搞定这种问题,我想这也是大部分这种需求的常见solution把。

手工切分本身技术还比较简单,就是要考虑表的编码,管理等多个方面,以及如何快速定位到可能的partition,这些在设计方面都应该注意了。

而且对于多partitions的结果,应该使用多线程等并发,同步技术来提高perf.

这里的partition还做到支持对某一个partition做进一步切分,这样切分到每一个partition块尽量表中数据在50万以下,这样加上db index,速度应该能够满足一定的需求的,手工切分本身很容易scale out,可以把表放在不同的机器上等等load balance方法来scale.

回想感觉最有意思还是表编码自身的考虑有点意思,我很大程度的灵感来源于IP地址的划分,因为这个表自身增长速度会很慢,所以采用unsigned int来搞定,43亿来表示2000万还是小意思嘛。我主要是通过前缀+长度来定义表的标识。1,2,3前缀可以让给数据比较密集的表,因为它们可以支持10位,其它就用9位来表示,可能有些不再切分范围内的就让他们从0开始增长把。这里partition list本身维护可以序列化到filesystem中,每次Load class时候deserialize一下,然后就是本身partition如何快速定位就需要用点复杂点的data stuctures了。