生命之中的最大错误在于:终日担心犯错误。— 爱尔伯特·哈伯德 (Elbert Hubbard 1856-1915),《笔记》
本代码是从uchome的代码修改的,是因为要解决uchome的效率而处理的。
这个思维其实很久就有了,只是一直没有去做,相信也有人有同样的想法,如果有类似的,那真的希望提出相关的建议。
封装的方式比较简单,增加了只读数据库连接的接口扩展,不使用只读数据库也不影响原代码使用。
有待以后不断完善。。
为了方便,试试建立了google的一个项目:
http://code.google.com/p/mysql-rw-php/
希望给有需要的朋友带来帮助。
为什么需要读写分离?
主要是数据库压力过大的情况下的解决方案。写操作会把表锁定,而导致很多查询相继锁定而等候,导致程序处于等候状态。
读写分离是建立在mysql的replication基础上的,master服务器仅负责写操作,slave机器仅提供读操作,相对而言提高了读写性能,也可以增加mysql的承受能力。
PHP实现的Mysql读写分离
主要特性:
1 简单的读写分离
2 一个主数据库,可以添加更多的只读数据库
3 读写分离但不用担心某些特性不支持
4 缺点:同时连接两个数据库
英文比较烂,也写几个字吧
php code for mysql read/write split
feature:
simply rw split
one master,can add more slaves
support all mysql feature
link to the master and slave at the same time
这个思维其实很久就有了,只是一直没有去做,相信也有人有同样的想法,如果有类似的,那真的希望提出相关的建议。
封装的方式比较简单,增加了只读数据库连接的接口扩展,不使用只读数据库也不影响原代码使用。
有待以后不断完善。。
为了方便,试试建立了google的一个项目:
http://code.google.com/p/mysql-rw-php/
希望给有需要的朋友带来帮助。
为什么需要读写分离?
主要是数据库压力过大的情况下的解决方案。写操作会把表锁定,而导致很多查询相继锁定而等候,导致程序处于等候状态。
读写分离是建立在mysql的replication基础上的,master服务器仅负责写操作,slave机器仅提供读操作,相对而言提高了读写性能,也可以增加mysql的承受能力。
PHP实现的Mysql读写分离
主要特性:
1 简单的读写分离
2 一个主数据库,可以添加更多的只读数据库
3 读写分离但不用担心某些特性不支持
4 缺点:同时连接两个数据库
英文比较烂,也写几个字吧
php code for mysql read/write split
feature:
simply rw split
one master,can add more slaves
support all mysql feature
link to the master and slave at the same time
在使用中的环境如何在尽量少影响的情况下做数据库转移,这个有很多问题需要注意的,需要考虑周全。
这次要转移的数据库是MyISAM,转移起来比较简单,但目标数据库是Master-Slave方式的,所以转移起来需要注意:
1 转移到Master时,Master-Slave的数据应该是一样的,否则会导致同步出问题
2 转移到Master时,切换时间尽可能短
转移过程大概有以下阶段:
1 导出当前数据库的数据
2 导入到新的数据库
3 更改连接数据库的方式
第一阶段有好多方式:
1 导出sql文件mysqldump
适合数据不多而且有InnoDB的数据表的情况。
2 复制数据库mysqlhotcopy
适合MyISAM数据表
3 停止数据库,直接复制文件
适合懒人不怕停止服务的情况
第二阶段主要看你选择的第一阶段了:
1 导入sql文件
如果没有相应的数据库,需要创建
可以远程导入的,导入到Master数据库就可以了,slave会自动传输的
2 复制数据库文件
这里就简单的复制了,打包传输然后到目标数据库解压也就ok了
或者scp传输文件,NFS共享文件
Master和Slave都传输一样的文件,记得文件在目标服务器需要是mysql可读写的
第三阶段是在第二阶段完成后立刻做的,这里有一个快捷的方式来应对有很多PHP文件需要修改的情况:
假设原先的数据库的连接是 127.0.0.1 ,先修改为 mysqldb,然后在 /etc/hosts文件里面加一行指定
这样的好处是,转移数据库连接方式只是需要修改hosts文件即可一下子把所有数据库连接都修改了,无痛转移。。
但以上方法要求mysql端口要一致。
另外,如果没法修改为名称做连接,那可以启用mysql-proxy,做一下设置就可以了,详细可以查询相关资料
也可以使用rinted做端口代理应付转移的过渡期,参考rinetd
以上三种过渡方式设定后,再修改每个连接为新的服务器连接即可。
这次要转移的数据库是MyISAM,转移起来比较简单,但目标数据库是Master-Slave方式的,所以转移起来需要注意:
1 转移到Master时,Master-Slave的数据应该是一样的,否则会导致同步出问题
2 转移到Master时,切换时间尽可能短
转移过程大概有以下阶段:
1 导出当前数据库的数据
2 导入到新的数据库
3 更改连接数据库的方式
第一阶段有好多方式:
1 导出sql文件mysqldump
适合数据不多而且有InnoDB的数据表的情况。
mysqldump -S /Data/mysqldb/3306/mysql.sock -uusername -ppassword aslibra>backup.sql
-S 是sock文件的位置
-S 是sock文件的位置
2 复制数据库mysqlhotcopy
适合MyISAM数据表
mysqlhotcopy -S /Data/mysqldb/3306/mysql.sock -u username -p password --addtodest aslibra /backup/mysql/
-S 是sock文件的位置
--addtodest 是覆盖现有数据库文件
会复制一份在/backup/mysql/aslibra/XXX
-S 是sock文件的位置
--addtodest 是覆盖现有数据库文件
会复制一份在/backup/mysql/aslibra/XXX
3 停止数据库,直接复制文件
适合懒人不怕停止服务的情况
第二阶段主要看你选择的第一阶段了:
1 导入sql文件
mysql -S /Data/mysqldb/3306/mysql.sock -uusername -ppassword aslibra<backup.sql
如果没有相应的数据库,需要创建
可以远程导入的,导入到Master数据库就可以了,slave会自动传输的
2 复制数据库文件
这里就简单的复制了,打包传输然后到目标数据库解压也就ok了
或者scp传输文件,NFS共享文件
Master和Slave都传输一样的文件,记得文件在目标服务器需要是mysql可读写的
第三阶段是在第二阶段完成后立刻做的,这里有一个快捷的方式来应对有很多PHP文件需要修改的情况:
假设原先的数据库的连接是 127.0.0.1 ,先修改为 mysqldb,然后在 /etc/hosts文件里面加一行指定
127.0.0.1 mysqldb
这样的好处是,转移数据库连接方式只是需要修改hosts文件即可一下子把所有数据库连接都修改了,无痛转移。。
但以上方法要求mysql端口要一致。
另外,如果没法修改为名称做连接,那可以启用mysql-proxy,做一下设置就可以了,详细可以查询相关资料
也可以使用rinted做端口代理应付转移的过渡期,参考rinetd
以上三种过渡方式设定后,再修改每个连接为新的服务器连接即可。
上次写的《mysql的互为主从设置》,有点问题需要解决:
如何解决三台机器的主从一致性?
其实就是查一下如何记录日志的参数,发现了解决方式:
三台: 4308 <--- 4306 (log-slave-updates)<--> 4307
(my.cnf 里面添加一行 log-slave-updates)
也就是流程变成:
4306被修改,由于4307和4308都设置4306为master,所以都会正常发给4307和4308
4307被修改,则由于4306设置4307为master,所以会收到4307的修改,但log-slave-updates的参数就有一个效果,就是记录从master发来的修改也记录在bin日志,从而发给其它serverid的slave。
4308 <--- 4306 (log-slave-updates)
↓.............↑
4307--------->
(log-slave-updates)
也就是做成一个循环,即可三个实例互为master:
4306的修改会发送到4308(slave),由于4308记录了,同时也发给它的slave(4307)
4307的修改会发送到4306(slave),由于4306记录了,同时也发给它的slave(4308)
4308的修改会发送到4307(slave),由于4307记录了,同时也发给它的slave(4306)
不知道是否有效,但是有个问题是,一个实例挂了,似乎就容易出错了。
4308(只读) <--- 4306(读写) (log-slave-updates)<--> 4307(读写)
4309(只读) <------↓
................<------↓
两个读写的数据库互备,防止写入冲突,最好是里面的数据库是单独使用,就不至于产生自增字段冲突之类的了
...DB1 |
->DB2 |-> 4307
.................↑
.................↓
->DB1 |-> 4306 <---->Slave1 Slave2...
...DB2 | (log-slave-updates)
这样估计容易处理数据库的压力,还有待生产环境测试。
几个跟热备有关的mysql命令(参考)
SET SQL_LOG_BIN=0|1
#主机端运行,需要super权限,用来开停日志,随意开停,会造成主机从机数据不一致,造成错误
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=n
# 客户端运行,用来跳过几个事件,只有当同步进程出现错误而停止的时候才可以执行。
RESET MASTER
#主机端运行,清除所有的日志,这条命令就是原来的FLUSH MASTER
RESET SLAVE
#从机运行,清除日志同步位置标志,并重新生成master.info
虽然重新生成了master.info,但是并不起用,最好,将从机的mysql进程重启一下,
LOAD TABLE tblname FROM MASTER
#从机运行,从主机端重读指定的表的数据,每次只能读取一个,受timeout时间限制,需要调整timeout时间。执行这个命令需要同步账号有 reload和super权限。以及对相应的库有select权限。如果表比较大,要增加net_read_timeout 和 net_write_timeout的值
LOAD DATA FROM MASTER
#从机执行,从主机端重新读入所有的数据。执行这个命令需要同步账号有reload和super权限。以及对相应的库有select权限。如果表比较大,要增加net_read_timeout 和 net_write_timeout的值
CHANGE MASTER TO master_def_list
#在线改变一些主机设置,多个用逗号间隔,比如
CHANGE MASTER TO
MASTER_HOST='master2.mycompany.com',
MASTER_USER='replication',
MASTER_PASSWORD='bigs3cret'
MASTER_POS_WAIT() #从机运行
SHOW MASTER STATUS #主机运行,看日志导出信息
SHOW SLAVE HOSTS #主机运行,看连入的从机的情况。
SHOW SLAVE STATUS (slave)
SHOW MASTER LOGS (master)
SHOW BINLOG EVENTS [ IN 'logname' ] [ FROM pos ] [ LIMIT [offset,] rows ]
PURGE [MASTER] LOGS TO 'logname' ; PURGE [MASTER] LOGS BEFORE 'date'
如何解决三台机器的主从一致性?
其实就是查一下如何记录日志的参数,发现了解决方式:
三台: 4308 <--- 4306 (log-slave-updates)<--> 4307
(my.cnf 里面添加一行 log-slave-updates)
也就是流程变成:
4306被修改,由于4307和4308都设置4306为master,所以都会正常发给4307和4308
4307被修改,则由于4306设置4307为master,所以会收到4307的修改,但log-slave-updates的参数就有一个效果,就是记录从master发来的修改也记录在bin日志,从而发给其它serverid的slave。
4308 <--- 4306 (log-slave-updates)
↓.............↑
4307--------->
(log-slave-updates)
也就是做成一个循环,即可三个实例互为master:
4306的修改会发送到4308(slave),由于4308记录了,同时也发给它的slave(4307)
4307的修改会发送到4306(slave),由于4306记录了,同时也发给它的slave(4308)
4308的修改会发送到4307(slave),由于4307记录了,同时也发给它的slave(4306)
不知道是否有效,但是有个问题是,一个实例挂了,似乎就容易出错了。
4308(只读) <--- 4306(读写) (log-slave-updates)<--> 4307(读写)
4309(只读) <------↓
................<------↓
两个读写的数据库互备,防止写入冲突,最好是里面的数据库是单独使用,就不至于产生自增字段冲突之类的了
...DB1 |
->DB2 |-> 4307
.................↑
.................↓
->DB1 |-> 4306 <---->Slave1 Slave2...
...DB2 | (log-slave-updates)
这样估计容易处理数据库的压力,还有待生产环境测试。
几个跟热备有关的mysql命令(参考)
SET SQL_LOG_BIN=0|1
#主机端运行,需要super权限,用来开停日志,随意开停,会造成主机从机数据不一致,造成错误
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=n
# 客户端运行,用来跳过几个事件,只有当同步进程出现错误而停止的时候才可以执行。
RESET MASTER
#主机端运行,清除所有的日志,这条命令就是原来的FLUSH MASTER
RESET SLAVE
#从机运行,清除日志同步位置标志,并重新生成master.info
虽然重新生成了master.info,但是并不起用,最好,将从机的mysql进程重启一下,
LOAD TABLE tblname FROM MASTER
#从机运行,从主机端重读指定的表的数据,每次只能读取一个,受timeout时间限制,需要调整timeout时间。执行这个命令需要同步账号有 reload和super权限。以及对相应的库有select权限。如果表比较大,要增加net_read_timeout 和 net_write_timeout的值
LOAD DATA FROM MASTER
#从机执行,从主机端重新读入所有的数据。执行这个命令需要同步账号有reload和super权限。以及对相应的库有select权限。如果表比较大,要增加net_read_timeout 和 net_write_timeout的值
CHANGE MASTER TO master_def_list
#在线改变一些主机设置,多个用逗号间隔,比如
CHANGE MASTER TO
MASTER_HOST='master2.mycompany.com',
MASTER_USER='replication',
MASTER_PASSWORD='bigs3cret'
MASTER_POS_WAIT() #从机运行
SHOW MASTER STATUS #主机运行,看日志导出信息
SHOW SLAVE HOSTS #主机运行,看连入的从机的情况。
SHOW SLAVE STATUS (slave)
SHOW MASTER LOGS (master)
SHOW BINLOG EVENTS [ IN 'logname' ] [ FROM pos ] [ LIMIT [offset,] rows ]
PURGE [MASTER] LOGS TO 'logname' ; PURGE [MASTER] LOGS BEFORE 'date'
mysql做主从参考:
http://www.aslibra.com/blog/read.php/1039.htm
之前做过主从的设置,但考虑到两个主服务器做主备的情况,可以考虑互为主从。
原先主备:4306 ----> 4307
互为主从:4306 <--> 4307
之前的方式是这样的,假设两个mysql实例是4306和4307,4306是主,4307是从,则4306上的更改都会写入日志,从而4307的数据库可以随之更新,如果4306也设置4307为主服务器,则4307的更改也会更新到4306上。
有一点值得测试,更新的延时是否会有影响?
4306和4307的数据库如果同时向一个自增数据表写入数据,有可能出现自增的冲突。
三台: 4308 <--- 4306 <--> 4307
另外,如果还想增加一个slave,那其实没法再完整同步了。
假设4308做slave,master是4306,那其实只有4306上的操作会更新到4308,4307上的更新只能发到4306,但不会同时发到4308的数据库,所以只有更新到一部分。
所以,互为主从其实并不实用,除非保证一直使用其中一个,另外一个作为即时备份,可以使用LVS或者keepalived来让服务仅仅访问其中一个,另外,再次的切换时间如果比较快,有可能会出现自增字段的冲突。
那就是A和B同时监听某IP,LVS和keepalived来分配A和B的使用,A挂了,切换到B。一段时间后,A恢复了,然后A不适宜立刻使用,因为B上已经写入数据,对A而言,还是旧的数据,那此时访问到的是还没有通过REPLICATION取到数据,所以此时的切换就不能自动了,否则容易出错。
还是mysql_proxy可能比较有效,有待测试。
http://www.aslibra.com/blog/read.php/1039.htm
之前做过主从的设置,但考虑到两个主服务器做主备的情况,可以考虑互为主从。
原先主备:4306 ----> 4307
互为主从:4306 <--> 4307
之前的方式是这样的,假设两个mysql实例是4306和4307,4306是主,4307是从,则4306上的更改都会写入日志,从而4307的数据库可以随之更新,如果4306也设置4307为主服务器,则4307的更改也会更新到4306上。
有一点值得测试,更新的延时是否会有影响?
4306和4307的数据库如果同时向一个自增数据表写入数据,有可能出现自增的冲突。
三台: 4308 <--- 4306 <--> 4307
另外,如果还想增加一个slave,那其实没法再完整同步了。
假设4308做slave,master是4306,那其实只有4306上的操作会更新到4308,4307上的更新只能发到4306,但不会同时发到4308的数据库,所以只有更新到一部分。
所以,互为主从其实并不实用,除非保证一直使用其中一个,另外一个作为即时备份,可以使用LVS或者keepalived来让服务仅仅访问其中一个,另外,再次的切换时间如果比较快,有可能会出现自增字段的冲突。
那就是A和B同时监听某IP,LVS和keepalived来分配A和B的使用,A挂了,切换到B。一段时间后,A恢复了,然后A不适宜立刻使用,因为B上已经写入数据,对A而言,还是旧的数据,那此时访问到的是还没有通过REPLICATION取到数据,所以此时的切换就不能自动了,否则容易出错。
还是mysql_proxy可能比较有效,有待测试。
在考虑网站的稳定性的时候,我们不妨先分析一下访问一个网站会经过什么基本内容:
1 域名(DNS服务器)
2 IP(对某个机器)
3 Web服务器
4 动态脚本引擎
5 数据库
6 存储
要使得访问正常,那就得保证这六个步骤都很正常,我们看看会有哪些不正常的情况:
1 域名
要保证域名服务器的稳定,一般而言,都会有两个以上的域名服务器,域名基本上会有一个有效期,本身DNS体系就还算稳定,当然所有DNS服务器都无法访问到了,那就没辙了。
域名的延时可以设置时间长一点,这样会使得更加稳定,设置短一点,那是方便改变IP,切换服务器。
域名可以做多个指向,产生DNS轮询,也就是基本的域名到IP的负载均衡,也可以做不同地区的访问优化,访问不同服务器。
查看域名一般可以使用nslookup,在windows和linux下都有,比如 nslookup www.sohu.com
你可以得到如下信息:
也就是说是做了别名指向到 pgcnctct07.a.sohu.com,同时指定了8个服务器IP,用户访问时会随机选择其中一个访问
一般的域名是这样的信息:
2 IP
如果域名指向具体的IP了,这个IP对应的机器坏了,那就得换IP了,这个就会有时间上的延时,上面的指定8个IP,也就是让损失减少一点,但还是不合理的,我们需要用到虚拟IP,那可以更加有效的提供服务。
keepalived是解决这个问题而诞生了,它主要的功能是两个以上的机器添加一个虚拟IP(VIP),分等级高低,高的接管此VIP后,低等级的就备用,这样就可以让两个机器稳定提供服务了。
具体可以看看keepalived的网站:http://www.keepalived.org/
3 Web服务器
web服务器就有很多选择的空间了,这里面还有不同的架构,比如前端缓存、加速、代理、负载均衡等。
缓存类的有:Squid lighttpd ncache等
加速类:varnish等
代理类:LVS apache Nginx Haproxy lighttpd等
负载均衡类:LVS 上面代理类也有此功能
我们可以看看别人服务器都用了什么软件:
[root@localhost ~]# curl -I http://www.aslibra.com
HTTP/1.1 301 Moved Permanently
Date: Thu, 01 Jan 2009 14:03:47 GMT
Server: Apache
X-Powered-By: PHP/4.3.9
location: blog/
Connection: close
Content-Type: text/html
我的是虚拟主机,用的是apache,支持php
[root@localhost ~]# curl -I http://www.sohu.com
HTTP/1.0 200 OK
Date: Thu, 01 Jan 2009 14:01:13 GMT
Server: Apache/1.3.37 (Unix) mod_gzip/1.3.26.1a
Vary: Accept-Encoding,X-Up-Calling-Line-id,X-Source-ID,X-Up-Bearer-Type
Cache-Control: max-age=70
Expires: Thu, 01 Jan 2009 14:02:23 GMT
Last-Modified: Thu, 01 Jan 2009 14:00:14 GMT
Content-Type: text/html
Age: 24
Content-Length: 215936
X-Cache: HIT from 19709676.29867817.28603015.sohu.com
Via: 1.0 19709676.29867817.28603015.sohu.com:80 (squid/2.6.STABLE12)
Connection: close
sohu的服务器是apache,编译了gzip支持,不肯定是否PHP
前端加了缓存,有X-Cache标记,看Via标签知道是Squid
4 动态脚本引擎
这里动态脚本比较多,我也就知道php的了
PHP如果用在apache的模块上,很多时候都说占用资源比较大,而且这样apache性能不好
不妨可以试试fast-cgi方式,比较灵活,支持不同的web服务器,比如lighttpd和nginx
还支持负载均衡,可以用几个服务器做后端
5 数据库
数据库的稳定性也可以参考前面的VIP的解决方式,但要解决 主主同步的问题,这个我没测试过,还不好说
一般都可以做一个主备同步,这个很好做,做了主备同步后,一来有备份服务器,二来可以把只读操作放在slave服务器上,增加安全性和稳定性
Mysql同步和主从设置
6 存储
存储方面我还没有真正处理,但从单机考虑,可以有磁盘阵列和冗余校正应该就不错
对于存储的集群,也有很多解决方案,比如GFS、Mogile等解决方案,可以架设多个服务器做存储,方便空间扩展和存储稳定
以上步骤还有待日后再修正和完善
1 域名(DNS服务器)
2 IP(对某个机器)
3 Web服务器
4 动态脚本引擎
5 数据库
6 存储
要使得访问正常,那就得保证这六个步骤都很正常,我们看看会有哪些不正常的情况:
1 域名
要保证域名服务器的稳定,一般而言,都会有两个以上的域名服务器,域名基本上会有一个有效期,本身DNS体系就还算稳定,当然所有DNS服务器都无法访问到了,那就没辙了。
域名的延时可以设置时间长一点,这样会使得更加稳定,设置短一点,那是方便改变IP,切换服务器。
域名可以做多个指向,产生DNS轮询,也就是基本的域名到IP的负载均衡,也可以做不同地区的访问优化,访问不同服务器。
查看域名一般可以使用nslookup,在windows和linux下都有,比如 nslookup www.sohu.com
你可以得到如下信息:
引用
Name: pgcnctct07.a.sohu.com
Addresses: 61.135.179.184, 61.135.179.190, 61.135.179.191, 61.135.179.146
61.135.179.155, 61.135.179.160, 61.135.179.161, 61.135.179.166
Aliases: www.sohu.com, d7.a.sohu.com
Addresses: 61.135.179.184, 61.135.179.190, 61.135.179.191, 61.135.179.146
61.135.179.155, 61.135.179.160, 61.135.179.161, 61.135.179.166
Aliases: www.sohu.com, d7.a.sohu.com
也就是说是做了别名指向到 pgcnctct07.a.sohu.com,同时指定了8个服务器IP,用户访问时会随机选择其中一个访问
一般的域名是这样的信息:
引用
[root@localhost ~]# nslookup www.aslibra.com
Server: 202.106.0.20
Address: 202.106.0.20#53
Non-authoritative answer:
Name: www.aslibra.com
Address: 222.76.215.25
Server: 202.106.0.20
Address: 202.106.0.20#53
Non-authoritative answer:
Name: www.aslibra.com
Address: 222.76.215.25
2 IP
如果域名指向具体的IP了,这个IP对应的机器坏了,那就得换IP了,这个就会有时间上的延时,上面的指定8个IP,也就是让损失减少一点,但还是不合理的,我们需要用到虚拟IP,那可以更加有效的提供服务。
keepalived是解决这个问题而诞生了,它主要的功能是两个以上的机器添加一个虚拟IP(VIP),分等级高低,高的接管此VIP后,低等级的就备用,这样就可以让两个机器稳定提供服务了。
具体可以看看keepalived的网站:http://www.keepalived.org/
3 Web服务器
web服务器就有很多选择的空间了,这里面还有不同的架构,比如前端缓存、加速、代理、负载均衡等。
缓存类的有:Squid lighttpd ncache等
加速类:varnish等
代理类:LVS apache Nginx Haproxy lighttpd等
负载均衡类:LVS 上面代理类也有此功能
我们可以看看别人服务器都用了什么软件:
[root@localhost ~]# curl -I http://www.aslibra.com
HTTP/1.1 301 Moved Permanently
Date: Thu, 01 Jan 2009 14:03:47 GMT
Server: Apache
X-Powered-By: PHP/4.3.9
location: blog/
Connection: close
Content-Type: text/html
我的是虚拟主机,用的是apache,支持php
[root@localhost ~]# curl -I http://www.sohu.com
HTTP/1.0 200 OK
Date: Thu, 01 Jan 2009 14:01:13 GMT
Server: Apache/1.3.37 (Unix) mod_gzip/1.3.26.1a
Vary: Accept-Encoding,X-Up-Calling-Line-id,X-Source-ID,X-Up-Bearer-Type
Cache-Control: max-age=70
Expires: Thu, 01 Jan 2009 14:02:23 GMT
Last-Modified: Thu, 01 Jan 2009 14:00:14 GMT
Content-Type: text/html
Age: 24
Content-Length: 215936
X-Cache: HIT from 19709676.29867817.28603015.sohu.com
Via: 1.0 19709676.29867817.28603015.sohu.com:80 (squid/2.6.STABLE12)
Connection: close
sohu的服务器是apache,编译了gzip支持,不肯定是否PHP
前端加了缓存,有X-Cache标记,看Via标签知道是Squid
4 动态脚本引擎
这里动态脚本比较多,我也就知道php的了
PHP如果用在apache的模块上,很多时候都说占用资源比较大,而且这样apache性能不好
不妨可以试试fast-cgi方式,比较灵活,支持不同的web服务器,比如lighttpd和nginx
还支持负载均衡,可以用几个服务器做后端
5 数据库
数据库的稳定性也可以参考前面的VIP的解决方式,但要解决 主主同步的问题,这个我没测试过,还不好说
一般都可以做一个主备同步,这个很好做,做了主备同步后,一来有备份服务器,二来可以把只读操作放在slave服务器上,增加安全性和稳定性
Mysql同步和主从设置
6 存储
存储方面我还没有真正处理,但从单机考虑,可以有磁盘阵列和冗余校正应该就不错
对于存储的集群,也有很多解决方案,比如GFS、Mogile等解决方案,可以架设多个服务器做存储,方便空间扩展和存储稳定
以上步骤还有待日后再修正和完善
重启mysql时失败,提示“Table ´mysql.servers´ doesn´t exist ”
查一下资料得到一下两个解决方法,第一个试过可以:
使用MySQL Query Browser为mysql库创建缺失的表
系统数据库(mysql) 缺少表的创建sql命令为:
CREATE TABLE servers (
Server_name char(64) NOT NULL,
Host char(64) NOT NULL,
Db char(64) NOT NULL,
Username char(64) NOT NULL,
Password char(64) NOT NULL,
Port int(4) DEFAULT NULL,
Socket char(64) DEFAULT NULL,
Wrapper char(64) NOT NULL,
Owner char(64) NOT NULL,
PRIMARY KEY (Server_name)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table';
另外一种解决办法是:进入Mysql的bin目录运行 mysql -u root -p mysql
输入密码后运行
mysql> SOURCE ../share/mysql_fix_privilege_tables.sql
查一下资料得到一下两个解决方法,第一个试过可以:
使用MySQL Query Browser为mysql库创建缺失的表
系统数据库(mysql) 缺少表的创建sql命令为:
CREATE TABLE servers (
Server_name char(64) NOT NULL,
Host char(64) NOT NULL,
Db char(64) NOT NULL,
Username char(64) NOT NULL,
Password char(64) NOT NULL,
Port int(4) DEFAULT NULL,
Socket char(64) DEFAULT NULL,
Wrapper char(64) NOT NULL,
Owner char(64) NOT NULL,
PRIMARY KEY (Server_name)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table';
另外一种解决办法是:进入Mysql的bin目录运行 mysql -u root -p mysql
输入密码后运行
mysql> SOURCE ../share/mysql_fix_privilege_tables.sql
阿权的一个数据库有很多进程都是sleep的,这个是openads的网站,管理的是网页的广告,估计有200个,多的时候会更多些,我也在想这个情况到底是否正常呢?
mysql_pconnect()中的p,就是单词persistent(永久的)的首字母。要理解是否正常,那就得看看 mysql_pconnect 是如何工作的了,看看官方文档:
也就是说,会建立一个对数据库的连接,会先查找是否还有空闲的同样host、username、password的连接,没有就新建一个,否则就用这个空闲的连接。
这么理解应该挺好知道为什么会有一些进程是sleep的,就是说之前并发请求有100个,那就会有100个持续连接建立了,并且把连接保存在连接池中,如果连接有效时间过了,连接会自动完结了吧,这样可能就在访问压力低的时候sleep的进程变少了。
如果连接数可以足够,pconnect是不错的选择,mysql启动参数里面可以设定最大连接数的(参考《Mysql的启动参数 》http://www.aslibra.com/blog/read.php?1037),参考一下:
所以空闲进程多是不怕的,就担心影响别的应用,如果连接数足够,那还是用pconnect比connect方式要好
mysql_pconnect()中的p,就是单词persistent(永久的)的首字母。要理解是否正常,那就得看看 mysql_pconnect 是如何工作的了,看看官方文档:
引用
resource mysql_pconnect ([ string $server [, string $username [, string $password [, int $client_flags ]]]] )
Establishes a persistent connection to a MySQL server.
mysql_pconnect() acts very much like mysql_connect() with two major differences.
First, when connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.
Second, the connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use (mysql_close() will not close links established by mysql_pconnect()).
This type of link is therefore called 'persistent'.
Establishes a persistent connection to a MySQL server.
mysql_pconnect() acts very much like mysql_connect() with two major differences.
First, when connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.
Second, the connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use (mysql_close() will not close links established by mysql_pconnect()).
This type of link is therefore called 'persistent'.
也就是说,会建立一个对数据库的连接,会先查找是否还有空闲的同样host、username、password的连接,没有就新建一个,否则就用这个空闲的连接。
这么理解应该挺好知道为什么会有一些进程是sleep的,就是说之前并发请求有100个,那就会有100个持续连接建立了,并且把连接保存在连接池中,如果连接有效时间过了,连接会自动完结了吧,这样可能就在访问压力低的时候sleep的进程变少了。
如果连接数可以足够,pconnect是不错的选择,mysql启动参数里面可以设定最大连接数的(参考《Mysql的启动参数 》http://www.aslibra.com/blog/read.php?1037),参考一下:
max_connect_errors=100000
max_connections=1024
wait_timeout=600
max_connections=1024
wait_timeout=600
所以空闲进程多是不怕的,就担心影响别的应用,如果连接数足够,那还是用pconnect比connect方式要好
引用
pconnect的优点是速度,重用一个现有的连接几乎不花费时间。
缺点是效率。因为服务器(比如apache)可以使用任意一个进程迎接新的页面请求,
所以一段时间之后,可能每个进程都存了一个或几个连接,而且不同进程之间连接不能共享。
最坏的情况是其他进程保持着大量空闲连接,而某个进程却因为数据库连接数达到上限却无法取得连接
缺点是效率。因为服务器(比如apache)可以使用任意一个进程迎接新的页面请求,
所以一段时间之后,可能每个进程都存了一个或几个连接,而且不同进程之间连接不能共享。
最坏的情况是其他进程保持着大量空闲连接,而某个进程却因为数据库连接数达到上限却无法取得连接






