Discuz! Next Memcache cache implementation method

  • 2020-03-31 20:48:55
  • OfStack

preface :
In the PHP+MySQL architecture of the site, the focus of this article from the perspective of MySQL to analyze how to Discuz! Forums (or similar programs with the PHP+MySQL architecture) handle a lot of traffic. Some Suggestions for using Memcache to relieve MySQL stress are also given. Many of these data are the results of personal tests. If you have any different opinions, please let us know in the comments. In addition, due to the problem of personal thinking, the text is relatively jump, hereby declare!

System analysis :
From the point of view of MySQL alone, it should not be too difficult to load a single MySQL database to hundreds of millions of operations per day (about 1,100 MySQL operations per second, then multiplied by 86400). According to this data, it is not a problem for a single MySQL server forum to reach 20 million PV. I believe that most of the domestic forums cannot achieve 20 million PV per day, but the actual situation is not the case. When the forum PV exceeded millions, a WEB was already overwhelmed.

According to some of the data I have, the current Discuz! The basic server architecture of the forum is Squid in the front and DB in the back. In this architecture, the increase of web server pressure can be solved by increasing the server in parallel, while the pressure of MySQL is nowhere to be released. Without considering the official services of MySQL, we can reduce the load of MySQL server by making proper use of Memcache.

Some friends may say that we can handle the sub-table of the data table (note: the sub-table here refers to the sub-table of the PHP program, such as pw, dv), but the current situation is that a DB server has been unable to support the current data processing, the sub-table of MySQL through PHP still can not reduce the load of MySQL. (note: this paragraph is for established systems, if it is independently developed, it is good to synchronize the data partition at the early stage of the architecture.)

You might have a friend who says use the master-slave architecture of MySQL, and if you bring that up, I'm going to make it very clear to you, go back to the manual. In Mysql Master/Slave mode, slaves are mainly used to backup data. Only when the Master fails, slaves will take over the Master's service and process external requests until the Master returns to normal. That is to say: In the case of Master/Slave, either the Master is in the service or the Slave is in the service, and the Master/Slave is not in the service at the same time. Using MySQL master slave still does not effectively reduce the load on MySQL.

Maybe you will ask me why I don't use MySQL Cluster, which is a waste of money, the same amount of money to pay, the biggest benefit is king. PS: as an aside, the MySQL manual interprets MySQL clusters as MySQL clusters, which I'm not used to.

In fact, MySQL partitions in MySQL5.1 are a nice thing, allowing you to allocate multiple parts of a single table across file systems based on rules that can be set to any size. In fact, different parts of the table are stored as separate tables in different locations. I think this is the most active and effective way to reduce MySQL load in the current situation One of the solutions . Unfortunately, I don't have any personal experience with this MySQL partitioning approach, nor do I have a strong case that it is stable or unstable. So I'm still on the prowl. If you know, please tell me! Some friends said that tencent is using MySQL partition, but unfortunately I did not get the exact data.

Well, after analyzing and summarizing so many ways to reduce the load on MySQL, I came to the conclusion that under certain conditions such as user environment requirements, I could relieve Discuz in the current situation! A more efficient way to load MySQL on the forum is to use Memcache!

Discuz! Using Memcache
1. Added in config. Inc. PHP

$memcachehost = '127.0.0.1;
$memcacheport = 11211;
$memcachelife = 60;

2. In include/common. Inc., in PHP

$mem = new Memcache;
$mem - > The connect ($memcachehost, $memcacheport);

3. Modify the two methods of fetch_array and query in include/db_mysql.class.php, and add the query_mysql method, the code is as follows:

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 - > SQL, the query ($$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 - > The 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. Will need to use Memcache cache of SQL queries by the code

$db - > The query (

Modified to

$db - > Query_memcache (

Note and will

While ($post = $db - > Fetch_array ($query)) {

Modified to

The foreach ($query as $post) {

No while $db-> Fetch_array can be unmodified.

Take the following code if you need it:

Preg_replace ("/while \ [$] +) (\ w \ \ s * = \ s * [$] db - > Fetch_array \ [$] query \ \)/is ", "foreach (\ $query as $\ \ \ 1)", $file);

Related articles: