Friday, December 28, 2007

MySQL优化实例

引用来源
在Apache, PHP, MySQL的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分。对于Discuz!论坛程序也是如此,MySQL的设置是否合理优化,直接影响到论坛的速度和承载量!同时,MySQL也是优化难度最大的一个部分,不但需要理解一些MySQL专业知识,同时还需要长时间的观察统计并且根据经验进行判断,然后设置合理的参数。

下面我们了解一下MySQL优化的一些基础,MySQL的优化我分为两个部分,一是服务器物理硬件的优化;二是MySQL自身(my.cnf)的优化。

(1) 服务器硬件对MySQL性能的影响

a) 磁盘寻道能力(磁盘I/O),以目前高转速SCSI硬盘(7200转/秒)为例,这种硬盘理论上每秒寻道7200次,这是物理特性决定的,没有办法改变。 MySQL每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以,通常认为磁盘I/O是制约MySQL性能的最大因素之一,对于日均访问量在100万PV以上的Discuz!论坛,由于磁盘I/O的制约,MySQL的性能会非常低下!解决这一制约因素可以考虑以下几种解决方案:

使用RAID-0+1磁盘阵列,注意不要尝试使用RAID-5,MySQL在RAID-5磁盘阵列上的效率不会像你期待的那样快; 抛弃传统的硬盘,使用速度更快的闪存式存储设备。经过Discuz!公司技术工程的测试,使用闪存式存储设备可比传统硬盘速度高出6-10倍左右。

b) CPU 对于MySQL应用,推荐使用S.M.P.架构的多路对称CPU,例如:可以使用两颗Intel Xeon 3.6GHz的CPU。

c) 物理内存对于一台使用MySQL的Database Server来说,服务器内存建议不要小于2GB,推荐使用4GB以上的物理内存。

(2) MySQL自身因素当解决了上述服务器硬件制约因素后,让我们看看MySQL自身的优化是如何操作的。对MySQL自身的优化主要是对其配置文件my.cnf中的各项参数进行优化调整。下面我们介绍一些对性能影响较大的参数。

由于my.cnf文件的优化设置是与服务器硬件配置息息相关的,因而我们指定一个假想的服务器硬件环境:

CPU: 2颗Intel Xeon 2.4GHz

内存: 4GB DDR

硬盘: SCSI 73GB


下面,我们根据以上硬件配置结合一份已经优化好的my.cnf进行说明:

# vi /etc/my.cnf

以下只列出my.cnf文件中[mysqld]段落中的内容,其他段落内容对MySQL运行性能影响甚微,因而姑且忽略。

[mysqld]
port = 3306
serverid = 1
socket = /tmp/mysql.sock
skip-locking
# 避免MySQL的外部锁定,减少出错几率增强稳定性。
skip-name-resolve


禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!

back_log = 384

指定MySQL可能的连接数量。当MySQL主线程在很短的时间内接收到非常多的连接请求,该参数生效,主线程花费很短的时间检查连接并且启动一个新线程。

back_log参数的值指出在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中。如果系统在一个短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的侦听队列的大小。不同的操作系统在这个队列大小上有它自己的限制。

试图设定back_log高于你的操作系统的限制将是无效的。默认值为50。对于Linux系统推荐设置为小于512的整数。

key_buffer_size = 256M
# key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。


对于内存在4GB左右的服务器该参数可设置为256M或384M。
注意:该参数值设置的过大反而会是服务器整体效率降低!

max_allowed_packet = 4M
thread_stack = 256K
table_cache = 128K
sort_buffer_size = 6M


查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 6 = 600MB。所以,对于内存在4GB左右的服务器推荐设置为6-8M。

read_buffer_size = 4M

读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!

join_buffer_size = 8M

联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!

myisam_sort_buffer_size = 64M
table_cache = 512
thread_cache_size = 64
query_cache_size = 64M


指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察:

# > SHOW VARIABLES LIKE '%query_cache%';
# > SHOW STATUS LIKE 'Qcache%';
# 如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;


如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。

tmp_table_size = 256M
max_connections = 768

指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提 示,则需要增大该参数值。

max_connect_errors = 10000000
wait_timeout = 10


指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。

thread_concurrency = 8

该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4 × 2 = 8

skip-networking

开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开启该选项!否则将无法正常连接!

links for 2007-12-28

Wednesday, December 26, 2007

JS字符截取




Tuesday, December 25, 2007

PHP控制浏览器缓存的方法


