discuz论坛大表优化

通过观察,大部分的dz论坛在数据量发展到一定程度,在线人数逐渐提高后,首先锁表的是sessions,这个表我已经写过多种优化的方式,不外乎寻找一些比mysql负载性能好的程序来代替这部分工作。但时间长了,随着在线人数继续增加,那个附加的程序也会面临瓶颈。提高硬件性能和软件性能固然能提高负载,但一旦到瓶颈,必须想其他的方案。

硬件和简约的程序能提高性能,在大数据量下,算法的优势就能体现出来了。

顺便提一下主从:很多人认为主从可以解决问题,其实未必。设想一主多从结构,假如主库写压力很大,那同样压力会同步到从库,会造成N个从库压力同时很大。事实上从库压力会小于主库,因为主库是多进程写,而从库是单进程写, 但总的来说,执行的语句不会少。所以,主从这种结构在一定情况下也就失去了优势。(在硬件资源充裕,压力不是很大的环境下,这种问题发生较少,在硬件条件比较差的一些环境下,这种瓶颈很容易表现出来)

这里拿discuz7的posts表举例,摆脱主从结构,硬件比较差,表很大,10G以上。

一个负载大的dz论坛,在线人数多,又比较活跃,那posts表的压力肯定不会小。在一个回复比较频繁,存储引擎使用myisam的posts表,锁表是经常发生的,我所遇见的问题发生的环境为:数据库单点,无主从,io压力中等。posts表频繁锁表,而造成查询排队,查询速度骤然下降。

在不提升硬件的情况下,要想提速,显然是比较困难的,大量的文本数据装入memcached显然也不合适。所以,这个问题我用优化数据存储的角度对数据表进行了改造。

TIPS:同样100M带宽的集线器和交换机,交换机的吞吐性能远远高于集线器,原因在于:交换机建立专有通道,避免了冲突。

而在mysql中,锁表可以形象描述为冲突了,读写冲突了。但如果我们分表,把读写分散,也许会好点。

分表规则:按照tid进行hash,分散到16个表中。

假设,一读一写,两个操作,同时进行,那么他们撞在一起的几率就是1。如果分为两个表,那么他们撞在一起的几率就是1/2 = 0.5,用一个函数来表示,就是F(x)=1/x ,显然,分的表越多,冲突的机会越小,锁表的几率就越少。即时锁表,影响的也只是1/x的数据,不会对所有的用户造成影响。

数据模型解释:如果是绝对同步发生,几率应该是 F(x)=1/((x-1)*x),但在计算机里,无论两个操作时间间隔多小,在cpu时间片上都是顺序执行,因为,函数我认定为:F(x)=1/x。

以上用数学的方式解释了算法优化对性能的提升。实际上,通过对逍遥论坛的用户行为统计:posts表95%以上的操作都是在读写,搜索和管理占小部分。

补充一种分表算法:在discuzX里,后台启用了分表,我没有细看,大概是把表按照时间段或者其他条件分开。我猜测,作者本意是拆分老数据,主表只留最新数据和一些命中高的数据。这种方式可以起到一定效果,但根据统计,大部分用户习惯浏览回复最新帖子,因此,大部分的读写还是定位到了一张表,也就是没有彻底解决读写冲突的问题。还有一个朋友使用的是顺序分表,500w个pid一张表,但这个方法同上个方法,没解决冲突问题。所以,在他的基础上,我考虑出按照tid进行hash分表的方案。

说到这里,分表又给我们带来了麻烦,有些查询并不能用tid主键进行定位,这里我用了mysql合并表,这个合并表可以合并16个分表,成为一个大表进行查询,而表名依然用原始的表明,这样,dz中原来的功能就不受影响了。

此方案已经实现,我用的新老数据+分别hash的方式,即32张表存储posts数据的方式。但未做压力测试。最近努力学习loadrunner使用,这个压测马上就可以进行了。

少吃点,吃好的。

discuz论坛大表优化

相关文章:

你感兴趣的文章:

标签云: