什么是pom? pom作为项目对象模型。通过xml表示maven项目,使用pom.xml来实现。主要描述了项目:包括配置文件;开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的url,项目的依赖性,以及其他所有的项目相关因素。 快速察看: xml 代码 <project> <modelVersion>4.0.0</modelVersion> <groupId>...</groupId> <artifactId>...</artifactId>…
December 12, 2018
在PHP中使用memcached提高动态网站性能, memcached, memcache, memcached数据库缓存类
确认是否已经安装memcached:Verify Installation
php -m | grep memcached
视频:
memcached 函数
看官网:http://php.net/manual/zh/book.memcached.php
Memcached — Memcached类
- Memcached::add — 向一个新的key下面增加一个元素
- Memcached::addByKey — 在指定服务器上的一个新的key下增加一个元素
- Memcached::addServer — 向服务器池中增加一个服务器
- Memcached::addServers — 向服务器池中增加多台服务器
- Memcached::append — 向已存在元素后追加数据
- Memcached::appendByKey — 向指定服务器上已存在元素后追加数据
- Memcached::cas — 比较并交换值
- Memcached::casByKey — 在指定服务器上比较并交换值
- Memcached::__construct — 创建一个Memcached实例
- Memcached::decrement — 减小数值元素的值
- Memcached::decrementByKey — Decrement numeric item’s value, stored on a specific server
- Memcached::delete — 删除一个元素
- Memcached::deleteByKey — 从指定的服务器删除一个元素
- Memcached::deleteMulti — Delete multiple items
- Memcached::deleteMultiByKey — Delete multiple items from a specific server
- Memcached::fetch — 抓取下一个结果
- Memcached::fetchAll — 抓取所有剩余的结果
- Memcached::flush — 作废缓存中的所有元素
- Memcached::get — 检索一个元素
- Memcached::getAllKeys — Gets the keys stored on all the servers
- Memcached::getByKey — 从特定的服务器检索元素
- Memcached::getDelayed — 请求多个元素
- Memcached::getDelayedByKey — 从指定的服务器上请求多个元素
- Memcached::getMulti — 检索多个元素
- Memcached::getMultiByKey — 从特定服务器检索多个元素
- Memcached::getOption — 获取Memcached的选项值
- Memcached::getResultCode — 返回最后一次操作的结果代码
- Memcached::getResultMessage — 返回最后一次操作的结果描述消息
- Memcached::getServerByKey — 获取一个key所映射的服务器信息
- Memcached::getServerList — 获取服务器池中的服务器列表
- Memcached::getStats — 获取服务器池的统计信息
- Memcached::getVersion — 获取服务器池中所有服务器的版本信息
- Memcached::increment — 增加数值元素的值
- Memcached::incrementByKey — Increment numeric item’s value, stored on a specific server
- Memcached::isPersistent — Check if a persitent connection to memcache is being used
- Memcached::isPristine — Check if the instance was recently created
- Memcached::prepend — 向一个已存在的元素前面追加数据
- Memcached::prependByKey — Prepend data to an existing item on a specific server
- Memcached::quit — 关闭所有打开的链接。
- Memcached::replace — 替换已存在key下的元素
- Memcached::replaceByKey — Replace the item under an existing key on a specific server
- Memcached::resetServerList — Clears all servers from the server list
- Memcached::set — 存储一个元素
- Memcached::setByKey — Store an item on a specific server
- Memcached::setMulti — 存储多个元素
- Memcached::setMultiByKey — Store multiple items on a specific server
- Memcached::setOption — 设置一个memcached选项
- Memcached::setOptions — Set Memcached options
- Memcached::setSaslAuthData — Set the credentials to use for authentication
- Memcached::touch — Set a new expiration on an item
- Memcached::touchByKey — Set a new expiration on an item on a specific server
memcached 自定义类 (兼容 memcache 和 memcached)
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); class Mmemcached { private $m; private $client_type; private $skip_prefix = false; private $prefix = MEMCACHE_PREFIX; protected $errors = []; public function __construct($params = array()) { $this->prefix = $params['prefix'] ?? MEMCACHE_PREFIX; $this->client_type = trim(ucfirst($params['engine'] ?? ($params['client_type'] ?? MEMCACHE_ENGINE))); $servers = $params['servers'] ?? ($params['server'] ?? array(MEMCACHE_HOST, MEMCACHE_PORT, MEMCACHE_WEIGHT)); if ($this->client_type) { // Which one should be loaded switch ($this->client_type) { case 'Memcached': $this->m = new Memcached(); break; case 'Memcache': $this->m = new Memcache(); // Set Automatic Compression Settings $auto_compress_tresh = $params['auto_compress_tresh'] ?? ($params['compress_tresh'] ?? MEMCACHE_COMPRESSION); $auto_compress_savings = $params['auto_compress_savings'] ?? ($params['compress_savings'] ?? MEMCACHE_COMPRESS_SAVINGS); if ($auto_compress_tresh) $this->setcompressthreshold($auto_compress_tresh, $auto_compress_savings); break; } $this->auto_connect($servers); } return $this; } /* +-------------------------------------+ Name: auto_connect Purpose: runs through all of the servers defined in the configuration and attempts to connect to each @param return : none +-------------------------------------+ */ private function auto_connect($servers = array()) { if($servers) foreach ($servers as $key => $server) $this->add_server($server); } /* +-------------------------------------+ Name: add_server Purpose: @param return : TRUE or FALSE +-------------------------------------+ */ public function add_server($server = array()) { $host = $server['host'] ?? MEMCACHE_HOST; $port = $server['port'] ?? MEMCACHE_PORT; $weight = $server['weight'] ?? MEMCACHE_WEIGHT; return $this->m->addServer($host, $port, $weight); } /* +-------------------------------------+ Name: add Purpose: add an item to the memcache server(s) @param return : TRUE or FALSE +-------------------------------------+ */ public function add($key = null, $value = null, $expiration = null) { if (is_null($expiration)) $expiration = MEMCACHE_EXPIRATION; if (is_array($key)) { foreach ($key as $multi) { if (!isset($multi['expiration']) || $multi['expiration'] == '') $multi['expiration'] = MEMCACHE_EXPIRATION; $this->add($this->key_name($multi['key']), $multi['value'], $multi['expiration']); } } else { switch ($this->client_type) { case 'Memcache': $add_status = $this->m->add($this->key_name($key), $value, MEMCACHE_COMPRESSION, $expiration); break; default: case 'Memcached': $add_status = $this->m->add($this->key_name($key), $value, $expiration); break; } return $add_status; } } /* +-------------------------------------+ Name: set Purpose: similar to the add() method but uses set @param return : TRUE or FALSE +-------------------------------------+ */ public function set($key = null, $value = null, $expiration = null) { if (is_null($expiration)) $expiration = MEMCACHE_EXPIRATION; if (is_array($key)) { foreach ($key as $multi) { if (!isset($multi['expiration']) || $multi['expiration'] == '') $multi['expiration'] = MEMCACHE_EXPIRATION; $this->set($this->key_name($multi['key']), $multi['value'], $multi['expiration']); } } else { switch ($this->client_type) { case 'Memcache': $add_status = $this->m->set($this->key_name($key), $value, MEMCACHE_COMPRESSION, $expiration); break; default: case 'Memcached': $add_status = $this->m->set($this->key_name($key), $value, $expiration); break; } return $add_status; } } /* +-------------------------------------+ Name: get Purpose: gets the data for a single key or an array of keys @param return : array of data or multi-dimensional array of data +-------------------------------------+ */ public function get($key = null) { $output = false; if ($this->m) { if (is_null($key)) $this->errors[] = 'The key value cannot be NULL'; if (is_array($key)) { foreach ($key as $n => $k) $key[$n] = $this->key_name($k); $output = $this->m->getMulti($key); } else $output = $this->m->get($this->key_name($key)); } return $output; } /* +-------------------------------------+ Name: delete Purpose: deletes a single or multiple data elements from the memached servers @param return : none +-------------------------------------+ */ public function delete($key, $expiration = null) { if (is_null($key)) $this->errors[] = 'The key value cannot be NULL'; if (is_null($expiration)) $expiration = MEMCACHE_DELETE_EXPIRATION; if (is_array($key)) foreach ($key as $multi) $this->delete($multi, $expiration); else $this->m->delete($this->key_name($key), $expiration); } /* +-------------------------------------+ Name: replace Purpose: replaces the value of a key that already exists @param return : none +-------------------------------------+ */ public function replace($key = null, $value = null, $expiration = null) { if (is_null($expiration)) $expiration = MEMCACHE_EXPIRATION; if (is_array($key)) { foreach ($key as $multi) { if (!isset($multi['expiration']) || $multi['expiration'] == '') $multi['expiration'] = MEMCACHE_EXPIRATION; $this->replace($multi['key'], $multi['value'], $multi['expiration']); } } else { switch ($this->client_type) { case 'Memcache': $replace_status = $this->m->replace($this->key_name($key), $value, MEMCACHE_COMPRESSION, $expiration); break; default: case 'Memcached': $replace_status = $this->m->replace($this->key_name($key), $value, $expiration); break; } return $replace_status; } } /* +-------------------------------------+ Name: increment Purpose: increments a value @param return : none +-------------------------------------+ */ public function increment($key = null, $by = 1) { return $this->m->increment($this->key_name($key), $by); } /* +-------------------------------------+ Name: decrement Purpose: decrements a value @param return : none +-------------------------------------+ */ public function decrement($key = null, $by = 1) { return $this->m->decrement($this->key_name($key), $by); } /* +-------------------------------------+ Name: flush Purpose: flushes all items from cache @param return : none +-------------------------------------+ */ public function flush() { return $this->m->flush(); } /* +-------------------------------------+ Name: getversion Purpose: Get Server Vesion Number @param Returns a string of server version number or FALSE on failure. +-------------------------------------+ */ public function getversion() { return $this->m->getVersion(); } /* +-------------------------------------+ Name: get_stats Purpose: Get Server Stats Possible: "reset, malloc, maps, cachedump, slabs, items, sizes" @param returns an associative array with server's statistics. Array keys correspond to stats parameters and values to parameter's values. +-------------------------------------+ */ public function get_stats($type = 'items') { switch ($this->client_type) { case 'Memcache': $stats = $this->m->getStats($type); break; default: case 'Memcached': $stats = $this->m->getStats(); break; } return $stats; } /* +-------------------------------------+ Name: setcompresstreshold Purpose: Set When Automatic compression should kick-in @param return TRUE/FALSE +-------------------------------------+ */ public function setcompressthreshold($tresh, $savings = 0.2) { $setcompressthreshold_status = null; switch ($this->client_type) { case 'Memcache': $setcompressthreshold_status = $this->m->setCompressThreshold($tresh, $savings); break; default: $setcompressthreshold_status = true; break; } return $setcompressthreshold_status; } public function skip_prefix($prefix = true) { $this->skip_prefix = $prefix; return $this; } /* +-------------------------------------+ Name: key_name Purpose: standardizes the key names for memcache instances @param return : md5 key name +-------------------------------------+ */ private function key_name($key) { $prefix = $this->prefix; if($this->skip_prefix) $this->prefix = is_string($this->skip_prefix) ? $this->skip_prefix : ''; $output = md5(str_replace(' ', '', strtolower($this->prefix.$key))); if($this->skip_prefix) { $this->prefix = $prefix; $this->skip_prefix = false; } return $output; } /* +--------------------------------------+ Name: isConected Purpose: Check if the memcache server is connected. +--------------------------------------+ */ public function isConnected() { foreach ($this->get_stats() as $key => $server) { if ($server['pid'] == -1) { return false; } return true; } } }
前提是要有个配置文件:
// -------------------------------------------------------------------------- // Configs // -------------------------------------------------------------------------- define('MEMCACHE_ENGINE', 'Memcache'); define('MEMCACHE_HOST', '127.0.0.1'); define('MEMCACHE_PORT', 11211); define('MEMCACHE_WEIGHT', 1); define('MEMCACHE_PREFIX', ''); define('MEMCACHE_COMPRESSION', false); define('MEMCACHE_COMPRESS_SAVINGS', 0.2); define('MEMCACHE_EXPIRATION', 86400); define('MEMCACHE_DELETE_EXPIRATION', 0); // -------------------------------------------------------------------------- // Servers // -------------------------------------------------------------------------- $memcached['servers'] = [ 'default' => [ 'host' => MEMCACHE_HOST, 'port' => MEMCACHE_PORT, 'weight' => MEMCACHE_WEIGHT, 'persistent' => false, ], ]; // -------------------------------------------------------------------------- // Configuration // -------------------------------------------------------------------------- $memcached['config'] = [ 'engine' => MEMCACHE_ENGINE, // Set which caching engine you are using. Acceptable values: Memcached or Memcache 'prefix' => MEMCACHE_PREFIX, // Prefixes every key value (useful for multi environment setups) 'compression' => false, // Default: FALSE or MEMCACHE_COMPRESSED Compression Method (Memcache only). // Not necessary if you already are using 'compression' 'auto_compress_tresh' => false, // Controls the minimum value length before attempting to compress automatically. 'auto_compress_savings' => 0.2, // Specifies the minimum amount of savings to actually store the value compressed. The supplied value must be between 0 and 1. 'expiration' => 3600, // Default content expiration value (in seconds) 'delete_expiration' => 0, // Default time between the delete command and the actual delete action occurs (in seconds) ];
用法:
$app_products = $this->memcached->get('import_list_'.$start.$limit); if(!$app_products) { $app_products = $this->db ->table(TABLE_APP_PRODUCTS) ->fields('id, store_id, product_id, title, body_html, product_type, tags') ->limit($start.','.$limit) ->desc('id') ->where(array('store_id' => $this->_current_store_id, 'is_deleted' => 0, 'published' => 0)) ->pages(true, true); $this->memcached->set('import_list_'.$start.$limit, $app_products); }
其他操作:
1. 启动memcached
memcached -p 11211 -d -u root -P /tmp/memcached.pid
- -P是表示使用TCP,默认端口为11211
- -d表示后台启动一个守护进程(daemon)
- -u表示指定root用户启动,默认不能用root用户启动
- -P表示进程的pid存放地点,此处“p”为大写“P”
- -l,后面跟IP地址,手工指定监听IP地址,默认所有IP都在监听
- -m后面跟分配内存大小,以MB为单位,默认为64M
- -c最大运行并发连接数,默认为1024
- -f 块大小增长因子,默认是1.25
- -M 内存耗尽时返回错误,而不是删除项,即不用LRU算法 在64位系统中,会报libevent-1.4.so.2文件无法找到,解决办法是把32位目录里的同名文件链接至64位目录中,即像windows那样建立快捷方式。 Shell > /usr/local/lib/libevent-1.4.so.2 /usr/lib64/libevent-1.4.so.2 启动后如果发现没有端口在监听,是因为命动命令时带pid参数的“p”是大写“P”,你可能写成小写了。
- 接到memcache: shell>telnet 127.0.0.1 11211
2. 命令行直接操作命令
- 存数据。
- set:添加一个新条目到memcached或是用新的数据替换替换掉已存在的条目
- add:当KEY不存在的情况下,它向memcached存数据,否则,返回NOT_STORED响应
- replace:当KEY存在的情况下,它才会向memcached存数据,否则返回NOT_STORED响应
- cas:改变一个存在的KEY值 ,但它还带了检查的功能
- append:在这个值后面插入新值
- prepend:在这个值前面插入新值
- 取,有两个命令项:
- get:取单个值 ,从缓存中返回数据时,将在第一行得到KEY的名字,flag的值和返回的value长度,真正的数据在第二行,最后返回END,如KEY不存在,第一行就直接返回END
- Get_multi:一次性取多个值
- 删除,一个命令:
- delete
3. Memcached的分布式算法:
当向memcached集群存入/取出key/value时,memcached客户端程序根据一定的算法计算存入哪台服务器,然后再把key/value值存到此服务器中。也就是说,存取数据分二步走,第一步,选择服务器,第二步存取数据。

- 分布式算法(Consistent Hashing):
选择服务器算法有两种,一种是根据余数来计算分布,另一种是根据散列算法来计算分布。
- 余数算法: 先求得键的整数散列值,再除以服务器台数,根据余数确定存取服务器,这种方法计算简单,高效,但在memcached服务器增加或减少时,几乎所有的缓存都会失效。
- 散列算法:
先算出memcached服务器的散列值,并将其分布到0到2的32次方的圆上,然后用同样的方法算出存储数据的键的散列值并映射至圆上,最后从数据映射到的位置开始顺时针查找,将数据保存到查找到的第一个服务器上,如果超过2的32次方,依然找不到服务器,就将数据保存到第一台memcached服务器上。如果添加了一台memcached服务器,只在圆上增加服务器的逆时针方向的第一台服务器上的键会受到影响。在PHP中使用memcached提高动态网站性能, memcached, memcache, memcached数据库缓存类
4. Memcache的管理与性能监控:
可以通过命令行直接管理与监控也可通过nagios,cacti等web软件进行监控
命令行:Shell>telnet 127.0.0.1 1211 //如果在启动时指定了IP及端口号,这里要作相应改动,连接成功后命令
- stats:统计memcached的各种信息
- stats reset:重新统计数据
- stats slabs,显示slabs信息,可以详细看到数据的分段存储情况
- stats items:显示slab中的item数目
- stats cachedump 1 0:列出slabs第一段里存的KEY值
- set|get:保存或获取数据
- STAT evictions 0:表示要腾出新空间给新的item而移动的合法item数目

参考:
PHP: Memcached安装, Memcache/Memcached的PHP操作手册, Memcached使用, Memcached教程
本文:在PHP中使用memcached提高动态网站性能, memcached, memcache, memcached数据库缓存类
2 Comments