找回密码
 亲,注册吧

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

查看: 21748|回复: 582

三、Discuz x2.5 效率机制

[复制链接]
发表于 2013-12-24 00:10:41 | 显示全部楼层 |阅读模式
本帖最后由 花花公子 于 2013-12-24 00:13 编辑


MySQL 优化

在整个 Discuz! X2.5 产品中,为了提供效率,需要对 SQL 做相应的优化。有时候不能忽略一些细小的优化,当出现过多未优化的细节时,也能带来致命的负载问题。
延迟更新机制
例如:首页的在线人数等,在实际产品中,有些数据不一定需要实时更新的,因为对于这类型的数据来说,实时更新的价值不高,对于这种情况我们可以考虑在产品研发过程中引入廷迟更新机制,这样可以从一定程度上降低SQL的负载。
索引
索引的合理使用,能给你带来高效的SQL查询,但不是索引越多越好,索引的引入需在查看整个模块的设计,使之最大程度上使用索引。
读写分离
读写分离,在X2的版本中,我们引入了多SQL服务器的支持,在主从服务器中,你可以配置写服务器跟读服务器,这样对于负载高的站点中可以使用这个功能达到读写分离,降低由于写过程序中造成的MySQL表锁定后的SQL排队等候时间过长。当你的服务器支持读写分离要求时,你可以在config_global.php中配置。例如:
  1. /**
  2. * 数据库主服务器设置, 支持多组服务器设置, 当设置多组服务器时, 则会根据分布式策略使用某个服务器
  3. * @example
  4. * $_config['db']['1']['dbhost'] = 'localhost'; // 服务器地址
  5. * $_config['db']['1']['dbuser'] = 'root'; // 用户
  6. * $_config['db']['1']['dbpw'] = 'root';// 密码
  7. * $_config['db']['1']['dbcharset'] = 'gbk';// 字符集
  8. * $_config['db']['1']['pconnect'] = '0';// 是否持续连接
  9. * $_config['db']['1']['dbname'] = 'x1';// 数据库
  10. * $_config['db']['1']['tablepre'] = 'pre_';// 表名前缀
  11. *
  12. * $_config['db']['2']['dbhost'] = 'localhost';
  13. * ...
  14. *
  15. */
  16. $_config['db'][1]['dbhost'] = 'localhost';
  17. $_config['db'][1]['dbuser'] = 'root';
  18. $_config['db'][1]['dbpw'] = 'root';
  19. $_config['db'][1]['dbcharset'] = 'gbk';
  20. $_config['db'][1]['pconnect'] = 0;
  21. $_config['db'][1]['dbname'] = 'ultrax';
  22. $_config['db'][1]['tablepre'] = 'pre_';

  23. /**
  24. * 数据库从服务器设置( slave, 只读 ), 支持多组服务器设置, 当设置多组服务器时, 系统每次随机使用
  25. * @example
  26. * $_config['db']['slave']['1']['dbhost'] = 'localhost';
  27. * $_config['db']['slave']['1']['dbuser'] = 'root';
  28. * $_config['db']['slave']['1']['dbpw'] = 'root';
  29. * $_config['db']['slave']['1']['dbcharset'] = 'gbk';
  30. * $_config['db']['slave']['1']['pconnect'] = '0';
  31. * $_config['db']['slave']['1']['dbname'] = 'x2';
  32. * $_config['db']['slave']['1']['tablepre'] = 'pre_';
  33. *
  34. * $_config['db']['slave']['2']['dbhost'] = 'localhost';
  35. * ...
  36. *
  37. */
  38. $_config['db']['slave'] = array();
