MySQL压力测试工具mysqlslap

2009年12月17日 没有评论

mysqlslap是官方提供的压力测试工具之一,官方介绍如下:                武汉百度推广公司
mysqlslap is a diagnostic program designed to emulate client load for a MySQL server and to report
the timing of each stage. It works as if multiple clients are accessing the server. mysqlslap is
available as of MySQL 5.1.4.

下面介绍一些常见参数:
–auto-generate-sql-write-number

每个线程中产生多少个insert
–auto-generate-sql-guid-primary

自动产生guid格式的主键
–number-of-queries=50000

每个连接客户端总共发起的查询次数
–concurrency=10,50,100

并发连接线程数,分别是10、50、100个并发
-i, –iterations

重复执行测试的次数
–number-char-cols=10

创建测试表的 char 型字段数量
–number-int-cols=10

创建测试表的 int 型字段数量
下面是一个完整的例子:
mysqlslap -hlocalhost -uroot –engine=innodb –auto-generate-sql-write-number=100000 \
–auto-generate-sql-guid-primary –concurrency=10,50,100 –number-of-queries=500000 \
–iterations=2 –number-char-cols=10 –number-int-cols=10 –auto-generate-sql \
–create-schema=sbtest –auto-generate-sql-load-type=mixed

具体的慢慢看手册吧,不多嗦了,哈。

PS:这个工具原来不在mysql里,我还找了半天,补上官方手册                   武汉百度公司http://dev.mysql.com/doc/refman/5.1/en/mysqlslap.html

分类: MySQL 标签:

MySQL主从复制的一些技巧

2009年12月17日 没有评论

问题:主从服务器表类型的选择   

       一般的共识是主服务器使用innodb,事务,行锁等功能是myisam所没有的,对修改操作而言,它更高效;从服务器使用myisam,全文检索功能是innodb所没有的,对查询操作而言,它更高效。这样就可以各尽其能。

问题:主从服务器字段类型的选择

      字段类型对于分页等操作有很大影响。主服务器一般是innodb,因为不涉及查询,所以可以使用varchar等来存储字符串来节省空间,从服务器一般是 myisam,因为涉及查询,所以必须在char和varchar之间仔细权衡,没有varchar, text, blob字段的表是静态表,反之是动态表,静态表的检索效率要比动态表好若干倍,一般来说,所有涉及大结果集的查询都应该尽可能保证在静态表上完成,这里说一个例子:比如说常见的articles表有title(varchar), body(text)等字段,在做文章列表的时候,因为不是静态表,所以查询不会很快,下面开始重构解决方案:把原来的articles表拆分成 subjects表和contents表,title字段设置为一个足够的char类型放在subjects表里,body字段还保持是text类型放到 contents表里,subjects和contents表之间的关系是一对多,这样,顺带着也方便的实现了多页文章的功能,而且更重要的是在查询文章列表的时候,操作都是在subjects静态表里完成,效率肯定会比前一种方案提升很多。

强调:MyISAM里静态表和动态表的区别对性能影响极大,但我敢说很大一部分使用者并没有注意过这一点!如果你就是其中之一,那么我强烈建议你再次体会一下前面说的articles分解为subjects/contents的过程,相信你熟悉了以后,下一个应用的速度会有质的提升。

问题:主从服务器读写分离时读操作失败

       先重现一下问题:比如说添加一条新数据,添加成功后根据last_insert_id跳转到新添加数据的浏览页面。在此过程中添加新数据的操作是在主服务器上完成的,浏览新数据的操作实在从服务器上完成的,不过由于主从服务器间SQL同步存在延迟,所以当使用last_insert_id在从服务器上查询的时候,从服务器很可能还没有还没来得及同步到此记录,所以读操作失败。解决思路也不复杂,在代码里加入一个缓存层(可以使用memcached),新添加的数据都顺手放到缓存层里一份,新数据的读操作也先查询缓存层,这样就不会再有读操作失败的问题了,当然删除或者更新数据的时候也要顺带着处理好缓存数据,可以使用观察者模式来搞定。不过这样缓存方案只限于读取单一的记录,对于读取列表的记录的情况,则是无效的。

问题:主从服务器索引是否有必要保持一致

      一般都是利用主从服务器完成读写分离,从服务器上进行读操作,主服务器进行写操作,这样的话,主服务器上仅保留主键,外键,唯一索引等必要的索引即可,以便保持数据合法性,而对于那些原本用于优化SELECT操作的索引,可以全部删除,如此的话主服务器的写操作效率会提升很多。把索引保持在从服务器上还有一个好处就是实际应用里,我们可能时常要通过ALTER TABLE去调整索引,而ALTER TABLE本身数据剧烈运动,会影响在线业务,为了规避影响,我们可以先停止一台从服务器,然后ALTER TABLE建好索引,然后再把从服务器启动,用这样的方法把所有的从服务器都建好索引,从而平滑的完成了ALTER TABLE操作。

转载自:小楼一夜听语          

 

PS:NOW()函数不会因为主从服务器之间同步的时间差而造成数据不一致,因为mysql会通过 seconds_behind_master 参数来自动进行校正。 当然前提是主从服务器的系统时间必须保持一致。

分类: MySQL 标签:

Mysql同步和主从设置

2009年12月17日 没有评论

设置Mysql的主从设置很重要,有如下几点用处:       

1 做备份机器,一旦主服务器崩溃,可以直接启用从服务器作为主服务器
2 可以直接锁定从服务器的表只读,然后做备份数据,这样不会影响主服务器的服务
3 可以处理读写数据库的负载均衡

阿权总结的设置主从的要点有如下:

1 主从服务器的启动方式的不同点
2 主服务器只读或者停止服务然后获取当前数据快照,清理日志或者重新开始记录日志
3 从服务器一般需要只读,否则容易产生错误导致同步失败

阿权制作主从的过程总结:

1 停止数据库服务,并且删除当前的所有mysql日志(默认是mysql-bin.*)
2 把当前的所有数据库打包,备用
3 打包完成后,主服务器可以启动了
4 把从服务器的同步日志删除(默认是mysql-relay-bin.*)
5 把文件解压到从服务器的数据目录
6 设置好cnf文件,启动即可

当然,取得快照的方法还有别的:
1 FLUSH TABLES WITH READ LOCK 锁定所有表
2 打包文件或者是直接导出数据,比停止服务好的地方就是有一段读数据库的时间
3 然后 unlock tables

主从的配置区别:                      

启动方式请参考《Mysql多实例启动》
主服务器没有设置 master的值,下面的参数影响同步:

#设定不同步的数据库,这些库的修改不会记录到日志,可以添加多行
binlog-ignore-db = test
#设定记录的库,可以添加多行
binlog-do-db = vnet

从服务器设置了系列master的参数:

master-host = 192.168.1.147
master-port = 3308
master-user = usr
master-password = pwd
master-retry-count = 999
master-connect-retry = 60

#并且可以设置忽略的库,可以添加多行
replicate-ignore-db = testdb
#设置仅处理的库,可以添加多行
replicate-do-db = aslibra

设置忽略的和处理的参数的一个就好,如果需要忽略哪些,就加上忽略的库,如果仅仅需要处理一两个,那就加上do-db的设置吧

如何检查同步情况?

show master status;
show slave status;

这里会列出当前同步的情况,包括同步哪些库,忽略哪些库

如何检查发生同步错误?

1 主服务器更新后没有反映在从服务器,这个是看的到的
2 可以使用phpmyadmin看进程或者是命令 SHOW PROCESSLIST
主服务器会有一条slave用户的记录,比如
slave  127.0.0.1:42157  无  Binlog Dump  598  Has sent all binlog to slave; waiting for binlog to be updated  —

从服务器会有两条记录
system user     无  Connect  724  Waiting for master to send event  —
system user     无  Connect  187  Has read all relay log; waiting for the slave I/O thread to update it  —

如果同步失败,则后一条没有

同步特性及已知问题

跨库的操作是不更新的,比如

update dbtest.aslibra set domain=’www.aslibra.com’ where id=5

更多内容可以参考《同步特性及已知问题》,这里就不详细列出了啦

哪些从服务器操作会导致错误?

1 删除表或者修改表结构会导致之后更新该表产生错误,可以恢复原先结构再继续同步就可以,错误如下

0805034:41:03 [Note] Slave SQL thread initialized, starting replication in log ‘mysql-bin.000003’ at position 244, relay log ‘/Data/mysql3309/var/mysql-relay-bin.000004’ position: 3810805034:44:00 [ERROR] Slave: Error ‘Can’t DROP ‘id’; check that column/key exists’ on query. Default database: ‘dbtest’. Query: ‘ALTER TABLE test DROP id’, Error_code: 10910805034:44:00 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log ‘mysql-bin.000004’ position 252

2 从服务器如果写入一条记录,自增字段加一,主键唯一性错误,这样主服务器就无法同步这样的数据,导致同步停止。如果不产生主键冲突的数据是不会有影响

INTO aslibra (id, ddd) VALUES (”, ‘2008-05-02′)’, Error_code: 1062
0805034:36:44 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log ‘mysql-bin.000003’ position 244

3 从服务器删除某条数据,主服务器再删除该条数据,不会产生错误

阿权的总结:

1 从服务器如果需要重新做同步数据,必须是主服务器开始记录日志的数据快照。所以快照很重要,可以用该快照立刻构建一个从服务器。
2 日志只是记录sql语句,执行删除和更新如果与主服务器数据不同是不会产生错误
3 如果执行插入数据,产生主键冲突则会导致错误,停止同步,除非从服务器执行本语句正常,则可以继续同步
4 表结构修改如果返回错误,则也会导致同步停止

原创内容如转载请注明:来自 阿权的书房            

分类: MySQL 标签:

MySQL主从数据库配置注意问题

2009年12月16日 没有评论

      一般使用MySQL的时候,如果数据量不大,我们都使用一台MySQL服务器,备份的时候使用mysqldump工具就可以了,但是随着业务不断发展,问题出现了:  武汉百度推广公司
      首先:数据量往往直线上升,单独一台数据库服务器开始出现性能的瓶颈,数据访问越来越慢。
      其次:备份也变得困难了,因为mysqldump是导出一份文本文件,而数据量特别大的时候,这样的备份往往需要很长时间,可能有人会说,我们可以直接通过拷贝数据文件来备份数据库,这样很方便,快捷,不错,这样是比mysqldump方便快捷,但是,直接拷贝数据文件备份的方式要求我们必须先关闭mysql服务,然后再拷贝数据文件,否则,你拷贝的文件很可能是坏的。而实际运行的mysql服务往往要求在任何时候都不可以停止服务,所以这样的备份方式在此情况下不可行。
      如果你遇到了类似上面的问题,你就可以使用建立MySQL主从服务器的方式来解决,下面先来看看主从服务器的设置:
      前提:MySQL主从服务器最好使用相同的软件版本,以避免不不可预期的故障。
首先设置MySQL主服务器:
在主服务器上为从服务器建立一个用户:
grant replication slave on *.* to ‘用户名‘@’主机’ identified by ‘密码’;
编辑主服务器的配置文件:/etc/my.cnf的mysqld处

server-id = 1
log-bin
binlog-do-db=需要备份的数据库名,如果备份多个数据库,重复设置这个选项即可
binlog-ignore-db=不需要备份的数据库苦命,如果备份多个数据库,重复设置这个选项即可
编辑从服务器的配置文件:/etc/my.cnf
server-id=2
master-host=主机
master-user=用户名
master-password=密码
master-port=端口
replicate-do-db=需要备份的数据库名,如果备份多个数据库,重复设置这个选项即可
记得先手动同步一下主从服务器中要备份的数据库,然后重启主,从服务器。
要验证主从设置是否已经成功,可以登录从服务器输入如下命令:
mysql> show slave status\G
会得到类似下面的列表:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
      如果这两个选项不全是Yes,那就说明你前面某个步骤配置错了。
        如果你的设置是正确的,尝试在主服务器上插入若干条记录,然后你再转到从服务器,会发现相应的新记录已经自动同步过来了。
      如果你的主从服务器已经配置好了,那么你在应用程序中,只要保证所有的insert/delete/update操作是在主服务器上进行的,那么相应的数据变化会自动同步到从服务器上,这样,我们就可以把select操作分担到多台从数据库上,从而降低服务器的载荷。
      如果你想使用复制数据文件的方式来备份数据库,只要在从服务器上的mysql命令行先键入slave stop;然后复制数据库文件,复制好了,再 在mysql命令行键入slave start;启动从服务器,这样就即备份了数据有保证了数据完整性,而且整个过程中主服务器的mysql无需停止。
———————————————————————————–
提示:如果修改了主服务器的配置,记得删除从服务器上的master.info文件。否则从服务器使用的还是老配置,可能会导致错误。
———————————————————————————–
注意:关于要复制多个数据库时,binlog-do-db和replicate-do-db选项的设置,网上很多人说是用半角逗号分隔,经过测试,这样的说法是错误的,MySQL官方文档也明确指出,如果要备份多个数据库,只要重复设置相应选项就可以了。
比如:
binlog-do-db=a
binlog-do-db=b
replicate-do-db=a
replicate-do-db=b
———————————————————————————–
补充:从服务器上my.cnf中的master-*的设置仅在第一次生效,后保存在master.info文件里。
———————————————————————————–
在从服务器上使用show slave status
Slave_IO_Running,为No,则说明IO_THREAD没有启动,请执行slave start [IO_THREAD]
Slave_SQL_Running为No则复制出错,查看Last_error字段排除错误后执行slave start [SQL_THREAD]
查看Slave_IO_State字段
空 //复制没有启动
Connecting to master//没有连接上master
Waiting for master to send event//已经连上
———————————————————————————–
可以使用LOAD DATA FROM MASTER语句来建立slave。但有约束条件:
数据表要全部是MyISAM表,必须有SUPER权限,master的复制用户必须具备RELOAD和SUPER权限。
在master端执行RESET MASTER清除已有的日志变更,
此时slave端会因为找不到master日志无法启动IO_THREAD,请清空data目录下
relay-log.info,hosname-relay-bin*等文件重新启动mysql
中继日志文件默认的文件为hostname-relay-bin.nnn和hostname-relay-bin.index。可用从服务器的–
relay-log和–relay-log-index选项修改。在从服务器中还有一个relay-log.info中继信息文件,可用
–relay-log-info-file启动选项修改文件名。
双机互备则是两个mysql同时配置为master及slave
———————————————————————————–
主服务器上的相关命令:                   武汉百度公司
show master status
show slave hosts
show {master|binary} logs
show binlog events
purge {master|binary} logs to ‘log_name’
purge {master|binary} logs before ‘date’
reset master(老版本flush master)
set sql_log_bin={0|1}
———————————————————————————–
从服务器上的相关命令:
slave start
slave stop
SLAVE STOP IO_THREAD //此线程把master段的日志写到本地
SLAVE start IO_THREAD
SLAVE STOP SQL_THREAD //此线程把写到本地的日志应用于数据库
SLAVE start SQL_THREAD
reset slave
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
load data from master
show slave status(SUPER,REPLICATION CLIENT)
CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,MASTER_USER=, MASTER_PASSWORD= //动态改变master信息
PURGE MASTER [before ‘date’] 删除master端已同步过的日志
———————————————————————————–
–read-only
该选项让从服务器只允许来自从服务器线程或具有SUPER权限的用户的更新。可以确保从服务器不接受来自客户的更新。

分类: MySQL 标签:

同机MySQL数据库主从同步配置方案

2009年12月16日 没有评论

1、配置主库my.ini                    

port=3306

datadir=”C:/Program Files/MySQL/MySQL Server 5.0/Data/”

server-id=1

log-bin=mysql-bin
(注:一定要启用logbin功能才能进行同步备份。如果只想对某个数据库或者某个数据库的某些表做同步,那么还需要增加binlog-do-db参数进行限制,格式:binlog-do-db = dbname)

2、配置从库my.ini

port=3307

注意:主从的datadir目录不能一样(各自的log文件在各自的data目录下)
datadir=”D:/Program Files/MySQL/MySQL Server 5.0/Data/”

server-id=2

#启用从库日志,这样可以进行链式复制

log-slave-updates

#从库是否只读,0表示可读写,1表示只读(可选项)

read-only=1

#只复制某个表(如果只想对某个数据库或者某个数据库的某些表做同步,需要选择这项)

replicate-do-table=dbname.tablename

#只复制某些表(可用匹配符。功能同上参数。)

replicate-wild-do-table=dbname.tablename%

#只复制某个库(如果对多个数据库做同步,那么可以用多行来表示。)

replicate-do-db = dbname

#只复制某些库(可用匹配符。)

replicte-wild-do-db=dbname%

#不复制某个表

replicate-ignore-table=dbname.tablename

#不复制某些表

replicate-wild-ignore-table=dbname.tablename%

