Andy's Blog » wordpress memcached, memcached wordpress, wordpress memcache, memcache wordpress, memcached wordpress 多个, clear memcached wordpress » WordPress + Memcached 终极加速

WordPress + Memcached 终极加速

更新:我发现给 WordPress 加上 Memcached 以后,速度并没有变快,反而是变慢了,但MySQL的查询倒是减少了。

开启 Memcached : 22 queries. 1.069 seconds.
不开启 Memcached : 55 queries. 0.510 seconds.

所以,还是慎用!
================================================
1. 你的服务器要支持memcached,至于怎么安装,有空我再写一篇
2. 下载以下这个 object-cache.php 放到 wp-content 目录
3. 在 wp-config.php 加入如下几行

global $memcached_servers;
$memcached_servers = array('default' => array('127.0.0.1:11211')); // 这里是你的 memcached 地址和端口
global $blog_id;
$blog_id = '21andy_blog'; // 这里是用于区分服务器上有多个 wordpress 而避免使用同一内存缓存

4. 装好后打开 wordpress 看一下,查询是不是少了很多?再看下wp-content/cache/ 目录,不会生成那些垃圾文件

以下是我修正的版本,在多个 wordpress 在同一服务器的时候,会发生张冠李戴的错误,以下已经解决这个问题

object-cache.php
<?php
 
/*
Name: Memcached
Description: Memcached backend for the WP Object Cache.
Version: 2.0
URI:
http://dev.wp-plugins.org/browser/memcached/
Author: Ryan Boren
 
Fixed by 21andy.com for multi-wordpress on same server.
Install this file to wp-content/object-cache.php
*/

 
function wp_cache_add($key, $data, $flag = '', $expire = 0) {
    
global $wp_object_cache;
 
    
return $wp_object_cache->add($key, $data, $flag, $expire);
}
 
function wp_cache_incr($key, $n = 1, $flag = '') {
    
global $wp_object_cache;
 
    
return $wp_object_cache->incr($key, $n, $flag);
}
 
function wp_cache_decr($key, $n = 1, $flag = '') {
    
global $wp_object_cache;
 
    
return $wp_object_cache->decr($key, $n, $flag);
}
 
function wp_cache_close() {
    
global $wp_object_cache;
 
    
return $wp_object_cache->close();
}
 
function wp_cache_delete($id, $flag = '') {
    
global $wp_object_cache;
 
    
return $wp_object_cache->delete($id, $flag);
}
 
function wp_cache_flush() {
    
global $wp_object_cache;
 
    
return $wp_object_cache->flush();
}
 
function wp_cache_get($id, $flag = '') {
    
global $wp_object_cache;
 
    
return $wp_object_cache->get($id, $flag);
}
 
function wp_cache_init() {
    
global $wp_object_cache;
 
    
$wp_object_cache = new WP_Object_Cache();
}
 
function wp_cache_replace($key, $data, $flag = '', $expire = 0) {
    
global $wp_object_cache;
 
    
return $wp_object_cache->replace($key, $data, $flag, $expire);
}
 
function wp_cache_set($key, $data, $flag = '', $expire = 0) {
    
global $wp_object_cache;
 
    
if ( defined('WP_INSTALLING') == false )
        
return $wp_object_cache->set($key, $data, $flag, $expire);
    
else
        
return true;
}
 
function wp_cache_add_global_groups( $groups ) {
    
global $wp_object_cache;
 
    
$wp_object_cache->add_global_groups($groups);
}
 
function wp_cache_add_non_persistent_groups( $groups ) {
    
global $wp_object_cache;
 
    
$wp_object_cache->add_non_persistent_groups($groups);
}
 
class WP_Object_Cache {
    
var $global_groups = array ('users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss');
 
    
var $no_mc_groups = array( 'comment', 'counts' );
 
    
var $autoload_groups = array ('options');
 
    
var $cache = array();
    
var $mc = array();
    
var $stats = array();
    
var $group_ops = array();
 
    
var $cache_enabled = true;
    
var $default_expiration = 0;
 
    
function add($id, $data, $group = 'default', $expire = 0) {
        
$key = $this->key($id, $group);
 
        
if ( in_array($group, $this->no_mc_groups) ) {
            
$this->cache[$key] = $data;
            
return true;
        
}
 
        
$mc =& $this->get_mc($group);
        
$expire = ($expire == 0) ? $this->default_expiration : $expire;
        
$result = $mc->add($key, $data, false, $expire);
        @ ++
$this->stats['add'];
        
$this->group_ops[$group][] = "add $id";
 
        
if ( false !== $result )
            
$this->cache[$key] = $data;
        
return $result;
    
}
 
    
function add_global_groups($groups) {
        
if ( ! is_array($groups) )
            
$groups = (array) $groups;
 
        
$this->global_groups = array_merge($this->global_groups, $groups);
        
$this->global_groups = array_unique($this->global_groups);
    
}
 
    
function add_non_persistent_groups($groups) {
        
if ( ! is_array($groups) )
            
$groups = (array) $groups;
 
        
$this->no_mc_groups = array_merge($this->no_mc_groups, $groups);
        
$this->no_mc_groups = array_unique($this->no_mc_groups);
    
}
 
    
function incr($id, $n, $group) {
        
$key = $this->key($id, $group);
        
$mc =& $this->get_mc($group);
 
        
return $mc->increment($key, $n);
    
}
 
    
function decr($id, $n, $group) {
        
$key = $this->key($id, $group);
        
$mc =& $this->get_mc($group);
 
        
return $mc->decrement($key, $n);
    
}
 
    
function close() {
 
        
foreach ( $this->mc as $bucket => $mc )
            
$mc->close();
    
}
 
    
function delete($id, $group = 'default') {
        
$key = $this->key($id, $group);
 
        
if ( in_array($group, $this->no_mc_groups) ) {
            
unset($this->cache[$key]);
            
return true;
        
}
 
        
$mc =& $this->get_mc($group);
 
        
$result = $mc->delete($key);
 
        @ ++
$this->stats['delete'];
        
$this->group_ops[$group][] = "delete $id";
 
        
if ( false !== $result )
            
unset($this->cache[$key]);
 
        
return $result;
    
}
 
    
function flush() {
        
return true;
    
}
 
    
function get($id, $group = 'default') {
        
$key = $this->key($id, $group);
        
$mc =& $this->get_mc($group);
 
        
if ( isset($this->cache[$key]) )
            
$value = $this->cache[$key];
        
else if ( in_array($group, $this->no_mc_groups) )
            
$value = false;
        
else
            
$value = $mc->get($key);
 
        @ ++
$this->stats['get'];
        
$this->group_ops[$group][] = "get $id";
 
        
if ( NULL === $value )
            
$value = false;
 
        
$this->cache[$key] = $value;
 
        
if ( 'checkthedatabaseplease' == $value )
            
$value = false;
 
        
return $value;
    
}
 
    
function get_multi( $groups ) {
    
/*
    format: $get['group-name'] = array( 'key1', 'key2' );
    */

    
$return = array();
        
foreach ( $groups as $group => $ids ) {
            
$mc =& $this->get_mc($group);
            
foreach ( $ids as $id ) {
                
$key = $this->key($id, $group);
                
if ( isset($this->cache[$key]) ) {
                    
$return[$key] = $this->cache[$key];
                    
continue;
                
} else if ( in_array($group, $this->no_mc_groups) ) {
                    
$return[$key] = false;
                    
continue;
                
} else {
                    
$return[$key] = $mc->get($key);
                
}
            
}
            
if ( $to_get ) {
                
$vals = $mc->get_multi( $to_get );
                
$return = array_merge( $return, $vals );
            
}
        
}
        @ ++
$this->stats['get_multi'];
        
$this->group_ops[$group][] = "get_multi $id";
        
$this->cache = array_merge( $this->cache, $return );
        
return $return;
    
}
 
    
function key($key, $group) {
        
global $blog_id;
 
        
if ( empty($group) )
            
$group = 'default';
 
        
if (false !== array_search($group, $this->global_groups))
            
$prefix = $blog_id; // fixed for multi-wordpress on same server
        
else
            
$prefix = $blog_id . ':';
 
        
return preg_replace('/\s+/', '', "$prefix$group:$key");
    
}
 
    
function replace($id, $data, $group = 'default', $expire = 0) {
        
$key = $this->key($id, $group);
        
$expire = ($expire == 0) ? $this->default_expiration : $expire;
        
$mc =& $this->get_mc($group);
        
$result = $mc->replace($key, $data, false, $expire);
        
if ( false !== $result )
            
$this->cache[$key] = $data;
        
return $result;
    
}
 
    
function set($id, $data, $group = 'default', $expire = 0) {
        
$key = $this->key($id, $group);
        
if ( isset($this->cache[$key]) && ('checkthedatabaseplease' == $this->cache[$key]) )
            
return false;
        
$this->cache[$key] = $data;
 
        
if ( in_array($group, $this->no_mc_groups) )
            
return true;
 
        
$expire = ($expire == 0) ? $this->default_expiration : $expire;
        
$mc =& $this->get_mc($group);
        
$result = $mc->set($key, $data, false, $expire);
 
        
return $result;
    
}
 
    
function colorize_debug_line($line) {
        
$colors = array(
            
'get' => 'green',
            
'set' => 'purple',
            
'add' => 'blue',
            
'delete' => 'red');
 
        
$cmd = substr($line, 0, strpos($line, ' '));
 
        
$cmd2 = "<span style='color:{$colors[$cmd]}'>$cmd</span>";
 
        
return $cmd2 . substr($line, strlen($cmd)) . "\n";
    
}
 
    
function stats() {
        
echo "<p>\n";
        
foreach ( $this->stats as $stat => $n ) {
            
echo "<strong>$stat</strong> $n";
            
echo "<br/>\n";
        
}
        
echo "</p>\n";
        
echo "<h3>Memcached:</h3>";
        
foreach ( $this->group_ops as $group => $ops ) {
            
if ( !isset($_GET['debug_queries']) && 500 < count($ops) ) {
                
$ops = array_slice( $ops, 0, 500 );
                
echo "<big>Too many to show! <a href='" . add_query_arg( 'debug_queries', 'true' ) . "'>Show them anyway</a>.</big>\n";
            
}
            
echo "<h4>$group commands</h4>";
            
echo "<pre>\n";
            
$lines = array();
            
foreach ( $ops as $op ) {
                
$lines[] = $this->colorize_debug_line($op);
            
}
            
print_r($lines);
            
echo "</pre>\n";
        
}
 
        
if ( $this->debug )
            
var_dump($this->memcache_debug);
    
}
 
    
function &get_mc($group) {
        
if ( isset($this->mc[$group]) )
            
return $this->mc[$group];
        
return $this->mc['default'];
    
}
 
    
function failure_callback($host, $port) {
        
//error_log("Connection failure for $host:$port\n", 3, '/tmp/memcached.txt');
    
}
 
    
function WP_Object_Cache() {
        
global $memcached_servers;
 
        
if ( isset($memcached_servers) )
            
$buckets = $memcached_servers;
        
else
            
$buckets = array('default' => array('127.0.0.1:11211'));
 
        
foreach ( $buckets as $bucket => $servers) {
            
$this->mc[$bucket] = new Memcache();
            
foreach ( $servers as $server  ) {
                
list ( $node, $port ) = explode(':', $server);
                
$this->mc[$bucket]->addServer($node, $port, true, 1, 1, 15, true, array($this, 'failure_callback'));
                
$this->mc[$bucket]->setCompressThreshold(20000, 0.2);
            
}
        
}
    
}
}
?>

Incoming search terms:

Tags: wordpress, 优化, memcached, 加速

本文地址: http://blog.21andy.com/20100206/1642.html

9 评论 to “PHP开源CMS之MODx”

  1. yunshan 于 2010-02-15 18:09:03 发表:

    同感啊,我用了memcached,也是查询次数减少了,但执行时间变长了

  2. charlies 于 2010-04-24 22:04:35 发表:

    不好意思,请教一下。2个 wp安装了你的修改版本后。第二个就无法打开,首页空白。

  3. charlies 于 2010-04-24 22:10:31 发表:

    搞好了。原来是忘记修改config文件。非常感谢提供修改版本

  4. WooDragon 于 2011-02-05 23:16:52 发表:

    貌似是DB cache插件的缘故,我关掉这个插件以后速度唰唰的= =

    ftium4 于 2011-08-12 15:11:37 回复:

    关掉DB cache后速度变得如何了?

  5. Robin 于 2012-06-23 15:57:36 发表:

    您好,我尝试着用你的方法来给我的 WordPress 博客加速,请问你在安装成功后如何测试?比如你在文中提到的查询速度和次数的数据时怎么得到的?用的什么测试工具?您在文中提到的数据如下:开启 Memcached : 22 queries. 1.069 seconds.
    不开启 Memcached : 55 queries. 0.510 seconds.

  6. 侯永禄 于 2012-08-19 13:17:16 发表:

    对于使用ajax加载内容的主题,该插件有用吗?

  7. tb11.com 于 2012-10-13 09:51:03 发表:

    object-cache.php官方更新到2.0.2了,仍然没解决窜站问题,求更新

  8. wifay 于 2013-01-16 15:22:11 发表:

    囧,我也有这样的困惑。因为 SQL 本身的缓存的存在吧?memcached 使用进程间通信更费事,如果 SQL 服务器没超载的前提下,使用 memcached 性能提升真不明显。