复制代码
SQL查询与循环
禁止在循环中进行相应的SQL查询,当遇到这种情况时,可以尽可能的将其转换成循环外的查询。
NOT IN
在SQL查询中禁用NOT IN条件,NOT IN的效率比IN低很多,当使用IN时,也要尽可能的保证IN的数量。
SQL分拆
化繁为简,在优化过程中,尽可能的化繁为简,把复杂的SQL分拆成几个简单的SQL更有种于对整体SQL的优化处理。
PHP 优化
PHP的优点之一是速度很快,但不能因为他的执行效率高而不对PHP的代码进行优化处理。在没有经过优化处理过的逻辑将会拖慢整个程序的执行效率。下面分析几个常见的问题:
文件绝对路径
在includes和requires中使用绝对路径,这样在分析路径花的时间更少。
循环与函数
在循环里别用函数,例如For($x=0; $x < count($array); $x), count()函数在外面先计算。
error_reporting
使用error_reporting(0)函数来预防潜在的敏感信息显示给用户。理想的错误报告应该被完全禁用在php.ini文件里。可是如果你在用一个共享的虚拟主机,php.ini你不能修改,那么你最好添加error_reporting(0)函数,放在每个脚本文件的第一行(或用require_once()来加载)这能有效的保护敏感的SQL查询和路径在出错时不被显示。
循环与嵌套
禁止过多的循环套循环,嵌套过多的循环会拉低执行效率。
循环与查询
禁止在循环内部执行相关的查询语句,除非万不得以,不然千万不可这么操作。
单引号
尽量使用单引号联接字符串。
变量复制
尽可能的减少变量复制操作。例如:$description = $_POST['description']。
switch/case
当if/else过多时,尽可能的使用switch/case 代替 if/else。能够使代码更加简明。
缓存机制
开启缓存机制有助于提升性能,同时降低MySQL负载。
gzip压缩
开启gzip压缩。
功能优化
为了提高产品的性能和效率,除了在MySQL和PHP方面做了优化处理外,Discuz! X2.5更重要的是在功能上进行了大量的调整。
member表优化
当一个数据表的数据量越来越大时,关于这个表的查询和更新操作就会变量越来越慢,为了提高数据库表的响应速度,应该时刻保持表数据的精简。那么如何既不影响正常功能又能保证表数据的精简?我们在十几个注册会员数从几十万到几百万不等的网站进行了一项非活跃用户数的统计,统计结果如下图:
Member.png
统计结果显示非活跃用户数和活跃用户数的比例趋近于82规则,即非活跃用户数占大部分,因此只要我们将非活跃用户进行存档即可大大减少用户表的数据量,提高访问速度。
存档的标准是:
90天之内无访问且帖子数小于5,估算可优化60%以上用户。
程序处理过程:
a、用户在回访时将数据从存档表中转移到主表
b、单用户默认均不兼容处理
     加为好友、打招呼、发短信将提示用户不存在或被冻结
     用户空间、查看用户资料页可正常显示
c、多用户操作默认兼容处理
     好友列表,帖子查看页可正常显示
d、后台用户管理时需要选表操作
post表的优化
在站点运营过程中,常遇到高楼贴的性能问题,比如 limit 187460, 20 。为了解决高楼贴可能出现的问题,Discuz! X2.5 做了如下调整:
1、增加position字段记录楼层,修改主键为:PRIMARY KEY (tid, `position`)联合主键,其中position 为auto_increment。
2、pid字段保留,仍然是auto_increment(单独的一个表),保持唯一,其值在一个单独的表中记录, 保留此字段的主要目的是可以让原程序的基本不用做修改。
使用方法:
SELECT * FROM pre_forum_post WHERE tid=424 AND position>=$start AND position<$end ORDER BY position;
3、抢楼贴和普通的盖楼贴机制统一。
4、删除和审核保留原来的机制,页面显示此楼层被删除或审核中。
点击数优化
在一个站点中,主题浏览量、文章查看数等数据实时更新时,需要频繁的写表操作,从而导致锁表问题。为了解决这一问题,Discuz! X2.5 做了如下调整:
1、增加forum_threadaddviews表,记录每一个TID的增量点击数。
2、查看帖子时,如果增量点击数到100,则使用进程锁将数据更新到thread表并更新增量点击数为0。
3、回贴时将增量点击数和回复数一起更新到thread表,并更新增量点击数为0。
4、执行计划任务:每天3点,5分钟一次,一次取500条数据更新到thread表, 并删除此500条数据,以减少forum_threadaddviews表的大小。
DIY模块更新数据优化
模块聚合数据的灵活性导致SQL语句的条件复杂且不使用索引,MYSQL对数据表的全表扫描,使网站的整体性能急剧下降。为了解决这一问题,Discuz! X2.5 做了如下调整:
1、在查询语句的WHERE条件中增加 id > max(id) - $maxnum。
2、最多扫描$maxnum行数据,产品后台可设置此值,最大是65535。
3、主题、文章、日志模块中添加此功能。
帖子点评和评分功能的优化
Discuz!X2.5 未优化前,查看帖子内容页时,需要分别到点评表和评分表中查询数据,必然产生含有 IN 操作的两条 SQL 查询,影响了站点性能。为了解决这一问题,Discuz! X2.5 做了如下调整:
1、增加forum_postcache表,记录每一个PID的点评列表和评分列表的结果。
2、查看帖子时生成缓存,点评和评分时删除缓存。
3、执行计划任务:每天删除前一天的数据,以减少forum_postcache表的大小。
内存级缓存优化
缓存层的引入是为了解决MYSQL自身对高并发处理的性能瓶颈,目前产品缓存层采用主流的Key-Value对形式,内存级的缓存产品很多,支持的内存优化接口有 Memcache、eAccelerator、Alternative PHP Cache(APC)、Xcache、Redis 五种,优化系统将会依据当前服务器环境依次选用接口,单服务器环境中推荐使用APC,多服务器环境中推荐使用Redis或Memcache。
数据层是以表为单位的类文件,所有表类都继承discuz_table基类,基类实现缓存操 作的相关函数;理论上所有的数据表均可以缓存,目前产品在六个压力大的数据表内置开启了缓存 机制:用户相关表、回帖、主题、主题和专辑关系、淘贴专辑、用户关注关系

