Objective:
In the Php+mysql architecture site, this article focuses on how to make the discuz! forum (or similar Php+mysql architecture program) respond to large visits from a MySQL perspective. At the same time, some suggestions for using memcache to reduce the MySQL pressure are given. Many of these data are personal test results, if there are different views, please leave a message.
System Analysis:
Simply from the MySQL point of view, a single MySQL database load to hundreds of millions of operations per day (approximately 1100 times a second MySQL operation, and then multiplied by 86400) should not be very difficult things. According to this data that is a single MySQL server forum can run to 20 million PV is not a problem, I believe that most of the forum is not possible to do 20 million PV per day, but the actual situation is not so. When the forum PV more than million time a web is already overwhelmed.
Some of the data I have in hand shows that the current discuz! forum's basic server architecture is in front of squid top, behind is a db in support. In this architecture, the Web server pressure increase can be increased by parallel server solution, while the MySQL pressure is nowhere to release, without considering the official MySQL service, we can use memcache to reduce the MySQL server load.
There may be friends who say we can table tables (note: This refers to the table through the PHP program to the table, such as PW,DV of the table) processing, but the current situation is a DB server can not support the current data processing, The MySQL-made table through PHP still does not reduce the load on MySQL. (Note: This paragraph of the text for the system has been formed, if it is an independent development of the system in the early stage of the structure of the data synchronized partition is good.) )
There may be friends who will say that using MySQL's master and slave architecture, if you raise this question, I will tell you clearly, go back to see the handbook. In the MySQL master/slave mode, Slave primarily to back up the data, only when Master fails, Slave takes master's service and processes the external request until master returns to normal. That is to say: In the Master/slave, either master in service, or slave in service, will not master/slave provide services at the same time. Using MySQL master and subordinate still can not effectively reduce the MySQL load.
Perhaps you will ask me why not use MySQL cluster (MySQL Cluster), that is white silver, ah, the same money to pay, get the biggest benefit is kingly. PS: To say a digression, MySQL manual in the MySQL cluster is interpreted as a MySQL cluster, not accustomed to.
In fact, the MySQL partition (MySQL Partition) in MySQL5.1 is a good thing, allowing multiple portions of a single table to be allocated across the file system based on rules that can be set to any size. In fact, different parts of the table are stored as separate tables in different places. I think this is one of the most active and effective ways to reduce MySQL load in the current situation. But unfortunately, this MySQL partitioning way I personally did not use the experience, there is not quite a sufficient case to show that it is stable or unstable. So I'm still wandering around. If you know, please tell me! A friend said Tencent is using MySQL partition, but unfortunately I did not get the exact data.
Okay, all right. After analyzing and summarizing so many ways of reducing MySQL load, I conclude that under the current situation, it is more effective to ease the MySQL load of discuz! forum by using memcache!
Reasons to use Memcache:
1.Web Server (LIGHTTPD, Nginx is said to be more efficient than Apache, you can try) on the CPU requirements high, low memory requirements, and memcached Server is low CPU requirements, high memory requirements, so you can use. It is possible to install Memcached server on the front-end Web server.
2. Money, money, money, the least pay, get the most benefits.
3. Simple and simple, for a system with reasonable architecture, adding memcache support may only be a process of handling files in batches
discuz! Use Memcache
1. Increase in the number of config.inc.php
PHP code
$memcachehost = ' 127.0.0.1 ';
$memcacheport = 11211;
$memcachelife = 60;
2. In the include/common.inc.php
PHP code
$mem = new Memcache;
$mem->connect ($memcachehost, $memcacheport);
3. Modify the Fetch_array and query methods in include/db_mysql.class.php and add the Query_mysql method, the following code:
PHP code
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. The code for the SQL query that will need to use the Memcache cache is
PHP code
$db->query (
Amended to
PHP code
$db->query_memcache (
Note and put
PHP code
while ($post = $db->fetch_array ($query)) {
Amended to
PHP code
foreach ($query as $post) {
$db->fetch_array without a while can be modified without modification.
The following code is useful to take it:
PHP code
Preg_replace ("/while\" ([$] (\w+) \s*\=\s*[$]db->fetch_array\ ([$]query\) \)/is ", foreach (\ $query as \$\\1)", $file) ;
Turn off a small tool to replace the batch.
You can replace this in EditPlus: While\ ([$] (. *) = [$]db->fetch_array\ ([$]query\) \) replaced by foreach ($query as $\1)
5. Finished, test it!