//下面的语句设置此页面的过期时间(用格林威治时间表示),只要是已经过去的日期即可。
header("Expires: Mon, 26 Jul 1970 05:00:00 GMT");
//下面的语句设置此页面的最后更新日期(用格林威治时间表示)为当天,可以强迫浏览器获取最新资料
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
//告诉客户端浏览器不使用缓存,HTTP 1.1 协议
header("Cache-Control: no-cache, must-revalidate");
//告诉客户端浏览器不使用缓存,兼容HTTP 1.0 协议
header("Pragma: no-cache");

Sunday, December 23, 2007

Paangood tech co. ?

最近感觉盘古网络,就是我现在用的主机空间,非常垃圾,不是一般的烂,速度其慢,我想可能是服务器资源分配不均衡导致,这是500¥一年的合租空间,不稳定,没有DreamHost的好,真的差很多。我怀疑在国外根本不可能访问到我的站点,导致最近我的Google Adsense点击几乎为0,所以我还是打算在年初想办法转换到国外的空间,原来在DH上的一年文件和网页没有及时拷贝回本地,真的是遗憾。

Tuesday, December 18, 2007

spreadsheet_excel_writer utf8 bug

here is a PEAR scodeadsheet_excel_writer bug report, if you use utf8 with scodeadsheet_excel_writer, you will get some error when you export excel files, that's all.

I get some error today, but you can use some patch on scodeadsheet_excel_writer, such as this one.

I think Gentoo is really good ;)

Monday, December 17, 2007

PHP 动态调用函数


/**
* $Id$
* Author: zhuzhu@perlchina.org (zhuzhu@isoshu.net)
*/
class Manage
{
var $todo = null;

public function route()
{
$action = &$_GET['action'];
switch($action){
case 'login':
$this->todo = '_login';
break;
case 'build_site':
$this->todo = '_build_site';
break;
case 'system';
$this->todo = '_system';
break;
default:
$this->todo = '_index';
break;
}
$myFun = $this->todo; // 动态调用函数
$this->{$myFun}();
}

private function _index()
{
print 'hi';
}
}

?>

Sunday, December 16, 2007

ubuntu laptop stop auto upgrade

yes, I stop to auto upgrade my ubuntu laptop. upgrade by hand from now on. I use ubuntu 6.06.
But I will use Linux forever. ;)

Tuesday, December 11, 2007

RHEL AS5 通过yum update自动升级

1.下载并安装yum-2.4.0-1.centos4.noarch.rpm文件,下载地址为:
ftp://ftp.pbone.net/mirror/ftp.centos.org/5.0/os/i386/CentOS/yum-cron-0.1-1.el5.centos.noarch.rpm

2.修改或建立/etc/yum.repos.d/rhel-debuginfo.repo为如下内容:
[base]
name=Red Hat Enterprise Linux $releasever -Base
baseurl=http://ftp.riken.jp/Linux/caos/centos/5.0/os/$basearch/
gpgcheck=1
[update]
name=Red Hat Enterprise Linux $releasever -Updates
baseurl=http://ftp.riken.jp/Linux/caos/centos/5.0/updates/$basearch/
gpgcheck=1
[extras]
name=Red Hat Enterprise Linux $releasever -Extras
baseurl=http://ftp.riken.jp/Linux/caos/centos/5.0/extras/$basearch/
gpgcheck=1
[addons]
name=Red Hat Enterprise Linux $releasever -Addons
baseurl=http://ftp.riken.jp/Linux/caos/centos/5.0/addons/$basearch/
gpgcheck=1


3.修改或建立/etc/yum.repos.d/dag.repo为如下内容:

[dag]
name=Dag RPM Repository for RHEL5
baseurl=http://ftp.riken.jp/Linux/dag/redhat/el5/en/$basearch/dag/
enabled=1
gpgcheck=1
gpgkey=http://ftp.riken.jp/Linux/dag/packages/RPM-GPG-KEY.dag.txt



4.运行update:

yum update

5.升级:
yum upgrade

6.安装其它软件,例如:
yum install mplayer

Friday, December 7, 2007

cakephp session manually

Into the Controller::beforeFilter for example
$this->Session->activate();

And into the Views before you need it
$session->activate();

Saturday, December 1, 2007

web.py with fastcgi on Apache

我们为您准备了这个文档来帮助您快速的使用web.py

你可以在windows平台使用putty,UNIX则需要使用SSH.
你的用户需要有使用shell的权限,这个可以在用户控制面板中进行设置
在评论页可以看到更多的信息

目录