用户相关表
数据
缓存KEY
缓存时效
用户相关表
UID
表数据更新时缓存数据会同步更新
回帖
TID
缓存第一页的post数据,表数据更新时缓存数据会同步更新
主题
TID
表数据更新时缓存数据会同步更新(版块列表默认参数第一页时以 forumdisplay_FID 为缓存KEY,缓存时间内数据不更新)
主题和专辑关系
TID
此TID的专辑ID集合,表数据更新时缓存数据会同步更新
淘贴专辑
TID
此TID的专辑集合,缓存时间内数据不更新
用户关注关系
UID
缓存时间内数据不更新

内存级缓存层实现细节
discuz_table基类中缓存机制的实现:
  1. /**
  2. * @var string 缓存主键名前缀,为空时表示此表不支持缓存
  3. */
  4. protected $_pre_cache_key;

  5. /**
  6. * @var string 缓存时间,以秒为单位,0表示永久或相关配置文件中的默认值
  7. */
  8. protected $_cache_ttl;
复制代码

discuz_table 基类中缓存机制的方法
  1. //缓存一个变量到缓存中,如果 KEY已经在则会被覆盖为新值
  2. store_cache($id, $data, $cache_ttl = null, $pre_cache_key = null)

  3. //获取指定KEY的缓存数据
  4. fetch_cache($ids, $pre_cache_key = null)

  5. //清除指定KEY的缓存
  6. clear_cache($ids, $pre_cache_key = null)

  7. //更新一个已经存在的KEY,只更新修改的字段
  8. update_cache($id, $data, $cache_ttl = null, $pre_cache_key = null)

  9. //批量更新缓存,只更新已经存在KEY的指定修改的字段
  10. update_batch_cache($ids, $data, $cache_ttl = null, $pre_cache_key = null)

  11. //重置已经存在的KEY的值
  12. reset_cache($ids, $pre_cache_key = null)

  13. //累加缓存数据中某字段的值
  14. increase_cache($ids, $data, $cache_ttl = null, $pre_cache_key = null)
复制代码








该会员没有填写今日想说内容.
0 该用户已被删除
发表于 2014-5-17 10:45:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-5-17 17:01:53 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-5-18 13:16:29 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-5-19 08:15:49 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-5-20 14:12:11 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

1

主题

269

回帖

273

积分

小学生

Rank: 2

积分
273
发表于 2014-5-21 01:36:25 | 显示全部楼层
看帖回帖是美德!:lol
0 该用户已被删除
发表于 2014-5-22 00:13:31 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

0

主题

1108

回帖

1144

积分

本科生

Rank: 4

积分
1144
发表于 2014-5-23 11:18:37 | 显示全部楼层
不错不错,楼主您辛苦了。。。

1

主题

362

回帖

452

积分

中学生

Rank: 3Rank: 3

积分
452
发表于 2014-5-24 06:52:26 | 显示全部楼层
路过,学习下
0 该用户已被删除
发表于 2014-5-26 05:26:09 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

5

主题

847

回帖

900

积分

本科生

Rank: 4

积分
900
发表于 2014-5-26 19:53:05 | 显示全部楼层
沙发!沙发!

0

主题

363

回帖

364

积分

中学生

Rank: 3Rank: 3

积分
364
发表于 2014-5-27 07:16:34 | 显示全部楼层
不错不错,楼主您辛苦了。。。
发表于 2014-5-28 07:16:22 | 显示全部楼层
我是来刷分的,嘿嘿
0 该用户已被删除
发表于 2014-5-28 18:34:56 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-5-30 00:23:47 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2014-5-31 06:26:14 | 显示全部楼层
好好 学习了 确实不错
0 该用户已被删除
发表于 2014-6-2 00:02:30 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

1

主题

327

回帖

336

积分

中学生

Rank: 3Rank: 3

积分
336
发表于 2014-6-2 10:01:06 | 显示全部楼层
帮帮顶顶!!
发表于 2014-6-3 08:48:52 | 显示全部楼层
学习了,谢谢分享、、、
0 该用户已被删除
发表于 2014-6-4 01:05:43 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-4 09:06:02 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

0

主题

390

回帖

395

积分

中学生

Rank: 3Rank: 3

积分
395
发表于 2014-6-5 03:18:32 | 显示全部楼层
路过,学习下
0 该用户已被删除
发表于 2014-6-6 13:49:19 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-6 21:57:39 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-7 10:08:26 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-8 12:36:47 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-9 05:40:52 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-9 16:00:49 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
0 该用户已被删除
发表于 2014-6-9 19:42:20 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 亲,注册吧 微信登录

本版积分规则

快速回复 返回顶部 返回列表