上一篇 下一篇 分享链接 返回 返回顶部

WordPress使用 Memcached提高网站速度

发布人:admin 发布时间:2025-12-19 11:09 阅读量:34
Memcached 使用说明

Memcached 使用说明

什么是 Memcached?

Memcached 是一个高性能的分布式内存对象缓存系统,用于加速动态 Web 应用程序,通过缓存数据和对象以减少数据库负载。它在 Web 开发中被广泛使用,尤其是在需要快速访问数据的情况下。

Memcached 的作用

  • 提高性能:通过将经常查询的数据存储在内存中,Memcached 减少了数据库的负担,显著提高响应速度。
  • 减少数据库访问:能够存储数据库查询的结果或 API 调用的返回数据,特别适用于高流量环境。
  • 提升用户体验:更快速的页面加载时间直接提高用户体验。
  • 支持高并发:允许多个用户同时请求数据,并能高效管理这些请求。
  • 数据缓存:可用于缓存用户会话信息、API 响应和查询结果等。

Memcached 安装和配置

以下是利用宝塔面板安装和配置 Memcached 的步骤(也适用于直接在 Linux 服务器上安装):

  1. 安装 Memcached 及其扩展:

    打开宝塔软件商店,找到 php74(根据你的版本选择 PHP),安装 opcache 和 Memcached 扩展。

  2. 防火墙配置:

    确保防火墙放行 Memcached 默认端口 11211,如有需要可以更改此端口。

  3. 性能调整:

    如果内存不够,可以在 Memcached 设置中调整连接数和缓存大小。

  4. 创建配置文件:

    在 WordPress 的 /wp-content 目录下创建 object-cache.php 文件,并添加以下代码:

    <?php
    if(
    	// (isset($_POST['action']) && $_POST['action'] == 'query-attachments') ||
    	(isset($_GET['debug']) && $_GET['debug'] == 'sql')
    ){
    	return;
    }
    
    if(!defined('WP_CACHE_KEY_SALT')){
    	define('WP_CACHE_KEY_SALT', '');
    }
    
    if(class_exists('Memcached')){
    	function wp_cache_add($key, $data, $group='', $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->add($key, $data, $group, (int)$expire);
    	}
    
    	function wp_cache_cas($cas_token, $key, $data, $group='', $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->cas($cas_token, $key, $data, $group, (int)$expire);
    	}
    
    	function wp_cache_close(){
    		global $wp_object_cache;
    		return $wp_object_cache->close();
    	}
    
    	function wp_cache_decr($key, $offset=1, $group='', $initial_value=0, $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->decr($key, $offset, $group, $initial_value, $expire);
    	}
    
    	function wp_cache_delete($key, $group=''){
    		global $wp_object_cache;
    		return $wp_object_cache->delete($key, $group);
    	}
    
    	function wp_cache_flush(){
    		global $wp_object_cache;
    		return $wp_object_cache->flush();
    	}
    
    	function wp_cache_get($key, $group='', $force=false, &$found=null){
    		global $wp_object_cache;
    		return $wp_object_cache->get($key, $group, $force, $found);
    	}
    
    	function wp_cache_get_multiple($keys, $group='', $force=false){
    		global $wp_object_cache;
    		return $wp_object_cache->get_multiple($keys, $group, $force);
    	}
    
    	function wp_cache_set_multiple($data, $group='', $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->set_multiple($data, $group, $expire);
    	}
    
    	function wp_cache_delete_multiple($keys, $group=''){
    		global $wp_object_cache;
    		return $wp_object_cache->delete_multiple($keys, $group);
    	}
    
    	function wp_cache_get_with_cas($key, $group='', &$token=null){
    		global $wp_object_cache;
    
    		$result	= $wp_object_cache->get_with_cas($key, $group);
    
    		if(is_array($result)){
    			$token	= $result['cas'];
    			$result	= $result['value'];
    		}
    
    		return $result;
    	}
    
    	function wp_cache_incr($key, $offset=1, $group='', $initial_value=0, $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->incr($key, $offset, $group, $initial_value, $expire);
    	}
    
    	if(!isset($_GET['debug']) || $_GET['debug'] != 'sql'){
    		function wp_cache_init(){
    			global $wp_object_cache;
    			$wp_object_cache	= new WP_Object_Cache();
    		}
    	}
    
    	function wp_cache_replace($key, $data, $group='', $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->replace($key, $data, $group, (int)$expire);
    	}
    
    	function wp_cache_set($key, $data, $group='', $expire=0){
    		global $wp_object_cache;
    		return $wp_object_cache->set($key, $data, $group, (int)$expire);
    	}
    
    	function wp_cache_switch_to_blog($blog_id){
    		global $wp_object_cache;
    		return $wp_object_cache->switch_to_blog($blog_id);
    	}
    
    	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);
    	}
    
    	function wp_cache_get_stats(){
    		global $wp_object_cache;
    		return $wp_object_cache->get_stats();
    	}
    
    	class WP_Object_Cache{
    		private $cache 	= [];
    		private $mc		= null;
    
    		private $blog_prefix;
    		private $global_prefix;
    
    		protected $global_groups	= [];
    		protected $non_persistent_groups	= [];
    
    		protected function action($action, $id, $group, $data, $expire=0){
    			if($this->is_non_persistent_group($group)){
    				$internal	= $this->internal('get', $id, $group);
    
    				if($action == 'add'){
    					if($internal !== false){
    						return false;
    					}
    				}elseif($action == 'replace'){
    					if($internal === false){
    						return false;
    					}
    				}elseif($action == 'increment' || $action == 'decrement'){
    					$data	= $action == 'increment' ? $data : (0-$data);
    					$data	= (int)$internal+$data;
    					$data	= $data < 0 ? 0 : $data;
    				}
    
    				return $this->internal('add', $id, $group, $data);
    			}else{
    				$key	= $this->build_key($id, $group);
    				$expire	= (!$expire && strlen($id) > 50) ? DAY_IN_SECONDS : $expire;
    
    				if($action == 'set'){
    					$result	= $this->mc->set($key, $data, $expire);
    				}elseif($action == 'add'){
    					$result	= $this->mc->add($key, $data, $expire);
    				}elseif($action == 'replace'){
    					$result	= $this->mc->replace($key, $data, $expire);
    				}elseif($action == 'increment'){
    					$result	= $data = $this->mc->increment($key, $data);
    				}elseif($action == 'decrement'){
    					$result	= $data = $this->mc->decrement($key, $data);
    				}
    
    				$code	= $this->mc->getResultCode();
    
    				if($code === Memcached::RES_SUCCESS){
    					$this->internal('add', $id, $group, $data);
    				}else{
    					$this->internal('del', $id, $group);
    
    					if($code != Memcached::RES_NOTSTORED){
    						// trigger_error($code.' '.var_export($result, true).' '.var_export($key, true));
    					}
    				}
    
    				return $result;
    			}
    		}
    
    		protected function internal($action, $id, $group, $data=null){
    			$group	= $this->parse_group($group);
    
    			if($action == 'get'){
    				$data	= $this->cache[$group][$id] ?? false;
    
    				return is_object($data) ? clone $data : $data;
    			}elseif($action == 'add'){
    				$this->cache[$group][$id]	= is_object($data) ? clone $data : $data;
    
    				return true;
    			}elseif($action == 'del'){
    				unset($this->cache[$group][$id]);
    			}
    		}
    
    		public function add($id, $data, $group='default', $expire=0){
    			if(wp_suspend_cache_addition()){
    				return false;
    			}
    
    			return $this->action('add', $id, $group, $data, $expire);
    		}
    
    		public function replace($id, $data, $group='default', $expire=0){
    			return $this->action('replace', $id, $group, $data, $expire);
    		}
    
    		public function set($id, $data, $group='default', $expire=0){
    			return $this->action('set', $id, $group, $data, $expire);
    		}
    
    		public function incr($id, $offset=1, $group='default', $initial_value=0, $expire=0){
    			$this->action('add', $id, $group, $initial_value, $expire);
    			return $this->action('increment', $id, $group, $offset);
    		}
    
    		public function decr($id, $offset=1, $group='default', $initial_value=0, $expire=0){
    			$this->action('add', $id, $group, $initial_value, $expire);
    			return $this->action('decrement', $id, $group, $offset);
    		}
    
    		public function cas($cas_token, $id, $data, $group='default', $expire=0){
    			$this->internal('del', $id, $group);
    
    			return $this->mc->cas($cas_token, $this->build_key($id, $group), $data, $expire);
    		}
    
    		public function delete($id, $group='default'){
    			$this->internal('del', $id, $group);
    
    			return $this->is_non_persistent_group($group) ? true : $this->mc->delete($this->build_key($id, $group));
    		}
    
    		public function flush(){
    			$this->cache	= [];
    
    			return $this->mc->flush();
    		}
    
    		public function get($id, $group='default', $force=false, &$found=null){
    			$value	= $force ? false : $this->internal('get', $id, $group);
    			$found	= $value !== false;
    
    			if(!$found && !$this->is_non_persistent_group($group)){
    				$value	= $this->mc->get($this->build_key($id, $group));
    				$code	= $this->mc->getResultCode();
    				$found	= $code !== Memcached::RES_NOTFOUND;
    
    				if($found){
    					if($code !== Memcached::RES_SUCCESS){
    						trigger_error($code.' '.var_export([$id, $group, $value], true));
    					}
    
    					$this->internal('add', $id, $group, $value);
    				}
    			}
    
    			return $value;
    		}
    
    		public function get_with_cas($id, $group='default'){
    			$key	= $this->build_key($id, $group);
    
    			if(defined('Memcached::GET_EXTENDED')){
    				$result	= $this->mc->get($key, null, Memcached::GET_EXTENDED);
    			}else{
    				$value	= $this->mc->get($key, null, $cas);
    				$result	= ['value'=>$value, 'cas'=>$cas];
    			}
    
    			return $this->mc->getResultCode() === Memcached::RES_NOTFOUND ? false : $result;
    		}
    
    		public function get_multiple($ids, $group='default', $force=false){
    			$caches	= [];
    			$keys	= [];
    
    			$non_persistent	= $this->is_non_persistent_group($group);
    
    			if($non_persistent || !$force){
    				foreach($ids as $id){
    					$caches[$id]	= $this->internal('get', $id, $group);
    					$keys[$id]		= $this->build_key($id, $group);
    
    					if(!$non_persistent && $caches[$id] === false){
    						$force	= true;
    					}
    				}
    
    				if($non_persistent || !$force){
    					return $caches;
    				}
    			}
    
    			$results	= $this->mc->getMulti(array_values($keys)) ?: [];
    
    			foreach($keys as $id => $key){
    				$caches[$id]	= $results[$key] ?? false;
    
    				$this->internal('add', $id, $group, $caches[$id]);
    			}
    
    			return $caches;
    		}
    
    		public function set_multiple($data, $group='default', $expire=0){
    			$items	= [];
    
    			foreach($data as $id => $value){
    				$this->internal('add', $id, $group, $value);
    
    				$key = $this->build_key($id, $group);
    
    				$items[$key]	= $value;
    			}
    
    			if($this->is_non_persistent_group($group)){
    				$result	= true;
    			}else{
    				$result	= $this->mc->setMulti($items, $expire);
    				$code	= $this->mc->getResultCode();
    
    				if($code !== Memcached::RES_SUCCESS){
    					if($code != Memcached::RES_NOTSTORED){
    						// trigger_error($code.' '.var_export($result,true));
    					}
    
    					foreach($data as $id => $value){
    						$this->internal('del', $id, $group);
    					}
    
    					return $result;
    				}
    			}
    
    			return $result;
    		}
    
    		public function delete_multiple($ids, $group='default'){
    			foreach($ids as $id){
    				$this->internal('del', $id, $group);
    
    				$keys[]	= $this->build_key($id, $group);
    			}
    
    			return (empty($keys) || $this->is_non_persistent_group($group)) ? true : $this->mc->deleteMulti($keys);
    		}
    
    		public function add_global_groups($groups){
    			$this->global_groups	= array_merge($this->global_groups, array_fill_keys((array)$groups, true));
    		}
    
    		public function add_non_persistent_groups($groups){
    			$this->non_persistent_groups	= array_merge($this->non_persistent_groups, array_fill_keys((array)$groups, true));
    		}
    
    		public function switch_to_blog($blog_id){
    			if(is_multisite()){
    				$this->blog_prefix	= ((int)$blog_id).':';
    			}
    		}
    
    		private function is_non_persistent_group($group){
    			return $group ? isset($this->non_persistent_groups[$group]) : false;
    		}
    
    		private function parse_group($group){
    			$group	= $group ?: 'default';
    			$prefix	= isset($this->global_groups[$group]) ? $this->global_prefix : $this->blog_prefix;
    
    			return WP_CACHE_KEY_SALT.$prefix.$group;
    		}
    
    		public function build_key($id, $group='default'){
    			return preg_replace('/\s+/', '', $this->parse_group($group).':'.$id);
    		}
    
    		public function get_stats(){
    			return $this->mc->getStats();
    		}
    
    		public function get_mc(){
    			return $this->mc;
    		}
    
    		public function failure_callback($host, $port){}
    
    		public function close(){
    			$this->mc->quit();
    		}
    
    		public function __construct(){
    			$this->mc	= new Memcached();
    			// $this->mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);	// 用于启用与 libketama 一致性哈希算法兼容的服务器分布策略
    
    			if(!$this->mc->getServerList()){
    				global $memcached_servers;
    
    				if(isset($memcached_servers)){
    					foreach($memcached_servers as $memcached){
    						$this->mc->addServer(...$memcached);
    					}
    				}else{
    					$this->mc->addServer('127.0.0.1', 11211);
    				}
    			}
    
    			if(is_multisite()){
    				$this->blog_prefix		= get_current_blog_id().':';
    				$this->global_prefix	= '';
    			}else{
    				$this->blog_prefix		= $GLOBALS['table_prefix'].':';
    				$this->global_prefix	= defined('CUSTOM_USER_TABLE') ? '' : $this->blog_prefix;
    			}
    		}
    	}
    }
    
  5. 修改 wp-config.php:

    在 WordPress 根目录的 wp-config.php 文件中插入以下代码以启用 Memcached:

    // 使用 Memcached 作为缓存存储
    $config['cache'] = array(
        'backend' => 'memcached',
        'servers' => array(
            array('host' => '127.0.0.1', 'port' => 11211)
        )
    );
  6. 检测 Memcached 是否生效:

    可以通过 Chrome 开发者工具(F12)查看请求响应时间,并与未开启 Memcached 之前的速度进行对比,来验证缓存是否生效。

注意:在进行添加或修改操作之前,请确保备份您的数据,以防万一出现问题。

目录结构
全文
QQ交流二群 QQ交流二群
联系客服 联系客服
电子邮箱: admin@ankuyun.com
关于Centos官网停止维护导致源失效解决方案

重大通知!用户您好,以下内容请务必知晓!


由于CentOS官方已全面停止维护CentOS Linux项目,公告指出 CentOS 7和8在2024年6月30日停止技术服务支持,详情见CentOS官方公告。
导致CentOS系统源已全面失效,比如安装宝塔等等会出现网络不可达等报错,解决方案是更换系统源。输入以下命令:


bash <(curl -sSL https://linuxmirrors.cn/main.sh)

然后选择中国科技大学或者清华大学,一直按回车不要选Y。源更换完成后,即可正常安装软件。


如需了解更多信息,请访问: 查看CentOS官方公告  

新域名:ankuyun.com

旧域名将保留一年,请及时更换


查看详情 关闭
网站通知