#不复制某个库(如果忽略多个数据库的同步,那么可以用多行表示。)

replicate-ignore-db=mysql

#复制完的sql语句是否立即从中继日志中清除,1表示立即清除(可选项)

relay-log-purge = 1
3、设置主库                         

连接到主库中,创建复制用户

C:\>mysql -uroot -ppassword -P3306

mysql> grant replication slave on *.* toidentified by ‘123456′;

Query OK, 0 rows affected (0.00 sec)
锁住主库的table,以便备份数据文件到从库进行初始化

mysql> flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

显示主库状态,注意记下当前二进制日志文件名和position

mysql> show master status;

+―――――――C+―――C+――――――-+――――――――+

| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+―――――――-+――――+――――――-+――――――――+

| mysql-bin.000001 |     98 | backup     |   mysql       |

+―――――――-+――――+――――――-+――――――――C+

1 row in set (0.00 sec)
4、设置从库

另外开启一个cmd,启动从库

连接到从库进行配置

C:\>mysql -uroot -ppassword -P3307

mysql> CHANGE MASTER TO

   -> MASTER_HOST=’localhost’,

   -> MASTER_USER=’backup’,

   -> MASTER_PASSWORD=’backup’,

   -> MASTER_LOG_FILE=’mysql-bin.000001′,

   -> MASTER_LOG_POS=98;

Query OK, 0 rows affected (0.01 sec)

注意到这里master_log_file和master_log_pos就是前面show master status的结果。

启动复制进程

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

至此配置基本完成,在主库解开table的锁定

mysql> unlock tables;

Query OK, 0 rows affected (0.00 sec)

最后在从服务器中执行如下操作:
mysql>show slave status \G;
如果下面三项显示为这样,则表示已经启动正常。
Slave_IO_State: Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

建议:在同步之前,2台Mysql的数据库 数据要一致,就是先把要备份的数据库导入到从slave服务器上。这样可以避免同步出错。

转载自:http://hi.baidu.com/codylee/blog/item/b16acdfc197b4588b901a0a7.html

分类: MySQL 标签:

dlmalloc简介

2009年12月13日 没有评论

       dlmalloc是目前一个十分流行的内存分配器,其由Doug Lea[1]从1987年开始编写,到目前为止,最新版本为2.8.3[2],由于其高效率等特点被广泛的使用和研究(很多linux系统等用的就是dlmalloc或其变形,比如ptmalloc[3])。                                     武汉百度公司
       dlmalloc的实现只有一个源文件(还有一个头文件),大概5000行,其内注释占了大量篇幅,由于有这么多注释存在的情况下,表面上看上去很容易懂,的确如此,在不追求细节的情况,对其大致思想的确很容易了解(没错,就只是了解而已),但是dlmalloc作为一个高品质的佳作,实现上使用了非常多的技巧,在实现细节上不花费一定的精力是没有办法深入理解其为什么这么做,这么做的好处在哪,只有当真正读懂后回味起来才发现它是如此美妙。
       lenky0401个人博客[4]将陆续推出关于dlmalloc源码(针对Doug Lea Malloc的最新版Version 2.8.3)的初步解析文章,由于lenky0401水平有限,因此也不能完全保证对dlmalloc的所有理解都准备无误,但是所有内容均出自个人的理解而并非存心妄自揣测来愚人耳目,所以如果读者发现其中有什么错误,请勿见怪,如果可以则请来信告之,并欢迎来信讨论(lenky0401@163.com)。

原文引用地址:http://www.aboutstudy.net/cms/wenzhangzhongxin/wangluobiancheng/PHP/2009-12-13/711.html

武汉百度推广

分类: Linux 标签:

PHP在Apache中两种工作方式的区别(CGI模式、Apache 模块DLL)

2009年12月11日 没有评论

        Windows 下有两种方法使 PHP 工作于 Apache 2.0.x 之中。一种是 使用 CGI 可执行程序,另一种是适用 Apache 模块的 DLL。                       
这两种工作方式的安装:

PHP 在 Apache 2.0 中的 CGI 方式
ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php

# 对 PHP 4 用这行
Action application/x-httpd-php "/php/php.exe"
# 对 PHP 5 用这行
Action application/x-httpd-php "/php/php-cgi.exe"
PHP 在 Apache 2.0 中的模块方式
# 对 PHP 4 用这两行:
LoadModule php4_module "c:/php/php4apache2.dll"
# 别忘了从 sapi 目录中把 php4apache2.dll 拷贝出来!
AddType application/x-httpd-php .php

# 对 PHP 5 用这两行:
LoadModule php5_module "c:/php/php5apache2.dll"
AddType application/x-httpd-php .php
# 配置 php.ini 的路径
PHPIniDir "C:/php"

这两种工作方式的区别:
在CGI模式下,如果客户机请求一个php文件,Web服务器就调用php.exe去解释这个文件,然后再把解释的结果以网页的形式返回给客户机;
而在模块化(DLL)中,PHP是与Web服务器一起启动并运行的。
所以从某种角度上来说,以apache模块方式安装的 PHP4有着比CGI模式更好的安全性以及更好的执行效率和速度。

一、FastCGI是什么?
  FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等等。
FastCGI的官方站点在http://www.fastcgi.com

  FastCGI的工作原理是:
  1、Web Server 启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module);
  2、FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
  3、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。
  4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个连接。 在正常的CGI模式中,php-cgi.exe在此便退出了。

  在上述情况中,你可以想象 CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

二、为什么要使用FastCGI,而不是多线程CGI解释器?
  这可能出于多方面的考虑,例如:
  1、你无论如何也不能在windows平台上稳定的使用多线程CGI解释器,无论是IIS ISAPI方式还是APACHE Module方式,它们总是运行一段时间就崩溃了。奇怪么?但是确实存在这样的情况!
  当然,也有很多时候你能够稳定的使用多线程CGI解释器,但是,你有可能发现网页有时候会出现错误,无论如何也找不到原因,而换用FastCGI方式时这种错误的概率会大大的降低。我也不清楚这是为什么,我想独立地址空间的CGI解释器可能终究比共享地址空间的形式来得稳定一点点。
  2、性能!性能?可能么,难道FastCGI比多线程CGI解释器更快?但有时候确实是这样,只有测试一下你的网站,才能最后下结论。原因嘛,我觉得很难讲,但有资料说在Zend WinEnabler的时代,Zend原来也是建议在Windows平台下使用FastCGI而不是IIS ISAPI或Apache Module,不过现在Zend已经不做这个产品了。

三、不使用FastCGI的理由
  1、多进程比多线程消耗更多的服务器内存,php-cgi.exe解释器每进程消耗7至25兆内存,将这个数字乘以50或100试试。
  2、性能。确实有时候多线程CGI解释器更快,呵呵,而且有时候,它也很稳定。
  3、CGI?听起来就很土,呵呵

四、IIS FastCGI配置方法
  1、首先确定你已正确安装了PHP 4.3.x及更新的版本。早期版本的PHP并未默认加入FastCGI支持,如果你想在早期版本中工作,需要重新编译它。我们假设PHP安装在c:\php,支持FastFCGI的可执行文件名是php-cgi.exe。
    注意:建议在Php.ini中关闭cgi.force_redirect,启用fastcgi.impersonate,启用cgi.rfc2616_header

  2、下载http://www.caraveo.com/fastcgi/fastcgi-0.6.zip并将其中的isapi_fcgi.dll解压缩到c:\php目录下(不是必须在此目录,这里只是叙述方便)。

  3、使用regedit.exe建立如下注册表项:
  HKEY_LOCAL_MACHINE:Software\FASTCGI\.php (必需)

  4、在此项下建立如下键值:
  字符串类型:AppPath,值为c:\php\php-cgi.exe (必需)
  字符串类型:BindPath,值为php-fcgi      (必需)
  以下是可选配置键值:
  DWORD类型:StartServers,启动时默认启动的解释器个数,默认值5
  DWORD类型:MaxServers,最大解释器个数,默认25
  DWORD类型:IncrementServers,当解释器不够用时增量个数,默认2
  DWORD类型:Timeout,增量解释器(超出StartServers数目的)存活时间,默认600(秒)
  DWORD类型:ThreadPoolSize,线程池大小,仅IIS下有效,默认10
  DWORD类型:Impersonate,仅IIS有效,如果为1,使用IIS安全标志,为0则关闭此特性。不要关闭它除非你不担心安全问题。默认1
  DWORD类型:MaxPostData,Post数据预读Byte限制,默认0
  DWORD类型:BypassAuth,仅IIS有效,如果为1并且isapi_fcgi.dll被配置为IIS Filter,同时IIS被配置为使用BASIC Authentication,这将强制所有认证请求使用IIS匿名用户。这一选项的目的是允许脚本实现自己的安全机制。默认0
  BINARY类型:CustomVars,附加环境变量值,新行分隔,Null结束

  5、如果是IIS6,添加一个Web服务扩展指向c:\php\isapi_fcgi.dll,并允许。应用程序池中的“最大工作进程数”请保持为1。

  6、添加应用程序扩展映射关系:
      1). 在Internet信息服务管理器中,选择网站或应用程序的根目录。
      2). 打开目录属性页(右键选择“属性”),再选择“主目录”。
      3). 点击“配置”按钮,选择“映射”Tab页。
      4). 点击“添加…”,在“可执行文件”设为: c:\php\isapi_fcgi.dll,扩展名设为.php,一定要选择“确认文件是否存在”,然后“确定”保存设置。
      5). 再同样添加对.php3或.phtml扩展名的支持(可选)。
      6). 保存设定并重新启动IIS。

  7、测试一下,同时请求多个Web页面,然后察看任务管理器中的进程,页面完成后php-cgi.exe进程持续运行并不退出。

