前言:
在 PHP+MySQL架构的站点中,本文重点从MySQL的角度去分析如何使Discuz!论坛(或者类似的PHP+MySQL架构的程序)应对大访问量。 同时给出一些使用Memcache去减轻MySQL压力的建议。其中很多数据是个人测试的结果,如有不同意见,敬请留言告之。另外由于个人思维的问题,行 文比较跳跃,特此声明!
系统分析:
单纯的从MySQL的角度出发,单台MySQL的数据库负载 到每天上亿次的操作(每秒大概1100次MySQL操作,然后乘以86400)应该不是非常困难的事情。按照这个数据也就是说一个单MySQL服务器的论 坛来说可以跑到2千万PV是不成问题的,我相信国内绝大部分的论坛都不可能做到每天2千万的PV,但实际情况并不是如此。当论坛PV超过百万的时候一台 WEB早已经不堪重负了。
就我手头的一些数据显示,目前的Discuz!论坛的基本服务器架构是前面Squid顶着,后面才是一台DB在撑 着。这种架构中,web服务器压力增大可以通过并行增加服务器解决,而MySQL压力却无处释放,在不考虑MySQL官方服务的情况下,我们通过合理的利 用Memcache是可以达到减轻MySQL服务器负载的。
可能会有朋友说我们可以对数据表进行分表(注:此处分表是指通过PHP程序去分表,比如pw,dv的分表)处理,但是当前的情况是一台DB服务器已经不能支撑当前的数据处理了,通过PHP对MySQL进行的分表依然不能减轻MySQL的负载。(注:本段文字针对已经成型的系统,如果是独立开发的系统在架构前期就进行数据的同步分区还是不错的。)
还 可能有朋友会说利用MySQL的主从构架,如果你提出这个问题,我就很明确的告诉你,回去看看手册吧。在Mysql Master/Slave 模式中,Slave主要是来备份数据的,只有当Master出现故障时,Slave才会接过Master的服务,对外部请求进行处理,直到Master恢 复正常。就是说:在Master/Slave中,要么是Master在服务,要么是Slave在服务,不会Master/Slave同时提供服务。使用MySQL主从依然不能有效的降低MySQL的负载。
或许你又会问我为什么不使用MySQL集群(MySQL Cluster),那可是白花花的银子啊,同等金钱的付出下,获得最大的收益才是王道。PS:说句题外话,MySQL手册中将MySQL集群解释为MySQL簇,不习惯。
其 实在MySQL5.1中的MySQL分区(MySQL Partition)是个很好的东西,它允许根据可以设置为任意大小的规则,跨文件系统分配单个表的多个部分。实际上,表的不同部分在不同的位置被存储为 单独的表。我认为这个才是当前情况下,最积极有效的降低MySQL负载的解决方法之一。但是遗憾的是,这种MySQL分区的方式我个人没有使用过的经历,也不见有相当充分的案例表明它是稳定的或者不稳定的。所以我还在徘徊中。如果你知道,请麻烦告之!有朋友说腾讯是在用MySQL分区,但是遗憾的是我没有得到确切的数据。
好了分析总结了这么多种降低MySQL负载的方式之后,在用户环境需求等特定条件下,我得出结论在当前情况下,缓解Discuz!论坛的MySQL负载比较有效的方法就是使用Memcache!
使用Memcache的理由:
1.Web Server(Lighttpd、Nginx据说都比Apache效率高好多,大家可以试用下)对CPU要求高,对内存要求低;而Memcached Server是对CPU要求低,对内存要求高,所以可以搭配使用。在对前端的Web Server上安装Memcached Server是可行的。
2.金钱金钱金钱,最少的付出,获得最大的收益。
3.简单简单简单,对于一个架构合理的系统来说,添加Memcache的支持可能只是一个批量处理文件的过程
Discuz!使用Memcache
1.在config.inc.php中增加
$memcacheport = 11211;
$memcachelife = 60;
2.在include/common.inc.php中
$mem = new Memcache;$mem->connect($memcachehost, $memcacheport);
3.修改include/db_mysql.class.php中的fetch_array、query这两个方法,并添加query_mysql方法,代码如下:
function fetch_array($query, $result_type = MYSQL_ASSOC) {return is_resource($query) ? mysql_fetch_array($query, $result_type) : $query[0];
}
function query_memcache($sql, $type = '') {
global $mem,$memcachelife;
$key = md5($sql);
if(!($query = $mem->get($key))) {
$query = $this->query($sql, $type);
while($item = $this->fetch_array($query)) {
$res[] = $item;
}
$query = $res;
$mem->set($key, $query , 0, $memcachelife);
}
return $query;
}
function query($sql, $type = '') {
global $debug, $discuz_starttime, $sqldebug, $sqlspenttimes;
$func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?
'mysql_unbuffered_query' : 'mysql_query';
if(!($query = $func($sql, $this->link)) && $type != 'SILENT') {
$this->halt('MySQL Query Error', $sql);
}
if(substr($sql, 0, 6) == 'SELECT') {
echo '<font color="red">Cache SQL</font>:<font color="green">'.$sql.'</font><br /><br />';
} else {
echo '<font color="red">Flash SQL</font>:<font color="green">'.$sql.'</font><br /><br />';
}
$this->querynum++;
return $query;
}
4.将需要使用Memcache缓存的SQL查询的代码由
$db->query(修改为
$db->query_memcache(注意并将
while($post = $db->fetch_array($query)) {修改为
foreach($query as $post) {没有while的$db->fetch_array可以不用修改。
下面代码有用得着的就拿去:
preg_replace("/while\([$](\w+)\s*\=\s*[$]db->fetch_array\([$]query\)\)/is", "foreach(\$query as \$\\1)", $file);回头放出个小工具批量替换下就可以了。
在EditPlus中可以这样替换:while\([$](.*) = [$]db->fetch_array\([$]query\)\)替换为foreach($query as $\1)
5.完成了,测试吧!~
附:Linux下的Memcache安装-------------------------------------------------------------
服务器端主要是安装memcache服务器端,目前的最新版本是 memcached-1.3.0 。
下载:http://www.danga.com/memcached/dist/memcached-1.2.2.tar.gz
另外,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent,libevent的最新版本是libevent-1.3。(如果你的系统已经安装了libevent,可以不用安装)
官网:http://www.monkey.org/~provos/libevent/
下载:http://www.monkey.org/~provos/libevent-1.3.tar.gz
用wget指令直接下载这两个东西.下载回源文件后。
1.先安装libevent。这个东西在配置时需要指定一个安装路径,即./configure –prefix=/usr;然后make;然后make install;
2.再安装memcached,只是需要在配置时需要指定libevent的安装路径即./configure –with-libevent=/usr;然后make;然后make install;
这样就完成了Linux下Memcache服务器端的安装。详细的方法如下:
1.分别把memcached和libevent下载回来,放到 /tmp 目录下:
# cd /tmp
# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz2.先安装libevent:
# tar zxvf libevent-1.2.tar.gz
# cd libevent-1.2
# ./configure –prefix=/usr
# make
# make install3.测试libevent是否安装成功:
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3
-rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3
-rw-r–r– 1 root root 454156 11?? 12 17:38 libevent.a
-rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3
还不错,都安装上了。4.安装memcached,同时需要安装中指定libevent的安装位置:
# cd /tmp
# tar zxvf memcached-1.2.0.tar.gz
# cd memcached-1.2.0
# ./configure –with-libevent=/usr
# make
# make install
如果中间出现报错,请仔细检查错误信息,按照错误信息来配置或者增加相应的库或者路径。
安装完成后会把memcached放到 /usr/local/bin/memcached ,5.测试是否成功安装memcached:
# ls -al /usr/local/bin/mem*
-rwxr-xr-x 1 root root 137986 11?? 12 17:39 /usr/local/bin/memcached
-rwxr-xr-x 1 root root 140179 11?? 12 17:39 /usr/local/bin/memcached-debug
安装Memcache的PHP扩展
1.在http://pecl.php.net/package/memcache 选择相应想要下载的memcache版本。
2.安装PHP的memcache扩展
tar vxzf memcache-2.2.1.tgz
cd memcache-2.2.1
/usr/local/php/bin/phpize
./configure –enable-memcache –with-php-config=/usr/local/php/bin/php-config –with-zlib-dir
make
make install
3.上述安装完后会有类似这样的提示:
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-2007xxxx/
4.把php.ini中的extension_dir = “./”修改为
extension_dir = “/usr/local/php/lib/php/extensions/no-debug-non-zts-2007xxxx/”
5.添加一行来载入memcache扩展:extension=memcache.so
memcached的基本设置:
1.启动Memcache的服务器端:
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid
-d选项是启动一个守护进程,
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,
-u是运行Memcache的用户,我这里是root,
-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid,
2.如果要结束Memcache进程,执行:
# kill `cat /tmp/memcached.pid`
也可以启动多个守护进程,不过端口不能重复。
3.重启apache,service httpd restart
Memcache环境测试:
运行下面的php文件,如果有输出This is a test!,就表示环境搭建成功。开始领略Memcache的魅力把!
< ?php
$mem = new Memcache;
$mem->connect(”127.0.0.1″, 11211);
$mem->set(’key’, ‘This is a test!’, 0, 60);
$val = $mem->get(’key’);
echo $val;
?>
Windows下的Memcache安装-------------------------------------------------------------
很多phper不知道如何在Windows下搭建Memcache的开发调试环境,最近个人也在研究Memcache,记录下自己安装搭建的过程。
其实我开始研究Memcache的时候并不知道居然还有memcached for Win32这个鸟东西,害得我在CnetOS下折腾1天才搞定,今天突然发现Windows下的Memcache进行开发调试完全没有问题,所以写篇Memcache的文档分享给大家。
Windows下的Memcache安装:
1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached
2. 在终端(也即cmd命令界面)下输入 ‘c:\memcached\memcached.exe -d install’ 安装
3. 再输入: ‘c:\memcached\memcached.exe -d start’ 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
4.下载php_memcache.dll,请自己查找对应的php版本的文件
5. 在C:\winnt\php.ini 加入一行 ‘extension=php_memcache.dll’
6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!
memcached的基本设置:
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
Memcache环境测试:
运行下面的php文件,如果有输出This is a test!,就表示环境搭建成功。开始领略Memcache的魅力把!
< ?php
$mem = new Memcache;
$mem->connect(”127.0.0.1″, 11211);
$mem->set(’key’, ‘This is a test!’, 0, 60);
$val = $mem->get(’key’);
echo $val;
?>
相关推荐
Java Memcache 缓存实现是将高性能的分布式内存对象缓存系统Memcache应用于Windows环境中的技术。Memcache是一个用于存储各种类型数据的高速缓存系统,包括但不限于图像、视频、文件和数据库查询结果,它的核心原理...
本文将详细介绍如何在Java中实现Memcached缓存,并探讨相关API的使用。 1. **Memcached Java Client API** - `SockIOPool`: 这个类负责管理连接池,它提供了设置服务器地址、权重、连接数等方法。例如,`...
下Memcache缓存实现方法】 在高访问量的PHP+MySQL网站中,如Discuz!论坛,应对海量用户访问是一项挑战。本文主要探讨如何通过Memcache缓存技术来减轻MySQL数据库的压力,从而优化系统性能。Memcache是一种高性能的...
在本主题中,我们将详细探讨Memcache缓存技术,特别是针对PHP5.2.6版本的配置以及在Windows操作系统的应用。 首先,理解Memcache的基本原理至关重要。Memcache的工作机制是在内存中存储数据,当应用程序需要访问...
### Java版Memcache缓存管理与开发 #### Memcache简介及其在高流量网站中的作用 在高流量网站中,为了缓解数据库的压力并提高网站响应速度,通常会采用Memcache作为缓存解决方案。Memcache是一种高性能、分布式...
在标题提到的“memcache缓存分布式集群”中,主要涉及以下知识点: 1. **分布式存储原理**:分布式存储是将数据分散存储在多台独立的设备上,以提高系统的可扩展性和可用性。Memcache分布式集群就是通过将数据分散...
1. **Web应用加速**:对于高并发的Web应用,使用MemCache缓存常用数据,可以显著减少数据库的读取压力。 2. **减少数据库负载**:避免大量重复的数据库查询,提高数据库的使用寿命。 3. **Session共享**:在分布式...
**Memcache缓存技术详解** Memcache是一种广泛应用于Web开发中的分布式内存缓存系统,它能够有效提升应用程序的性能,减少数据库的负载。这个压缩包提供了在PHP环境中配置和使用Memcache所需的关键组件。 1. **...
在IT行业中,构建高效、可扩展的Web应用是至关重要的,而这个项目“继上一版留言本并加入memcache缓存和pdo连接方式”显然就是这样的一个实践案例。它基于上一版本的留言本系统进行了优化,引入了memcache缓存技术和...
实现Redis和Memcached缓存的基本步骤如下: 1. **环境搭建**:首先,你需要在服务器上安装并启动Redis或Memcached服务。这通常可以通过下载对应软件包,配置相关参数,然后通过命令行启动服务完成。 2. **Java...
**MemCache和Redis缓存介绍** 在IT行业中,缓存技术是提高系统性能和响应速度的关键因素之一。MemCache和Redis是两种广泛使用的分布式内存缓存系统,它们能够有效地存储和检索数据,减轻数据库的负担,提升应用的...
在这个"springmvc配置Memcache缓存Demo"中,我们将探讨如何在Spring MVC项目中集成Memcache,一个高性能的分布式内存对象缓存系统,以提升应用的性能。 首先,让我们了解Memcache的基本概念。Memcache是一个开源的...
**分布式缓存与Memcache简介** 分布式缓存是一种在分布式系统中存储数据的机制,它通过将数据分散在多台服务器上,提高了系统的可扩展性和性能。这种技术常用于减轻数据库的压力,加速读取频繁访问的数据。Memcache...
这个"memcache 缓存机制"插件可能是一个用于集成Memcached服务到应用程序中的工具,通过它,我们可以更方便地利用Memcached的优势。 1. **基本概念** - **键值对存储**:Memcached基于键值对(key-value)存储数据,...
ASP Memcache 是一种在 ASP(Active Server Pages)环境中实现高效缓存管理的技术,它通过集成 Memcached 这个高性能的分布式内存对象缓存系统来提升应用程序的性能。Memcached 是一个广泛使用的开源软件,用于存储...
- 分布式环境下的Memcache集群配置,以实现更高的可用性和可扩展性。 通过本课件的学习,你将掌握如何在实际项目中部署和利用Memcache提升应用性能。源码部分可以帮助你更好地理解Memcache在实际编程中的应用,...
的Memcache缓存实现](http://www.ccvita.com/261.html) - [Memcache协议中文版](http://www.ccvita.com/306.html) - [Memcache分布式部署方案](http://www.ccvita.com/395.html) 以上步骤和信息旨在帮助开发者顺利...
在项目中可能会使用到多种缓存技术,如memcache文件缓存等。如果能把这些缓存机制统一接口,对外开放,让使用者可以不用关心缓存的内部实现就可以随意调用这些缓存类。实现这样的做法,需要一个缓存代理类,来完全...
**Memcache缓存详解** Memcache是一款高性能的分布式内存对象缓存系统,它广泛应用于Web应用中,用于减轻数据库负载,提高数据访问速度。通过在内存中存储常用数据,Memcache能够快速响应客户端请求,避免频繁地从...