1.架设 web.py
1.1 CGI
1.1.1 0. 开始
1.1.2 1. 安装 web.py
1.1.3 2. 安装 Flup
1.1.4 3. 使用 Apache 服务
1.1.5 4. 检查并发现错误
1.2 FCGI
1.2.1 Benchmarking
1.2.2 重启 FASTCGI
1.2.3 改进稳定性和加快启动速度

架设 web.py

CGI
如果您按照我们的步骤来,那么架设CGI将是一件十分容易的事情.在下面的示例代码中,将example.com替换成您自己映射在dreamhost的域名.

0. 开始

进入到您的web主目录.

cd ~/example.com


1.安装web.py

使用Subversion命令行代码工具来获取最新的web.py

svn co http://webpy.org/svn/trunk/web/

按照如下方式来建立一个index.cgi,这将是您的第一个web.py网页

#!/usr/bin/env python2.4
import web
urls = ('/', 'index')
class index:
def GET(self):
print "Hi web.py, finally we meet!"
def runfcgi_apache(func):
web.wsgi.runfcgi(func, None)
if __name__ == "__main__":
web.wsgi.runwsgi = runfcgi_apache
web.run(urls, globals())


将该文件上传到web主目录后,使用如下的命令来使该文件可访问

chmod +x index.cgi


2.安装Flup

使用wget命令来获取最新的fcgi

wget http://svn.saddi.com/py-lib/trunk/fcgi.py

按照如下提示修改web/wsgi.py

--- wsgi.py (revision 130)
+++ wsgi.py (working copy)
@@ -13,8 +13,8 @@

def runfcgi(func, addr=('localhost', 8000)):
"""Runs a WSGI function as a FastCGI server."""
- import flup.server.fcgi as flups
- return flups.WSGIServer(func, multiplexed=True, bindAddress=addr).run()
+ import fcgi as flups
+ return flups.WSGIServer(func, multiplexed=False, bindAddress=addr).run()


(译者注:使用++的内容替换掉--的内容)

3.使用apache的服务

编辑apache的.htaccess文件来启用cgi

vim .htaccess

添加如下代码

Options +ExecCGI
AddHandler cgi-script .py

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.cgi/$1 [L]



4.检查并发现错误
现在,你的web主目录应该是这个样子

$ ls -F ~/example.com
fcgi.py index.cgi* web/


使用你的浏览器访问http://example.com/(您自己映射在dreamhost的域名),应该就可以看到问候语.如果浏览器显示"500内部错误",那就应该检查下错误日志.

tail -n 30 ~/logs/example.com/http/error.log


(译者注:上面的内容足够成功运行web.py了,下面的内容我也还没有进行,所以仅供参考)

FCGI
1.使用FastCGI架设您的域名或二级域名.假设您的域名是todo.dabase.com
2.cd; rmdir ~/todo.dabase.com
3.svn co http://svn.natalian.org/projects/todo/
4.ln -s ~/todo ~/todo.dabase.com
5.Tweak ~/todo with your mysql db (see config.py) and email stuff for errors
并不建议您在shell下进行fcgi的测试开发,因为如果fastcgi的进程开始运行后,停止或重启这个进程都是一件让人头痛的事情.您可以使用web.reloader在本地进行开发,这样,您的任何改变将立即被反应到您的web程序.

Benchmarking

ab is from the apache2-utils Debian package.
从apache2-utils Debian包中找到ab组件

/usr/sbin/ab -c 4 -n 300 http://todo.dabase.com/

4 concurrent connections pushing out 300 requests. If you find it too slow, considering running lighttpd on a dedicated server.
4个并发连接将产生300个请求.如果你发现它运行太慢,请考虑在一台专用服务器上运行lighttpd.

重启FastCGI进程

为了使新的代码起作用,你需要重启fcgi进程.
如下代码将会起作用

killall python2.4



改进稳定性和加快启动速度

1.使用http://svn.saddi.com/py-lib/trunk/fcgi.py来代替较新的flup
2.按照如下方法修改wsgi.py

--- wsgi.py (revision 130)
+++ wsgi.py (working copy)
@@ -13,8 +13,8 @@

def runfcgi(func, addr=('localhost', 8000)):
"""Runs a WSGI function as a FastCGI server."""
- import flup.server.fcgi as flups
- return flups.WSGIServer(func, multiplexed=True, bindAddress=addr).run()
+ import fcgi as flups
+ return flups.WSGIServer(func, multiplexed=False, bindAddress=addr).run()