五、Apache配置方法
  1、首先确定你已正确安装了PHP 4.3.x及更新的版本。早期版本的PHP并未默认加入FastCGI支持,如果你想在早期版本中工作,需要重新编译它。我们假设PHP安装在c:\php,支持FastFCGI的可执行文件名是php-cgi.exe。
    注意:建议在Php.ini中打开cgi.force_redirect,关闭fastcgi.impersonate,关闭cgi.rfc2616_headers。

  2、下载http://www.fastcgi.com/dist/mod_fastcgi-2.4.2-AP20.dll,放到Apache 2.x的Modules目录中。

  3、确定Apache 2.x在CGI方式下可以正常运行PHP。httpd.conf中存在如下几行:
    ScriptAlias /php/ "c:/php/"
    Action application/x-httpd-php "/php/php-cgi.exe"
    SetEnv PHPRC "C:/php"
    AddType application/x-httpd-php .php

  4、在httpd.conf中添加:
    LoadModule fastcgi_module modules/mod_fastcgi-2.4.2-AP20.dll
    # 说明:此处的 -processes 3 表示启动三个 php-cgi.exe 进程,
    # 关于 FastCgiServer 的详细参数请参考 FastCGI 文档。
    FastCgiServer "c:/php/php-cgi.exe" -processes 3

  5、重新启动Apache,测试同上。

六、高级配置
  设想这样一种场景,你的服务器上同时跑Apache 2和IIS 6,两个Web服务器都跑php应用。那么,有如下三种可能:
  A、php使用iis isapi和apache module安装,均为多线程方式运行。这个和FastCGI没有关系。
  B、其中一个服务器使用FastCGI方式,另一个使用多线程方式。这个能运行正常。
  C、两个均使用FastCGI方式,这个往往不正常。一般表现为:
    两个服务器各自启动一些php-cgi.exe进程,然后服务器之一不解释php页面,或者隔一会儿就派生新的php-cgi.exe进程(可怕呀)。

  为什么呢?我想大概是因为上面使用的两个东西(iis isapi和apache module)的作者大概并没有想过要和对方同时使用吧,呵呵。想了想,Apache 2和IIS 6如果可以共用一批php-cgi.exe解释器就好了,既不浪费内存,估计也不会有调度问题了。
  经过研究和测试证明,这个想法是可行的。但是,由于Shane Caraveo并未在ISAPI DLL中提供使用外置FastCGI服务的功能,因此在此场景中只能是由IIS负责启动和管理php-cgi.exe,然后配置Apache去使用这些受 IIS管理的php-cgi.exe进程。

  配置方法:
  1、按上述四中的方法配置IIS FastCGI。
  2、基本按上述五中的方法配置Apache FastCGI,五.4改为在httpd.conf中添加:
    LoadModule fastcgi_module modules/mod_fastcgi-2.4.2-AP20.dll
    # 使用外部FastCGI服务器,请参考 FastCGI 文档。
    FastCgiExternalServer "c:/php/php-cgi.exe" -socket "php-fcgi"
  注意:-socket参数后的值必须与HKEY_LOCAL_MACHINE:Software\FASTCGI\.php中BindPath的值一致,这样两个FastCGI进程管理器才会使用同一个命名管道连接php-cgi.exe。

  注意:此配置中php-cgi.exe进程只受IIS中的FastCGI进程管理器管理, Apache的繁忙请求并不会使IIS中的FastCGI调度更多的php-cgi.exe进程。因此,在IIS中配置FastCGI时应当使 StartServers值足够大,以避免php解释器数量不足。同样带来的问题是,如果IIS关闭了,那么Apache就会找不到Php解释器了,这个要留心。

  由此带来的一个问题是:此时的php.ini中cgi.force_redirect、fastcgi.impersonate、cgi.rfc2616_headers应该怎么设定呢?这个留给大家去思考吧……呵呵

  另外一个可能遇到的问题是,IIS非常空闲,一段时间后由IIS启动的php-cgi.exe退出了,则apache就解释不了 Php了,怎么办呢?这时可以访问一下iis网站,php-cgi.exe就又起来了,晕哦。一个建议是使用IIS 6的进程池管理,在应用程序池中关掉“空闲超时”,并且,在“应用程序池标识”中将运行账号设定为与Apache服务启动账号一致。

分类: PHP 标签:

AJAX推送与拉取方式的比较(反向AJAX)

2009年12月11日 没有评论

      实时的动态数据比如新闻标题、证券报价和拍卖行情都需要尽快地发送给用户。然而,AJAX仍然受限于web请求/响应架构的弱点,使得服务器不能推送实时动态的web数据。            武汉百度推广

      Delft科技大学的Engin Bozdag、Ali Mesbah和Arie van Deursen一起讨论了下面这些可以实现基于web的实时事件通知的方法:

      1.HTTP拉取方式:在这种传统的方法中,客户端以用户可定义的时间间隔去检查服务器上的最新数据。这种拉取方式的频率要足够高才能保证很高的数据精确度,但高频率可能会导致多余的检查,从而导致较高的网络流量。而另一方面,低频率则会导致错过更新的数据。理想地,拉取的时间间隔应该等于服务器状态改变的速度。

      2.HTTP流:这种方法由存在于不间断的HTTP连接响应中或某个XMLHttpRequest连接中的服务器数据流所组成。                                       武汉百度公司

      3.反转AJAX:服务流应用到AJAX推送,就是所谓的反转AJAX 或者COMET 。它使得服务器在某事件发生时可以发送消息给客户端,而不需要客户端显式的请求。目标在于达到状态变化的实时更新。COMET使用了HTTP/1.1中的持续连接的特性。通过HTTP/1.1,除非另作说明,服务器和浏览器之间的TCP连接会一直保持连接状态,直到其中一方发送了一条明显的“关闭连接”的消息,或者有超时以及网络错误发生。

        4.长时间轮询:也就是所谓的异步轮询,这种方式是纯服务器端推送方式和客户端拉取方式的混合。它是基于BAYEUX协议的。这个协议遵循基于主题的发布——订阅机制。在订阅了某个频道后,客户端和服务器间的连接会保持打开状态,并保持一段事先定义好的时间。如果服务器端没有事件发生,而发生了超时,服务器端就会请求客户端进行异步重新连接。如果有事件发生,服务器端会发送数据到客户端,然后客户端重新连接。

在他们的实验性研究中,作者们在一个利用COMET推送方式实现(Dojo的Cometd库)的AJAX推送应用和一个纯拉取方式的应用之间,对数据一致性、服务器性能、网络性能以及数据遗失进行了比较。

分类: 前端技术 标签:

Unix/Linux 系统自动化管理: 邮件系统篇

2009年12月10日 没有评论

      本文是 Unix/Linux 系统管理自动化系列中的一篇,主要讲述邮件系统的配置,以及如何利用 Perl 脚本来实现电子邮件的自动发送。本文内容包括邮件传输代理 (MTA) 在 AIX 和 LINUX 系统中的具体配置,如何通过 sendmail 发送邮件,以及如何接收局域网内的用户邮件。

在 UNIX/Linux 系统的自动化管理中,利用脚本自动发送邮件的功能对系统监控的工作来说是非常重要的。系统管理人员可以利用 cron 或者 RMC 来创建监控脚本,一旦触发条件被满足,操作系统就会自动创建电子邮件,将相关的状态信息发送到指定的邮箱。通过电子邮件系统,系统管理人员就能够及时得获取被管理系统的状态,进而采取相应的措施。这种方式可以显著地节省系统管理人员的工作强度,并能够提高系统的可维护性。

Unix/Linux 邮件系统组成简介

在传统的 UNIX 和 Linux 系统中,电子邮件系统的主要组成部分包括邮件用户代理 (MUA — mail user agent)、邮件传输代理(MTA — mail transfer agent)、邮件提交代理 (MSA — mail submission agent)、邮件投递代理 (MDA — mail delivery agent) 和邮件访问代理 (MAA — mail access agent)。在日常工作中,系统管理人员经常接触的主要有邮件用户代理 (MUA) 和邮件传输代理 (MTA)。在 AIX 系统中,一个典型的邮件系统如图 1 所示。

图 1. 邮件系统示意图



邮件用户代理(MUA)是一个用来读写 mail 的程序,实际上就是邮件系统的客户端程序。它提供了阅读,发送和接受电子邮件的用户接口。最常用的邮件用户代理有 mutt,mail,elm,pine,它们都是随基本系统安装的 简单邮件应用程序

邮件传输代理(MTA)是一个在两个主机之间或者本地同一主机内传送邮件的程序,它负责邮件的存储和转发,并决定传送邮件到目的地的路线。UNIX/Linux 系统的标准 MTA 是 sendmail,其他的 MTA 还有 qmail, exim 和微软的 Exchange。MTA 会监视用户代理的请求,根据电子邮件的目标地址找出对应的邮件服务器,在服务器之间传输邮件并将接收到的邮件进行缓冲。

邮件投递代理(MDA)通常被 MTA 用来投递邮件到接收者的邮箱中。它能够从 MTA 接收邮件,并根据指定的规则来进行本地投递;它可以把邮件投递到本地用户、邮件列表、文件或者应用程序。UNIX/Linux 系统中常用的 MDA 包括 maildrop、procmail、postfix 和 delivermail 等。Postfix 用一个或多个 MDA 来递送邮件 , procmail 是另外一个有名的 MDA.

邮件提交代理(MSA)负责消息发送之前的所有必须完成的准备工作和错误检测。MSA 就如同在 MUA 和 MTA 之间的一个头脑清醒的检测人员,它会对所有的主机名和从 MUA 得到的信息头等信息进行检测。

MAA 邮件访问代理(MAA)将用户连接到邮件系统,并通过 POP 或 IMAP 协议来收取邮件。UNIX/Linux 系统中,常用的 MAA 有 UW-IMAP、Cyrus-IMAP、COURIER-IMAP 等;当邮件向目的地址进行传输时,一旦源地址和目的地址都不是本地系统,那么本地系统就会作为邮件的中继。

对于大多数邮件用户来说,利用邮件客户端来接收、查看和发送电子邮件是最常用的功能。接收和查看邮件比较简单,但是电子邮件的发送则相对复杂。在下面的章节里面,本文将根据不同的操作系统来具体介绍如何配置邮件服务器。

发送邮件代理配置及自动化发送

Linux 的 sendmail 配置

配置文件

在 Linux 系统中,Sendmail 包括如下配置文件:

  • /etc/sendmail.cf
  • /etc/mail/access
  • /etc/mail/aliases
  • /etc/mail/local-host-names
  • /etc/mail/mailertable
  • /etc/mail/virtusertable
  • /etc/mail/domaintable
  • ~/.forward

我们将会 下面的章节中详细介绍这些配置文件。

/etc/sendmail.cf

/etc/sendmail.cf 是 sendmail 的主配置文件。该文件存储了正在运行的 mailer 程序的类型信息,定义了重写邮件地址的规则和 sendmail 命令的操作环境。因为 sendmail.cf 的语法比较复杂,我们一般不建议手动修改该配置文件。安装了 sendmail 的 UNIX/Linux 系统都会带有 sendmail.cf,而且该配置文件在大多数情况下都不需要修改就可以使用。如果用户确实需要修改 sendmail.cf 配置文件 , 一般建议用户基于 sendmail.mc 宏文件,利用 m4 程序来生成新的 sendmail.cf 文件。

在 RedHat Linux 系统中,sendmail.mc 宏文件位于 /etc/mail/ 目录。

而 SUSE Linux 系统并没有 sendmail.mc 文件,相应的,它提供了 /etc/mail/linux.mc ( 或者 /etc/mail/linux.nullclient.mc) 替代 sendmail.mc。/etc/mail/linux.mc 是 SuSEconfig 使用 /etc/rc.config 和 /etc/rc.config.d/sendmail.rc.config (SuSE <= 7.3) 或者 /etc/sysconfig/sendmail (SuSE >= 8.0) 的参数而生成的宏文件。SuSEconfig 执行 /sbin/conf.d/SuSEconfig.sendmail 脚本来构建 .mc 文件,并执行 m4 来生成 sendmail.cf 配置文件。用户可以依照清单 1 所示的 SuSEconfig.sendmail 命令来生成配置文件。

清单 1. 使用 SUSEconfig.sendmail 命令生成配置文件

/ sbin/conf.d/SUSEconfig.sendmail -m4 > sendmail.mc

在 sendmail.mc 配置文件中经常出现如下的 m4 命令:

define:

用于定义配置文件中变量的值

divert:

用于定向 m4 进程的输出。

divert 被设置为 -1 时 , 取消输出。如果 divert(-1) 在一个文本块的前面出现,这段文本将不会再 sendmail.cf 中出现 . divert 被设置为 0 时来定向数据流的输出,如 sendmail.cf,

VERSIONID:

配置文件定义版本控制信息。

dnl:

注释掉后面的所有字符。

dnl 出现在行尾,表示将清除掉不想要的空白行;dnl 出现在行首,表示这一行将被当成注释。

DOMAIN:

选择传输邮件的域。

FEATURE:

识别配置文件中一个特性 (Feature)。

MAILER:

识别包含在 sendmail.cf 一套邮件传输方法。

OSTYPE:

定义宏所使用的操作系统,它允许 m4 程序增加同相关操作系统相关的文件。

undefine:

清除配置文件中的变量值。

需要注意的是,m4 宏处理器生成的 sendmail.cf 文件必须放在 /etc/ 目录 , 而非 /etc/mail。具体的操作如清单 2 所示。

清单 2.m4 命令生成配置文件 sendmail.cf

cp /etc/sendmail.cf/etc/sendmail.cf.bak m4sendmail.mc > sendmail.cf 

在用户修改完成 sendmail.cf 配置文件以后,最后一步操作是重新启动 sendmail 服务,具体的操作如清单 3 所示:


清单 3. 重启 sendmail 服务
service sendmail restart

/etc/mail/access 和 access.db

access 数据库是由 sendmail V8.9 版本引入的特性, 并在 V8.10 重得到很好的发展。它提供了一个单一集中管理的访问规则数据库;它可以基于发信者的姓名、地址或者 IP 来判断是否接受 (OK)、转发 (RELAY)、拒绝 (REJECT) 或者取消 (DISCARD)。sendmail 会在接收邮件时进行规则判断,默认情况下只接受本机发送的邮件。

对本地设置来说,/etc/mail/access 和 access.db 并不是必需的;只有在建立中央邮件集中服务器来处理所有邮件的时候才需要这两个文件。

access 数据库的配置主要有三个步骤,具体操作如下所示。

  1. 修改 /etc/mail/access 文件;修改后的内容如清单 4 所示。

    清单 4./etc/mail/access 文件内容

    localhost.localdomainRELAY localhostRELAY 127.0.0.1RELAY 192.168.1RELAY
  2. 利用 /etc/mail/access 创建数据库映射文件 access.db,命令如清单 5 所示。

    清单 5. 生成数据库映射文件 access.db

    makemap hash /etc/mail/access.db < /etc/mail/access
  3. 重启 sendmail, 读取 access.db,具体的命令如清单 3 所示。
    service sendmail restart

/etc/mail/aliases 和 aliases.db

aliases 是 sendmail 邮件系统的别名数据库。它可以定义邮递列表,在机器之间转发邮件,或者允许用多个名字指定一个用户。因为 Aliases 别名处理的规则是递归的,所以一个别名指向的目的地也可以是别名。对于每个信封,sendmail 都会在别名文件中查找本地用户的收件人名称。由于 Sendmail 的可能要在 aliases 文件中搜索数以千计的收件人名称,所以一个以 DB 数据库格式存储的 aliases 文件副本被创建,并用来提高查询的速度。

同样,这两个配置文件也不是必需的。如果 sendmail 是使用中央服务器的邮件处理中心处理所有邮件的话,安装在邻居服务器或客户机的 aliases 和 aliases.db 文件就不需要了。 aliases 数据库的配置主要有三个步骤,如下所示。

1.修改 /etc/mail/aliases。修改后的内容如清单 6 所示。

清单 6. 修改后的 aliases 文件

# Basic system aliases that MUST be present.postmaster:rootmailer-daemon:postmaster

# amavisvirusalert:root

2.根据 /etc/mail/ aliases 来创建数据库映射文件 aliases.db,该命令如清单 7 所示。

清单 7. 创建数据库映射文件 aliases.db

makemap hash /etc/mail/aliases.db < /etc/mail/aliases

3.重启 sendmail,读取 aliases.db,具体的命令如清单 3 所示。

service sendmail restart

其他配置文件

除了上文中介绍的配置文件以外,sendmail 还使用了其他的一些配置文件,本节将逐一介绍这些配置文件。

/etc/mail/local-host-names

设置服务器提供服务的域名,即本地主机名的主机名列表。该文件被修改后,sendmail 必须重新启动来更新设置;

/etc/mail/virtusertable 和 virtusertable.db

virtusertable 数据库用于映射虚拟域到新的地址。这个特性可以使网络上的虚拟域邮件被投递到本地系统、远程系统或者单一用户地址。/etc/mail/virtusertable 被修改以后,我们可以使用 makemap 命令来生成 /etc/mail/virtusertable.db。 同样,该文件被修改后,sendmail 必须重新启动来更新设置。

/etc/mail/domaintable 和 domaintable.db

domaintable 数据库用于映射旧域名到新域名。这个特性使得网络上多个域名可以由旧域名重写到新域名中。/etc/mail/domaintable 文件被修改后,我们可以利用 makemap 命令来生成 /etc/mail/domaintable.db。同样,该文件被修改后,sendmail 必须重新启动来更新设置。

/etc/mail/mailertable 和 mailertable.db

mailertable 数据库通过一种特殊的邮寄程序,把寻址到特定主机(或域)的邮件重定向到替代的目的地。这个特性使得网络上的邮件可以通过特殊的投递代理被投递到一个新的本地域名或远程域名。/etc/mail/mailertable 被修改后,我们可以利用 makemap 命令生成 /etc/mail/mailertable.db。同样,该文件被修改后,sendmail 必须重新启动来更新设置。

~/.forward

普通用户可以通过主目录下的 .forward 文件来实现邮件的别名和转发等功能。

验证 sendmail 服务

我们可以通过 telnet 程序来访问 localhost 的 25 端口,从而可以验证 sendmail 服务是否正常启动。如果能够登陆成功,则说明 sendmail 服务已经成功启动。具体的验证过程如清单 8 所示。

清单 8. 验证 sendmail 服务

linux:~ # telnet localhost 25Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.220 linux ESMTP Sendmail 8.13.6/8.13.6/SUSE Linux 0.8; Sat, 12 Sep 2009 14:37:24 -0700ehlo localhost250-linux Hello localhost [127.0.0.1], pleased to meet you250-ENHANCEDSTATUSCODES250-PIPELINING250-8BITMIME250-SIZE250-DSN250-ETRN250-DELIVERBY250 HELP

自动发送邮件的脚本实现

在 SLES11 系统中,sendmail-8.13.6-9.15 已经被默认安装,清单 9 所示的 Perl 脚本可以实现从本地主机自动发送邮件到远程邮箱的功能,发送的邮件将包含发送者的 mail 地址、接收者的 mail 地址、邮件主题、邮件的内容以及两个附件。

清单 9. 自动发送邮件的 Perl 脚本

#!/usr/bin/perl# 将要使用 sendmail 来发送邮件 my $mailprog = "/usr/sbin/sendmail";# 发送者的邮件地址 my $ senderemail = "sender\@cn.ibm.com";# 发送者的名字 my$sender = "sender";# 发送时的时间 my $datestring=`date +%m.%d.%Y`;# 接收者的 email 地址 my $email = "receiver\@cn.ibm.com";# Send file to user in emailopen(MAIL, "|$mailprog -f $sender -t $senderemail") or die;# 创建发送邮件的头 print MAIL "From: $sender\n";print MAIL "To: $email\n";# 主题 print MAIL "Subject: Automation test on SELS $datestring\n";#email 的信件内容 print MAIL "Hi All\nthis is the automation test result on $datestring. Please checktheattached files.\n";# 第一个附件 $file = "/tmp/28279.txt";open(FILE, "uuencode $file $file |") or die;print MAIL<FILE>;close(FILE);# 第二个附件 $file="/tmp/28280.txt";open(FILE, "uuencode $file $file |") or die;while( <FILE>) { print MAIL; };close(FILE);# 完成邮件发送 close(MAIL);

AIX 的 sendmail 配置

AIX 的 mail 系统中最重要的三个组成部分是用户接口 (the user interface)、消息路由程序 (the message routing program) 和消息投递程序 (the message delivery program) 或 mailer。AIX 系统中的 mail 程序就是所谓的用户接口 (the user interface),它对应上文提到的邮件用户代理 MUA;sendmail 程序就是所谓的消息路由程序 (the message routing program),它对应前面所说的邮件传输代理 MTA。在传递邮件的时后,如有必要,sendmail 命令将与远程系统建立 TCP/IP 连接 , 然后使用 SMTP 传递邮件到远程系统。

AIX 邮件系统的工作原理和配置,和 Linux 基本都相同,特殊的地方有以下几点。

  1. 生成配置文件的脚本的位置

    /usr/samples/tcpip/sendmail/cf/aixsample.mc 被用来生成 sendmail 相应的配置文件。

  2. sendmail daemon 启动和关闭的方式

    启动 sendmail:

    startsrc -s sendmail

    关闭 sendmail:

    stopsrc -s sendmail
  3. 通过 SMTP 服务器发 Internet 邮件

    在使用 SMTP 代理的情况下,sendmail 需要对 /etc/sendmail.cf 配置文件中的 DS 项进行修改。DS 项是指被用来转发邮件的主机。注意,该配置项修改以后,sendmail daemon 必须重启才能生效。/etc/sendmail.cf 文件的具体的修改内容如清单 10 所示。

    清单 10./etc/sendmail.cf 文件的修改内容

    # "Smart" relay host (may be null)DS[SMTP 的主机 IP] 

    自动发送邮件的脚本实现

    在 AIX6100-03 操作系统中,sendmail version AIX6.1/8.13.4 已经被默认安装。在这样的配置环境中,本节将给出两个实现不同功能的 Perl 脚本。

    清单 11 中的 Perl 脚本实现了邮件带主题和附件的功能。


    清单 11. 带有附件的邮件自动化发送邮件脚本

    #!/usr/bin/perl# 接受者的邮件系统 my $email = "receiver\@cn.ibm.com";# 将作为附件发送出去的两个文件 my $file1="/tmp/1.txt";my $file2="/tmp/2.txt";# 将要使用的邮件发送程序 my $mailprog = "/usr/bin/mail";# 记录发送时间 my $datestring=`date +%m\/%d\/%Y`;chomp($datestring);#email 的主题 my $subject= "\"Subject: Test on AIX $datestring with attachment\"";# 产生发送邮件命令 my $cmd_sendmail = "uuencode$file1 \"1.txt\" $file2\"2.txt\" |";$cmd_sendmail .="$mailprog -s $subject $email ";# 执行发送命令 system($cmd_sendmail);

    清单 12 中的 Perl 脚本实现了不带附件、有邮件内容的自动化发送邮件的功能。

    清单 12. 不带附件的邮件自动发送邮件的脚本实现

    #!/usr/bin/perl# 接受者的邮件系统 my $email = "receiver\@cn.ibm.com";# 记录发送时间 my $datestring=`date +%m\/%d\/%Y`;chomp($datestring);#email 的主题 my $subject= "\"Subject: Test on AIX $datestring \"";# 产生发送邮件命令 my$cmd_sendmail = "echo $message |";$cmd_sendmail .="$mailprog -s $subject $email";# 执行发送命令 `$cmd_sendmail`;

    不依赖邮件客户端配置的实现

    利用 Perl 模块实现邮件的发送

    我们同样可以借助许多现有的 Perl 模块来实现电子邮件的发送功能。从 CPAN 网站上的如下链接 (http://search.cpan.org/modlist/Mail_and_Usenet_News/Mail) 中,我们可以找到许多与 Mail 配置、传输相关的 Perl 模块,比如 Mail::Mailer,Mail::POP3Client, Mail::Postfix, Mail::Internet, Mail::Sendmail, Mail::Sender 等等。

    CPAN 网站上有如此众多的 Perl 模块可供选择,我们最终选择了 Mail::Mailer。Mail::Mailer 是由 Mark Overmeer 开发的,已经被集成进 MailTools 模块。目前 Mail::Mailer 版本为 2.04,用户可以在如下的链接地址上找着详细的介绍信息:http://search.cpan.org/~markov/MailTools-2.04/lib/Mail/Mailer.pod。总体上来说,Mail::Mailer 的实现很简洁,虽然它提供了很少的编程接口,但对于邮件的发送来说已经足够。

    Mail::Mailer 的安装

    我们可以通过 CPAN 来安装 Mail::Mailer。不过需要注意的是,在使用 CPAN 安装 Mail::Mailer 之前,我们需要确保计算机可以连接到 Internet 网络。

    我们可以在 Linux/UNIX 终端下输入清单 13 中的命令进入 CPAN 的操作界面。CPAN 的命令行界面如清单 14 所示。


    清单 13. 进入 CPAN 操作界面
    perl -MCPAN -e shell

    清单 14.CPAN 的命令行界面

    cpan shell -- CPAN exploration and modules installation (v1.9205)ReadLine support available (maybe install Bundle::CPAN or Bundle::CPANxxl?)cpan[1]>

    其中,cpan[1]>是 CPAN shell 的提示符;我们可以在它后面输入相应的 CPAN 命令来完成特定的功能。最后,我们可以通过在 CPAN 的操作界面中输入清单 15 中的命令来安装 Mail::Mailer。CPAN 会自动连接到 CPAN 网站搜索并下载 Mail::Mailer 相关的包,并最终完成 Mail::Mailer 的安装。

    清单 15. 安装 Mail::Mailer

    cpan[1]> install Mail::Mailer

    Mail::Mailer 的接口

    Mail::Mailer 提供的是面向对象的接口。它非常简单,除了 Mail::Mailer 对象构造和析构的方法以外,只有一个 open 方法需要介绍。

    使用 new 来构造 Mail::Mailer 对象的方法如清单 16 所示。

    清单 16.Mail:Mailer 对象的构造方法

    Mail::Mailer->new(TYPE, ARGS)

    其中,TYPE 是指后台的邮件发送程序,而 ARGS 是指传递给该后台邮件发送程序的参数列表。目前可用的 TYPE 值有 sendmail,smtp,qmail 和 testfile。

    sendmail:

    它会调用系统中已安装的 sendmail 做为邮件发送程序;

    smtp:

    它会通过 Net::SMTP 模块去投递邮件;

    qmail:

    它就会使用 qmail 的 qmail-inject 程序去发送邮件;

    testfile:

    用来调试的参数,它会将相关的数据写入日志文件。

    另外需要说明的方法是 $obj->open(),它的声明和参数说明如清单 17 所示。

    清单 17.Mail::Mailer 对象的 open() 方法

    $obj->open(HASH)

    当通过 Mail::Mailer->new(TYPE, ARGS)成功创建 Mail::Mailer 对象以后,我们就可以通过 open() 方法来构建邮件。这里 HASH 类型的参数包含一系列的 key 和对应的 value;注意,这些 key 值必须是邮件的 head 域所包含的值,比如 To,From,Replyto,Subject,Cc,Bcc 等等;而 value 必须是这些 key 所对应的值。

    Mail::Mailer 发送邮件的脚本实现

    我们将给出一个使用 Mail::Mailer 来发送电子邮件到指定邮箱的实例,如清单 18 所示。我们使用 sendmail 作为后台的邮件发送程序。

    清单 18. 使用 Mail::Mailer 发送邮件

    #!/usr/bin/perl – wuse Mail::Mailer;# 构造 Mail::Mailer 对象 my $mail = Mail::Mailer->new( ‘ sendmail ’ )or die “Couldn ’ t create Mail::Mailer object!\n”;# 构建邮件 $mail_headers->open({From => 'root@root-desktop',To => 'yourname@yourmail.com',Subject => 'Mail::Mailer is used',});# 发送邮件 print $mail “This is the body part of the message you can write your message here”;$mail->close($mail_headers);exit 0;

    结合 cron 的系统监控功能实现

    系统管理人员可以结合 cron 与电子邮件的自动发送功能,实现系统状态的自动监控功能。cron 是一个定时调度任务的守护进程,它可以根据时间、日期、月份、星期的组合来调度任务。关于 cron 的详细教程,读者可以参考在 developerworks 上的教程《 使用 cron 进行自动维护》,或者参考 Internet 上的相关文章。

    监控系统 CPU 利用率(LINUX)

    我们首先实现一个可以获取当前系统 CPU 使用率的 Perl 脚本。它可以获取当前的 CPU 使用率,一旦获取到的 CPU 使用率超过 85%,该脚本就会自动发送电子邮件给指定的用户。注意,该脚本只能运行于 Linux 平台。

    具体的 Perl 脚本内容可以参考清单 19。

    清单 19. 监控系统 CPU 利用率的脚本

    #!/usr/bin/perluse Mail::Mailer;sub get_cpu_stat {my @stats;my $fh;#Linux 系统,从 /proc/stat 来获取 CPU 信息open($fh, "cat /proc/stat |") or die "$!";while (<$fh>) {#get the cpu statif (/^cpu .*/) {@stats = split;}}close $fh;#then, we parse the cpu stat information;#the information from "man proc",#the format is for Linux 2.6.11 or higher#cpuusernicesystem idleiowait irqsoftirq steal#cpu628808 16426186124978051 22640349308600# 数据格式如上所示,更详细的信息请参考 proc 的 manpagemy $total = $stats[1] + $stats[2] + $stats[3] + $stats[4];my $idle = $stats[4];# 返回当前 CPU 的 total 和 idle 时间片计数return ($total, $idle);}my $mailer = Mail::Mailer->new('sendmail');my ($t1, $i1) = get_cpu_stat();sleep 5;my ($t2, $i2) = get_cpu_stat();my $total = $t2 - $t1;my $idle = $i2 - $i1;# 计算获取 5 秒钟之内的 CPU 利用率 my $per = 100 * ($total - $idle) / $total;if( $per > 85) {# 如果 CPU 利用率大于 85%my $msg = sprintf("!!!Attention\nThe CPU usage on your server is %.2f". "% right now!\nPleasecheck it right now!\n", $per);#send mail to the assigned user# 发送邮件给指定的用户$mailer->open({From => 'root@minjun-desktop',To => 'minjun.xi@cn.ibm.com',Subject => 'Attention for your cluster',})or die "Mail::Mailer failed!\n";print $mailer $msg;$mailer->close();}

    配置 cron 任务

    我们可以利用“crontab”命令来配置 cron 任务;在本文中,我们设定每个小时的第 30 分钟运行一下监控系统 CPU 利用率的脚本。我们使用”crontab – e”命令来编辑当前用户的 cron 任务,编辑的内容如清单 20 所示,其中 mon.pl 是清单 19 中 Perl 脚本的名称,/path/to/ 是指 mon.pl 脚本的路径。

    清单 20. 配置 cron 任务

    30 * * * * perl /path/to/mon.pl

    小结

    本文是 Unix/Linux 系统管理自动化系列中的一篇,主要讲述 UNIX/Linux 的邮件系统的配置,并讲述了如何使用 Perl 脚本来实现邮件的自动发送和接收;最后,本文把自动发送邮件的功能与 cron 系统结合在一起,给出了监控系统 CPU 利用率的脚本实现。系统管理人员可以利用类似的功能来实现系统的自动化管理,从而减轻自己的工作强度,并且提高系统的可维护性。

    参考资料

    学习

    Unix/Linux 系统自动化管理系列文章:Unix/Linux 操作系统提供了大量功能强大的工具和脚本语言(如 Perl,Python 等),让系统管理员可以根据自己的需求定制很多的自动化任务,如系统监控、数据备份、邮件通知、报表生成等工作。本系列文章主要关注于实现 Unix/Linux 系统上的管理自动化,让读者了解到脚本语言以及相关的工具可以让日常的管理工作变得更加轻松。

    http://www.sendmail.org/:sendmail 的官方网站,用户可以获取到更详细的 sendmail 资源。

    Securing and Optimizing Linux: RedHat Edition -A Hands on Guide:其中第 22 章节“Chapter 22. Software -Server/Mail Network”详细介绍了 Redhat Linux 环境下 sendmail 邮件系统的配置。

    IBM Certification Study Guide p5 and pSeries Administration and Support for AIX 5L Version 5.3:介绍 AIX5.3 系统管理的红皮书,内容相当全面广泛。其中 mail 系统部分的介绍也很详细,对 AIX 用户非常有参考价值。

    CPAN:Comprehensive Perl Archive Network,它包含了众多的 Perl 扩展模块和文档。

    Mail::Mailer:一个与邮件系统有关的 Perl 扩展模块,由 Mark Overmeer 开发。

    AIX and UNIX 专区 :developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。

    AIX and UNIX 新手入门 :访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。

    AIX and UNIX 专题汇总 :AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。

    developerWorks 技术活动 和 网络广播 :随时关注 developerWorks 技术活动和网络广播。

    获得产品和技术

    IBM 试用软件 :使用可从 developerWorks 直接下载的软件构建您的下一个开发项目。

    讨论

    Podcasts:听取 IBM 技术专家的讨论。

    developerWorks blog:参与 developerWorks 博客并加入 developerWorks 社区 。

    参与 AIX 和 UNIX 论坛:

    AIX 论坛

    AIX 开发人员论坛

    Cluster Systems Management

    IBM 支持帮助论坛

    性能工具论坛

    虚拟化论坛

    更多 AIX 和 UNIX 论坛

    作者简介

    郗闽军是 HPC 部门的软件工程师,主要从事集群系统管理软件的相关研发工作。

    文刀是 HPC 部门的软件工程师,主要从事集群系统管理软件的相关研发工作。

    原文引用:http://www.linuxidc.com/Linux/2009-11/23111.htm

分类: Linux 标签:

分布式数据库拆表拆库的常用策略

2009年12月8日 没有评论

      在大容量,高负荷的web系统中,对数据库进行一系列拆分,可有效提升数据库容量和性能。在初学程序的早期,程序员通常都喜欢按传统数据库设计模式,设计为单库和单一功能表的结构,这样的结构在数据量和并发量达到一定程度之后,会出现严重性能问题和维护问题。在出现问题的时候才着手进行优化,会非常痛苦,所以应该在系统架设之初就考虑好之后会出现的问题。           武汉百度推广

      目前有些数据库策略是采用单库结构,然后通过同步分发到数台服务器实现读写分离。个人觉得这样的策略非常笨拙,还是想办法将其分隔开来好,否则每台机器的内存都很容易超支。

        一般只对数据量比较大的表进行拆分,这应该没有什么异议;还有一种是有可能会进行维护的比较重要的表,比如文章目录表,如果有从其它系统倒数据进来的可能的话,也要拆掉,不然倒数据时一不小心把目录表弄坏了,发现忘了备份,那真是欲哭无泪。

下面来分析一下:

一、时间结构

      如果业务系统对时效性较高,比如新闻发布系统的文章表,可以把数据库设计成时间结构,按时间分有几种结构:

1) 平板式

表类似:
article_200901
article_200902
article_200903

用年来分还是用月可自定,但用日期的话表就太多了,也没这必要。一般建议是按月分就可以。

      这种分法,其难处在于,假设我要列20条数据,结果这三张表里都有2条,那么业务上很有可能要求读三次表。如果时间长了,有几十张表,而每张表是0条,那不就是要读完整个系统的表才行么?另外这个结构,要作分页是比较难实现的。

主键:在这个系统中,主键是13位带毫秒的时间戳,不要用自动编号,否则难以通过主键定位到表,也可以在查询时带上时间,但比较烦琐。

2) 归档式

表类似:
article_old
article_new

      为了解决平板式的缺点,可以采用时间归档式设计,可以看到这个系统只有两张表。一张是旧文章表,一张是新文章表,新文章表放2个月的信息,每天定期把2个月中的最早一天的文章归入旧表中。这样一方面可以解决性能问题,因为一般新闻发布系统读取的都是新的内容,旧的内容读取少;第二可以委婉地解决功能问题,比如平板式所说的问题,在归档式中最多也只需要读2张表就完成了。

      归档式的缺点在于旧表容量还是相对比较大,如果业务允许,可对旧表中的超旧内容进行再归档或直接清理掉。

二、版块结构

        如果按照文章的所属版块进行拆表,比如新闻、体育版块拆表,一方面可以使每个表数据量分离,另一方面是各版块之间相互影响可降到最低。假如新闻版块的数据表损坏或需要维护,并不会影响到体育版块的正常工作,从而降低了风险。版块结构同时常用于bbs这样的系统。

板块结构也有几种分法:

1) 对应式

对于版块数量不多,而且较为固定的形式,就直接对应就好。比如新闻版块,可以分出新闻的目录表,新闻的文章表等。

news_category
news_article
sports_category
sports_article

可看到每一个版块都对应着一组相同的表结构,好处就是一目了然。在功能上,因为版块之间还是有一些隔阂,所以需要联合查询的需求不多,开发上比时间结构的方式要轻松。

主键:依旧要考虑的,在这个系统中,主键是版块+时间戳,单纯的时间戳或自动编号也能用,查询时要记得带上版块用于定位表。

2) 冷热式

对应式的缺点是,如果版块数量很大而且不确定,那要分出的表数量就太多了。举个例子:百度贴吧,如果按一个词条一个表设计,那得有多少张表呢?

用这样的方式吧。

tieba_汽车
tieba_飞机
tieba_火箭
tieba__unite

这个表汽车、火箭表是属于热门表,定义为新建的版块放在unite表里面,待到其超过一万张主贴的时候才开对应表结构。因为在贴吧这种系统中,冷门版块肯定比热门版块多得多,这些冷门版块通常只有几张帖子,为它们开表也太浪费了;同时热门版块数量和访问量等,又比冷门版块多得多,非常有特点。

unite表还可以扩展成哈希表,利用词条的md5编码,可以分成n张表,我算了一下,md5前一位可分16张表,两位即是256张表。

tieba_unite_ab
tieba_unite_ac

三、哈希结构

哈希结构通常用于博客之类的基于用户的场合,在博客这样的系统里有几个特点,1是用户数量非常多,2是每个用户发的文章数量都较少,3是用户发文章不定期,4是每个用户发得不多,但总量仍非常之大。基于这些特点,用以上所说的任何一种分表方式都不合适,一没有固定的时效不宜用时间拆,二用户很多,而且还偏偏都是冷门,所以也不宜用版块(用户)拆。

哈希结构在上面有所提及,既然按每个用户不好直接拆,那就把一群用户归进一个表好了。

blog_aa
blog_ab
blog_ac

如上所说,md5取前两位哈希可以达到1296张表,如果觉得不够,那就再加一位,总数可达46656张表,还不够?

表的数量太多,要创建这些表也是挺麻烦的,可以考虑在程序里往数据库insert之前,多执行一句判断表存在与否并创建表的语句,很实用,消耗也并不很大。

主键:依旧要考虑的,在这个系统中,主键是用户ID+时间戳,单纯的时间戳或自动编号也能用,但查询时要记得带上用户名用于定位表。

四、总分结构

以上的这些结构,根据每个业务系统,能想出的估计还有很多。不过现在互联网业务越来越复杂了,有些时候,单一的拆分法还不能实现需求,需要几种拆分方案一起实施,多管齐下,这时候其中的逻辑会让人绕晕。我就开发过一个系统,仅仅是将哈希结构和时间结构混着一用,觉得逻辑就相当复杂。

所以,除了拆表之外,按最原始的单库单表,再建一个总表,是非常有利的架构。在这个架构中,每次往数据库会写入两倍数据,读取主要依赖拆表提升性能,总表用于实现拆表后难以实现的功能并且用于每天的定时备份;另外总表和分表还相互是一个完整的备份,任何一个分表损坏或数据不正常,都可以从总表中读到正确的数据并恢复,反之亦然。               武汉百度推广电话

在总分结构中,让人感到质疑的是总表的性能和可维护性。我的方案是总表可采用相对能保证稳定的一些服务软件和架构,例如oracle,或lvs+pgpool+PostgreSQL,重点保证数据稳定;相对的,分表就用轻量级的mysql,重点在于速度。能够对总分表各采用不同的软件和方案,也是总分结构的一大特点。

总结:如何通过拆表来优化系统,最基本的是要按业务需求和特点分析。本文仅仅是提供了几种基本方法,具体工作要先动脑好好想,千万不可乱套,用错了工作量要加十倍噢。

分类: MySQL 标签: