⑴ PHP中的Memcache和memcached的区别 Memcache的操作方法
Memcached和Memcache是Memcached服务器的扩展
其实很简单,memcache是php的一个扩展,用于php管理memcached(服务端),php-memcache.dll。
如果安装了memcached(服务端)不安装扩展,那么php无法操控memcached,但是命令行使用起来没有问题
如果安装了PHP memcache客户端(php memcache和php memcached)。但是没有安装memcached(服务端)服务,那么这个就无法使用
只有同时安装了memcached(服务端)和PHP memcache客户端扩展才可以提高动态网站性能
⑵ java中memcache怎么用
1. memcached client for java客户端API:memcached client for java
引入jar包:java-memcached-2.6.2.jar
package com.pcitc.memcached;
import com.danga.MemCached.*;
public class TestMemcached {
public static void main(String[] args) {
/* 初始化SockIOPool,管理memcached的连接池 */
String[] servers = { "192.168.1.111:11211" };
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(servers);
pool.setFailover(true);
pool.setInitConn(10);
pool.setMinConn(5);
pool.setMaxConn(250);
pool.setMaintSleep(30);
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setAliveCheck(true);
pool.initialize();
/* 建立MemcachedClient实例 */
MemCachedClient memCachedClient = new MemCachedClient();
for (int i = 0; i < 10; i++) {
/* 将对象加入到memcached缓存 */
boolean success = memCachedClient.set("" + i, "Hello!");
/* 从memcached缓存中按key值取对象 */
String result = (String) memCachedClient.get("" + i);
System.out.println(String.format("set( %d ): %s", i, success));
System.out.println(String.format("get( %d ): %s", i, result));
}
}
}
2. spymemcached客户端API:spymemcached client
引入jar包:spymemcached-2.10.3.jar
package com.pcitc.memcached;
import java.net.InetSocketAddress;
import java.util.concurrent.Future;
import net.spy.memcached.MemcachedClient;
public class MClient {
public static void main(String[] args) {
setValue();
getValue();
}
// 用spymemcached将对象存入缓存
public static void setValue() {
try {
/* 建立MemcachedClient 实例,并指定memcached服务的IP地址和端口号 */
MemcachedClient mc = new MemcachedClient(new InetSocketAddress(
"192.168.1.111", 11211));
Future<Boolean> b = null;
/* 将key值,过期时间(秒)和要缓存的对象set到memcached中 */
b = mc.set("neead", 900, "someObject");
if (b.get().booleanValue() == true) {
mc.shutdown();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 用spymemcached从缓存中取得对象
public static void getValue() {
try {
/* 建立MemcachedClient 实例,并指定memcached服务的IP地址和端口号 */
MemcachedClient mc = new MemcachedClient(new InetSocketAddress(
"192.168.1.111", 11211));
/* 按照key值从memcached中查找缓存,不存在则返回null */
Object b = mc.get("neead");
mc.shutdown();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
3.两种API比较
memcached client for java:较早推出的memcached JAVA客户端API,应用广泛,运行比较稳定。
spymemcached:A simple, asynchronous, single-threaded memcached client written in java. 支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常报timeOut等相关异常。
由于memcached client for java发布了新版本,性能上有所提高,并且运行稳定,所以建议使用memcached client for java
⑶ ThinkPHP5.0怎么使用memcache
'cache' => [
// 驱动方式
'type' => 'memcache',
// 缓存保存目录
'path' => CACHE_PATH,
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
],这样试试吧你看过后很简单吧以后不会可以向我一样经常到后盾人平台找找相关教材看看就会了,希望能帮到你,给个采纳吧谢谢٩(๑^o^๑)۶
⑷ memcache怎样清除缓存两种方法
memcache确实是一个加速很好的缓存器,什么都可以缓存~
——方法一——-cmd上直接清除,【清除所有缓存】
$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
flush_all
OK
quit
Connection to localhost closed by foreign host.
——方法二——-PHP清理缓存方法
<?php
$memcache = new Memcache;
$memcache->connect(‘localhost’, 11211) or die (“Could not connect”);
$version = $memcache->getVersion();
echo ”Server’s version: ”.$version.”
\n”;
?>
<?php
$memcache = new Memcache;
$memcache->connect(‘localhost’, 11211) or die (“Could not connect”);
print_r($memcache->getStats());
/**
* Array
* (
* [pid] => 8052
* [uptime] => 9205
* [time] => 1205898428
* [version] => 1.2.5 www.shellsec.com
* [pointer_size] => 32
* [rusage_user] => 0.008000
* [rusage_system] => 0.000000
* [curr_items] => 1
* [total_items] => 17
* [bytes] => 57
* [curr_connections] => 2
* [total_connections] => 15
* [connection_structures] => 3
* [cmd_get] => 9
* [cmd_set] => 23
* [get_hits] => 5
* [get_misses] => 4
* [evictions] => 0
* [bytes_read] => 671
* [bytes_written] => 850
* [limit_maxbytes] => 10485760
* [threads] => 1
* )
*/
?>
<?php
$memcache = new Memcache;
$memcache->connect(‘localhost’, 11211) or die (“Could not connect”);
$memcache->set( ’name’, ’leo’, 0, 30);
if(!$memcache->add( ’name’, ’susan’, 0, 30))
{
echo ’susan is exist’;
};
$memcache->replace( ’name’, ’lion’, 0, 300);
echo $memcache->get( ’name’);
$memcache->delete( ’name’, 5);
?>
<?php
function _callback_memcache_failure($host, $port) {
print ”memcache ’$host:$port’ failed”;
}
$memcache = new Memcache;
$memcache->addServer(’192.168.1.116′, 11211);
$memcache->setServerParams(’192.168.1.116′, 11211, 1, 15, true,
‘_callback_memcache_failure’);
echo $memcache->getServerStatus(’192.168.1.116′, 11211);
?>
<?php
$memcache = new Memcache;
$memcache->connect(‘localhost’, 11211);
$memcache->set(‘test_item’, 8);
$memcache->increment(‘test_item’, 4);
echo $memcache->decrement(‘test_item’, 7);
// 显示 5
?>
/usr/local/bin/memcached -d -m 10 -u root -l 127.0.0.1 -p 11211 -c 256 -P
/tmp/memcached.pid
memcached的服务正式启动
Memcache::add — 添加一个值,如果已经存在,则返回false
Memcache::addServer — 添加一个可供使用的服务器地址
Memcache::close — 关闭一个Memcache对象
Memcache::connect — 创建一个Memcache对象
memcache_debug — 控制调试功能
Memcache::decrement — 对保存的某个key中的值进行减法操作
Memcache::delete — 删除一个key值
Memcache::flush — 清除所有缓存的数据
Memcache::get — 获取一个key值
Memcache::getExtendedStats — 获取进程池中所有进程的运行系统统计
Memcache::getServerStatus — 获取运行服务器的参数
Memcache::getStats — 返回服务器的一些运行统计信息
Memcache::getVersion — 返回运行的Memcache的版本信息
Memcache::increment — 对保存的某个key中的值进行加法操作
Memcache::pconnect — 创建一个Memcache的持久连接对象
Memcache::replace — R对一个已有的key进行覆写操作
Memcache::set — 添加一个值,如果已经存在,则覆写
Memcache::setCompressThreshold — 对大于某一大小的数据进行压缩
Memcache::setServerParams — 在运行时修改服务器的参数
建议用面向对象的方式来测试这个库:
Memcache::getVersion方法的作用是返回运行的Memcache的版本信息。
Memcache::getStats 方法的作用是返回服务器的一些运行统计信息。Memcache::getStats方法有三个参
数,第一个参数表示要求返回的类型:reset, malloc, maps, cachemp, slabs, items, sizes;第二个
参数和第三个参数是在第一个参数设置为“cachemp”时使用的。Memcache::getExtendedStats方法的
作用是获取进程池中所有进程的运行系统统计。
Memcache::connect方法的作用是创建一个Memcache对象。Memcache::pconnect方法的作用是创建一个
Memcache的持久连接对象。Memcache::close方法的作用是关闭一个Memcache对象。
Memcache::set 方法的作用是添加一个值,Memcache::set方法有四个参数,第一个参数是key,第二个参
数是value,第三个参数可选,表示是否压缩保存,第四个参数可选,用来设置一个过期自动销毁的时间
。Memcache::add方法的作用和Memcache::set方法类似,区别是如果 Memcache::add方法的返回值为
false,表示这个key已经存在,而Memcache::set方法则会直接覆写。 Memcache::get方法的作用是获取
一个key值,Memcache::get方法有一个参数,表示key。Memcache::replace 方法的作用是对一个已有的
key进行覆写操作,Memcache::replace方法有四个参数,作用和Memcache::set方法的相同。
Memcache::delete方法的作用是删除一个key值,Memcache::delete方法有两个参数,第一个参数表示key
,第二个参数可选,表示删除延迟的时间。
memcache_debug()函数的作用是控制调试功能,前提是php在编译的时候使用了–enable-debug选项,否
则这个函数不会有作用。
Memcache::addServer 方法的作用是添加一个可供使用的服务器地址,Memcache::addServer方法有8个参
数,除了第一个参数意外,其他都是可选的,第一个参数表示服务器的地址,第二个参数表示端口,第三
个参数表示是否是一个持久连接,第四个参数表示这台服务器在所有服务器中所占的权重,第五个参数表
示连接的持续时间,第六个参数表示连接重试的间隔时间,默认为15,设置为-1表示不进行重试,第七个
参数用来控制服务器的在线状态,第8个参数允许设置一个回掉函数来处理错误信息。
Memcache::setServerParams方法的作用是在运行时修改服务器的参数,Memcache::setServerParams方法
有六个参数,Memcache::addServer方法少了第三和第四个参数。 Memcache::getServerStatus方法的作
用是获取运行服务器的参数,两个参数分别表示的地址和端口。
Memcache::flush方法的作用是清除所有缓存的数据,但是不会削去使用的内存空间。
Memcache::increment方法的作用是对保存的某个key中的值进行加法操作,Memcache::decremen方法的作
用是对保存的某个key中的值进行减法操作。
⑸ 怎么合理的使用memcache缓存如果缓存数据量过大怎么部署
memcache服务器,要特殊配置,内存要大,其他硬件能用即可
其他解决方案:可以配置分布式缓存
因为memcache一般是只供局域网使用的
工作原理是:web服务器使用memcache缓存,然后把数据缓存在memcache服务器上,memecache只用到内存
数据量过大只能增加服务器,部署分布式缓存
其他可以再联系
⑹ Memcache如何安装
1、将下载的memcached.exe文件放到磁盘固定的地方,不要删除。打开开始菜单,在输入框里输入cmd按回车。
⑺ 如何在Ubuntu 12.04上安装和使用Memcache
这个是centos的详细安装步骤,ubuntu也差不多。一下参考:PHP程序员,雷雪松的个人博客。
memcached需要libevent支持,所以首先安装libevent。
解决安装memcache出现configure: error: libevent is required. If it’s already installed, specify its path using –with-libevent=/dir/
这里要安装memcached.但在编译的时候提示需要指定libevent库,解决办法如下:
查看系统是否已经安装libevent
# rpm -qa|grep libevent
如果有,不要高兴,先升级
#yum -y install libevent
测试libevent是不是已经安装成功
#ls -al /usr/lib | grep libevent
可以看到多个已经安装的类包安装memcached(http://memcached.org/)
可以先查看编译参数
# wget http://memcached.googlecode.com/files/memcached-1.4.8.tar.gz
# tar zxvf memcached-1.4.8.tar.gz
# cd memcached-1.4.8
# ./configure -help
# ./configure -prefix=/usr/local/memcached
# make
# make install
在这个时候,不一定会编译通过,依旧会出现:
checking for libevent directory… configure: error: libevent is required. You can get it from http://www.monkey.org/~provos/libevent/
If it’s already installed, specify its path using –with-libevent=/dir/
因为libevent 这个包是系统默认安装的,没有安装相应的开发所用的头文件。
所以,还要使用如下命令来安装:
yum install libevent-devel
再编辑,即可通过。。
启用Memcached,
/usr/local/memcached/bin/memcached -d -m 128 -l 192.168.1.1 -p 11211 -u root
⑻ 如何在Ubuntu 12.04上安装和使用Memcache
如何在Ubuntu 12.04上安装和使用Memcache
关于Memcache
Memcache通过缓存服务器信息的方式来加速服务器处理能力的系统。Memcache分配一块服务器上的内存来缓存一段特定时间之内的最近的查询数据。一旦某个数据被再次请求,那么Memcache就直接从内存中返回这个数据,而不是从数据库中,所以这将会加速查询速度。
安装
安装前需要用户具有root权限。开始安装前,首先更新系统。
sudo apt-get update
另外,还需要安装MySQL和PHP。
sudo apt-get install mysql-server php5-mysql php5 php5-memcache
安装Memcache
首先安装Memcache。
sudo apt-get install memcached
接着安装php-pear(PHP扩展和应用库)。
sudo apt-get install php-pear
如果没有安装编译器,需要安装build-essential。
sudo apt-get install build-essential
最后使用PECL(PHP扩展社区库)来安装Memcache。
sudo pecl install memcache
安装完成后,向memcache.ini文件中添加memcached:
echo "extension=memcache.so" | sudo tee /etc/php5/conf.d/memcache.ini
现在可以开始使用Memcache了。
确认Memcache并查看其状态
Memcache运行后,可以通过以下命令查看。
ps aux | grep memcache
另外,还可以查看Memcache的状态。
echo "stats settings" | nc localhost 11211
Memcache如何工作的?
Memcache可以直接通过代码来实现从缓存中获取查询数据。Memcache获取数据的过程如下:
function get_foo(foo_id)
foo = memcached_get("foo:" . foo_id)
return foo if defined foo
foo = fetch_foo_from_database(foo_id)
memcached_set("foo:" . foo_id, foo)
return foo
end
简单的Memcache实例
研究一个简单的php脚本,该脚本使用Memcache来获取mysql表中的一个值。
首先登录到mysql,创建一个表,查询一些数据。
登录到mysql: mysql -u root -p
执行下面命令:
use test;
grant all on test.* to test@localhost identified by 'testing123';
create table example (id int, name varchar(30));
insert into example values (1, "new_data");
exit;
退出MySQL后,创建Memcache脚本文件。
nano memtest.php
详细研究一下memtest.php的脚本文件。
首先创建与Memcache的长连接,使用Memcache的默认端口,11211。
<?php
$meminstance = new Memcache();
$meminstance->pconnect('localhost', 11211);
然后连接到MySQL数据库
mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("test") or die(mysql_error());
接着创建查询,然后设置一个标识特定行为的key。
$query = "select id from example where name = 'new_data'";
$querykey = "KEY" . md5($query);
脚本首先查询缓存,如果结果不存在,则脚本再向原始数据库查询。一旦从原始数据库查询到结果,则脚本在Memcache中存储查询的结果,另外还可以设置缓存的有效期,即表示在这个有效期内,查询结果一直保持在缓存中(有效期一般是600秒)。
当首次运行脚本时,数据将会从MySQL数据库中获取到,此后这些数据会存储到缓冲中,这样第二次查询时,数据就是从缓存中获取的。
10分钟后,缓存会被再次清空,再次运行脚本,数据就会从数据库中获取。
$result = $meminstance->get($querykey);
if (!$result) {
$result = mysql_fetch_array(mysql_query("select id from example where name = 'new_data'")) or die('mysql error');
$meminstance->set($querykey, $result, 0, 600);
print "got result from mysql\n";
return 0;
}
print "got result from memcached\n";
return 0;
?>
以下是整个的脚本代码:
<?php
$meminstance = new Memcache();
$meminstance->pconnect('localhost', 11211);
mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("test") or die(mysql_error());
$query = "select id from example where name = 'new_data'";
$querykey = "KEY" . md5($query);
$result = $meminstance->get($querykey);
if (!$result) {
$result = mysql_fetch_array(mysql_query("select id from example where name = 'new_data'")) or die('mysql error');
$meminstance->set($querykey, $result, 0, 600);
print "got result from mysql\n";
return 0;
}
print "got result from memcached\n";
return 0;
?>
运行脚本的执行结果:
# php memtest.php
got result from mysql
# php memtest.php
got result from memcached
# php memtest.php
got result from memcached
⑼ 使用php Memcache模块如何正确遍历所有KEY以及VALUE
在php提供的用于与memcached交互的扩展模块中有memcached与memcache,前者提供方法getAllKeys用于遍历所有Memcached服务器上的key,但是并不保证原子操作,而后者却没有提供任何方法,虽然在PHP官方
文档中有人给出使用方法getExtendedStats来间接获取Memcached服务器上的所有key,但是给出的代码是有不少坑的,如果拿来就用,对于cluster的memcached服务器而言,有些问题就需要指出来。
下面将给出官方文档中的代码,并指出可能面临的问题,代码如下:
<?php
/**
*Functiontogetallmemcachekeys
*@authorManishPatel
*@Created:28-May-2010
*/
functiongetMemcacheKeys(){
$memcache=newMemcache;
$memcache->connect('127.0.0.1',11211)ordie("");
$list=array();
$allSlabs=$memcache->getExtendedStats('slabs');
$items=$memcache->getExtendedStats('items');
foreach($allSlabsas$server=>$slabs){
foreach($slabsAS$slabId=>$slabMeta){
$cmp=$memcache->getExtendedStats('cachemp',(int)$slabId);
foreach($cmpAS$keys=>$arrVal){
foreach($arrValAS$k=>$v){
echo$k."<br>";
}
}
}
}//EOgetMemcacheKeys()?>
在上述代码中,如果用于获取单个memcached服务器上的key,是不存在任何问题,但是获取连接池中的多个memcached所有key就存在问题,会发现打印出重复的key,问题就在于当使用getExtendedStats用去特定$slabID
上的信息时,返回的是连接池中所有的服务器上的特定$slabId的存储的keys信息。当$server为"127.0.0.1:11214"且$slabId为0将变量$cmp的信息打印出如下所示:
array(2){
["127.0.0.1:11214"]=>
array(1){
["course_schools__??¨é?¨"]=>
array(2){
[0]=>
string(1)"0"[1]=>
string(10)"12"}
}
["127.0.0.1:11216"]=>
array(1){
["monitorMemcache"]=>
array(2){
[0]=>
string(2)"10"[1]=>
string(10)"12"}
}
}
当$server为"127.0.0.1:11216"且$slabId为0将变量$cmp的信息打印出如下所示:
array(2){
["127.0.0.1:11214"]=>
array(1){
["course_schools__??¨é?¨"]=>
array(2){
[0]=>
string(1)"0"[1]=>
string(10)"12"}
}
["127.0.0.1:11216"]=>
array(1){
["monitorMemcache"]=>
array(2){
[0]=>
string(2)"10"[1]=>
string(10)"12"}
}
}
⑽ mysql 怎么使用memcached
一、Memcached简介
memcached
常被用来加速应用程序的处理,在这里,我们将着重于介绍将它部署于应用程序和环境中的最佳实践。这包括应该存储或不应存储哪些、如何处理数据的灵活分布以
及如何调节用来更新 memcached 和所存储数据的方法。我们还将介绍对高可用性的解决方案的支持,比如 IBM WebSphere® eXtreme
Scale。
所有的应用程序,特别是很多 web
应用程序都需要优化它们访问客户机和将信息返回至客户机的速度。可是,通常,返回的都是相同的信息。从数据源(数据库或文件系统)加载数据十分低效,若是每次想要访问该信息时都运行相同的查询,就尤显低效。
虽然很多 web 服务器都可被配置成使用缓存发回信息,但那与大多数应用程序的动态特性无法相适。而这正是 memcached
的用武之地。它提供了一个通用的内存存储器,可保存任何东西,包括本地语言的对象,这就让您可以存储各种各样的信息并可以从诸多的应用程序和环境访问这些信息。
二、基础知识
memcached 是一个开源项目,旨在利用多个服务器内的多余 RAM
来充当一个可存放经常被访问信息的内存缓存。这里的关键是使用了术语缓存:memcached 为加载自他处的信息提供的是内存中的暂时存储。
比如,考虑这样一个典型的基于 web 的应用程序。即便是一个动态网站可能也会有一些组件或信息常量是贯穿页面整个生命周期的。在一个博客站点内,针对单个
blog post
的类别列表不大可能在页面查看间经常性地变更。每次都通过一个对数据库的查询加载此信息相对比较昂贵,特别是在数据没有更改的情况下,就更是如此。从图 1
可以看到一个博客站点内可被缓存的页面分区。
图1.一个典型的博客页面内的可缓存元素
将这种结构放在 blog 站点的其他元素,poster 信息、注释 — 设置 blog post 本身 —
进行推断,可以看出为了显示主页的内容很可能需要发生 10-20 次数据库查询和格式化。
每天对数百甚至数千的的页面查看重复此过程,那么您的服务器和应用程序执行的查询要远远多于为了显示页面内容所需执行的查询。
通过使用 memcached,可以将加载自数据库的格式化信息存储为一种可直接用在 Web 页面上的格式。并且由于信息是从 RAM
而不是通过数据库和其他处理从磁盘加载的,所以对信息的访问几乎是瞬时的。
再强调一下,memcached 是一个用来存储常用信息的缓存,有了它,您便无需从缓慢的资源,比如磁盘或数据库,加载并处理信息了。
对 memcached 的接口是通过网络连接提供的。这意味着您可以在多个客户机间共享单个的 memcached
服务器(或多个服务器,如本文稍后所示的)。这个网络接口非常迅速,并且为了改善性能,服务器会故意不支持身份验证或安全性通信。但这不应限制部署选项。
memcached 服务器应该存在于您网络的内部。网络接口的实用性以及可以部署多个 memcached 实例的简便性让您可以使用多个机器上的多余 RAM
来提高您缓存的整体大小。
三、存储方法
memcached 的存储方法是一个简单的键/值对,类似于很多语言内的散列或关联数组。通过提供键和值来将信息存储到 memcached
内,通过按特定的键请求信息来恢复信息。
信息会无限期地保留在缓存内,除非发生如下的情况:
为缓存分配的内存耗尽 — 在这种情况下,memcached 使用
LRU(最近最少使用)方法从此缓存删除条目。最近未曾使用的条目会从此缓存中先删除,最旧的最先访问。
条目被明确删除 — 总是可以从此缓存内删除条目。
条目过期失效 — 各条目均有一个有效的期限以便针对此键存储的信息在过于陈旧时可从缓存中清除这些条目。
上述这些情况可以与您应用程序的逻辑综合使用以便确保缓存内的信息是最新的。有了这些基础知识后,让我们来看看在应用程序内如何能最好地利用
memcached。
四、何时使用memcached?
在使用 memcached 改进应用程序性能时,可以对一些关键的过程和步骤进行修改。
在加载信息时,典型的场景如图 2 所示。
图2.加载要显示的信息的典型顺序
一般而言,这些步骤是:
执行一个或多个查询来从数据库加载信息
格式化适合于显示(或进一步处理)的信息
使用或显示格式化了的数据
在使用 memcached 时,为配合这个缓存,可对应用程序的逻辑进行稍许修改:
尽量从缓存加载信息
如果存在,使用信息的被缓存版本
如果它不存在:
执行一个或多个查询来从数据库加载信息
格式化适合于显示或进一步处理的信息
将信息存储到缓存内
使用格式化了的数据
图 3 是对这些步骤的总结。
图3.在使用memcached时加载适合于显示的信息
数据加载成为了至多三个步骤的一个过程,从缓存加载数据或从数据库(视情况而定)加载数据并存储在缓存内。
当这个过程首次发生时,数据将正常地从数据库或其他数据源加载,然后再存储到 memcached 内。当下一次访问此信息时,它就会从 memcached
拉出,而不是从数据库加载,节省了时间和 CPU 循环。
问题的另一个方面是要确保如果更改了要存储在 memcached 内的信息,在更新后端信息的同时还要更新 memcached 的版本。这会让图 4
内所示的这个典型顺序发生稍许变化,如 图 5 所示。
图4.在一个典型的应用程序内更新或存储数据
图 5 显示了使用 memcached 后发生了变化的流程。
图5.在使用memcached时更新或存储数据
比如,仍以博客站点为例,在博客系统更新数据库内的类别列表时,更新应该遵循如下顺序:
更新数据库内的类别列表
格式化信息
将信息存储到 memcached 内
将信息返回至客户机
memcached 内的存储操作是原子的,所以信息的更新不会让客户机只获得部分数据;它们获得的或者是老版本,或者是新版本。
对于大多数应用程序,这两个操作是您惟一需要注意的。在访问他人使用的数据时,它会自动被添加到这个缓存内,而且如果对该数据进行了更改,此缓存内也会自动进行更新。
五、键、名称空间和值
memcached
另一个需要重点考虑的因素是如何组织和命名存储在缓存内的这些数据。从之前博客站点的例子中,不难看出需要使用一种一致的命名结构以便您能加载博客类别、历史和其他信息,然后再在加载信息(并更新缓存)时或者在更新数据(同样也要更新缓存)时使用。
使用的何种具体的命名系统特定于应用程序,但通常可以使用一种与现有应用程序类似的结构,并且这种结构很可能基于某种惟一识别符。当从数据库拉出信息或在整理信息集时,就会发生这种情况。
以 blog post 为例,可以在一个具有键 category-list 的项中存储类别列表。与此 post ID 对应的单个 post,比如
blogpost-29 相关的值都可以使用,而该项的注释则可以存储在 blogcomments-29内,其中 29 就是这个 blog post 的
ID。这样一来, 您就可以将各种各样的信息存储在缓存内,使用不同的前缀来标识这些信息。
memcached 键/值存储的简便性(以及安全性的缺乏)意味着如果您想要在使用同一个 memcached
服务器的同时支持多个应用程序,那么就可以考虑使用其他格式的量词来标识数据属于某种特定的应用程序。比如,可以添加像 blogapp:blogpost-29
这样的应用程序前缀。这些键是没有格式的,所以可以使用任何字符串作为键的名称。
在存储值的方面,应该确保存储在缓存内的信息适合于您的应用程序。比如,对于这个博客系统,您可能想要存储被博客应用程序使用的对象以便格式化博客信息,而不是原始的
HTML。如果同一个基础结构用在应用程序内的多个地方,这一点更具实用性。
大多数语言的接口,包括 Java™、Perl、PHP 等,都能串行化语言对象以便存储在 memcached
内。这就让您可以存储并随后从内存存储恢复全部对象,而不是在您的应用程序内手动重构它们。
很多对象,或它们使用的结构,都基于某种散列或数组结构。对于跨语言的环境,比如在 JSP 环境和 JavaScript
环境间共享相同信息,可以使用一种架构中立的格式,比如 JavaScript Object Notation (JSON) 甚或 XML。
六、填充并使用memcached
作为一种开源产品以及一种最初开发用来工作于现有开源环境内的产品,memcached 受大量环境和平台支持。与 memcached
服务器通信的接口有很多,并常常具有针对所有语言的多个实现。参见参考资料 以获得常用的库和工具箱。
要列出所有受支持的接口和环境不太可能,但它们均支持 memcached 协议提供的基础
API。这些描述已经被简化并应用在不同语言的上下文内,在这些语言中,使用不同的值可指示错误。主要的函数有:
get(key) — 从存储了特定键的 memcached 获得信息。 如果键不存在,就返回错误。
set(key, value [, expiry]) —
使用缓存内的标识符键存储这个特定的值。如果键已经存在,那么它就会被更新。期满时间的单位为秒,并且如果值小于 30 天
(30*24*60*60),那么就用作相对时间,如果值大于 30 天,那么就用作绝对时间 (epoch)。
add(key, value [, expiry]) —
如果键不存在就将这个键添加到缓存内,如果键已经存在就返回错误。如果您想要显式地添加一个新键而又不会因它已经存在而更新它,那么这个函数将十分有用。
replace(key, value [, expiry]) — 更新此特定键的值,如果键不存在就返回一个错误。
delete(key [, time]) —
从缓存中删除此键/值对。如果您提供一个时间,那么添加具有此键的一个新值就会被阻塞这个特定的时期。超时让您可以确保此值总是可以重新读取自您的数据中心。
incr(key [, value]) — 为特定的键增 1 或特定的值。只适用于数值。
decr(key [, value]) — 为特定的键减 1 或特定的值,只适用于数值。
flush_all — 让缓存内的所有当前条目无效(或到期失效)。
比如,在 Perl 内,基本 set 操作可以如清单 1 所示的那样处理。
清单 1. Perl 内的基本 set 操作
use Cache::Memcached;
my $cache = new Cache::Memcached {
'servers' => [
'localhost:11211',
],
};
$cache->set('mykey', 'myvalue');
Ruby 内的相同的基本操作如清单 2 所示。
清单 2. Ruby 内的基本 set 操作
require 'memcache'
memc = MemCache::new '192.168.0.100:11211'
memc["mykey"] = "myvalue"
在两个例子中可以看到相同的基本结构:设置 memcached 服务器,然后分配或设置值。其他的接口也可用,包括适合于 Java
技术的那些接口,让您可以在 WebSphere 应用程序内使用 memcached。memcached 接口类允许将 Java 对象直接序列化到
memcached 以便于存储和加载复杂的结构。当在像 WebSphere 这样的环境内进行部署时,有两个事情非常重要:服务的弹性(在 memcached
不可用时如何做)以及如何提高缓存存储量来改进在使用多个应用程序服务器或在使用像 WebSphere eXtreme Scale
这样的环境时的性能。我们接下来就来看看这两个问题。
七、弹性和可用性
有关 memcached
最常见的一个问题是:“若缓存不可用了,会发生什么情况呢?”正如之前章节中明示的,缓存内的信息不应该成为信息的的惟一资源。必须要能够从其他位置加载存储在缓存内的数据。
虽然,无法从缓存访问信息将会减缓应用程序的性能,但它不应该阻止应用程序的运转。可能会发生这样几个场景:
如果 memcached 服务宕掉,应用程序应该回退到从原始数据源加载信息并对信息进行显示所需的格式化。此应用程序还应继续尝试在 memcached
内加载和存储信息。
一旦 memcached
服务器恢复可用,应用程序就应该自动尝试存储数据。没有必要强制重载已缓存了的数据,可以使用标准的访问来用信息加载和填充缓存。最终,缓存将会被最常用的数据重新填充。
再次重申,memcached 是信息的缓存但并非惟一的数据源。memcached 服务器不可用不应该是应用程序的终结,虽然这意味着在
memcached 服务器恢复正常之前性能会有所降低。实际上,memcached
服务器相对简单,并且虽然不是绝对无故障的,但它的简单性的结果就是它很少会出错。
八、分配缓存
memcached 服务器只是网络上针对一些键存储值的一个缓存。如果有多台机器,那么很自然地会想要在所有多余机器上设置一个 memcached
的实例来提供一个超大的联网 RAM 缓存存储。
有了这个想法后,还有一种想当然是需要使用某种分配或复制机制来在机器之间复制键/值对。这种方式的问题是如果这么做反而会减少可用的 RAM
缓存,而不是增加。如图 6 所示,可以看出这里有三个应用程序服务器,每个服务器都可以访问一个 memcached 实例。
图6.多重memcached实例的不正确使用
尽管每个 memcached 实例都是 1 GB 的大小(产生 3 GB 的 RAM 缓存),但如果每个应用程序服务器只有其自己的缓存(或者在
memcached 之间存在着数据的复制),那么整个安装也仍只能有 1 GB 的缓存在每个实例间复制。
由于 memcached 通过一个网络接口提供信息,因此单个的客户机可以从它所能访问的任何一个 memcached
实例访问数据。如果数据没有跨每个实例被复制,那么最终在每个应用程序服务器上,就可以有 3 GB 的 RAM 缓存可用,如图 7 所示。
图7.多重memcached实例的正确使用
这个方法的问题是选择哪个服务器来储存键/值对,以及当想要重新获得一个值时,如何决定要与哪个 memcached
服务器对话。问题的解决方案就是忽略复杂的东西,比如查找表,或是寄望 memcached 服务器来为您处理这个过程。而 memcached
客户机则必须要力求简单。
memcached 客户机不必决定此信息,它只需对在存储信息时指定的键使用一个简单的散列算法。当想要从一列 memcached
服务器存储或获取信息时,memcached 客户机就会用一个一致的散列算法从这个键获取一个数值。举个例子,键 mykey 被转换成数值 23875
。是保存还是获取信息无关紧要,这个键将总是被用作惟一标识符来从 memcached 服务器加载,因此在本例中,“mykey” 散列转化后对应的值总是
23875。
如果有两个服务器,那么 memcached 客户机将对这个数值进行一个简单的运算(例如,系数)来决定它应将此值存储在第一个还是第二个配置了的
memcached 实例上。
当存储一个值时,客户机会从这个键确定出散列值以及它原来存储在哪个服务器上。当获取一个值时,客户机会从这个键确定出相同的散列值并会选择相同的服务器来获取信息。
如果在每个应用程序服务器上使用的是相同的服务器列表(并且顺序相同),那么当需要保存或检索同一个键时,每个应用程序服务器都将选择同一个
服务器。现在,在这个例子中,有 3GB 的 memcached 空间可以共享,而不是同一个 1 GB
的空间的复制,这就带来了更多的可用缓存,并很有可能会提高有多个用户情况下的应用程序的性能。
九、如何能不使用memcached?
尽管 memcached 很简单,但 memcached 实例有时候还是会被不正确地使用。
memcached不是一个数据库
最常见的 memcached 误用就是把它用作一个数据存储,而不是一个缓存。memcached
的首要目的就是加快数据的响应时间,否则数据从其他数据源构建或恢复需要很长时间。一个典型的例子就是从一个数据库中恢复信息,特别是在信息显示给用户前
需要对信息进行格式化或处理的时候。Memcached 被设计用来将信息存储在内存中以避免每次在数据需要恢复时重复执行相同的任务。
切不可将 memcached 用作运行应用程序所需信息的惟一信息源;数据应总是可以从其他信息源获取。此外,要记住 memcached
只是一个键/值的存储。不能在数据上执行查询,或者对内容进行迭代来提取信息。应该使用它来存储数据块或对象以备批量使用。
不要缓存数据库行或文件
虽然可以使用 memcached
存储加载自数据库的数据行,但这实际上是查询缓存,并且大多数数据库都提供各自的查询缓存的机制。其他的对象,比如文件系统的图像或文件的情况与此相同。很多应用程序和
web 服务器针对此类工作已经有了一些很好的解决方案。
如果在加载和格式化后,使用它来存储全部信息块,就可以从 memcached
获得更多的实用工具和性能上的改善。仍以我们的博客站点为例,存储信息的最佳点是在将博客类别格式化为对象,甚至是在格式化成 HTML 后。博客页面的构造可通过从
memcached 加载各个组件(比如 blog post、category list、post history 等)并将完成的 HTML
写回至客户机实现。
memcached并不安全
为了确保最佳性能,memcached 并未提供任何形式的安全性,没有身份验证,也没有加密。这意味着对 memcached
服务器的访问应该这么处理:一是通过将它们放到应用程序部署环境相同的私有侧,二是如果安全性是必须的,那么就使用 UNIX® socket
并只允许当前主机上的应用程序访问此 memcached 服务器。
这多少牺牲了一些灵活性和弹性,以及跨网络上的多台机器共享 RAM 缓存的能力,但这是在目前的情况下确保 memcached
数据安全性的惟一一种解决方案。
十、不要限制自己
除了不应该使用 memcached 实例的情况外,memcached 的灵活性不应忽视。由于 memcached
与应用程序处于相同的架构水平,所以很容易集成并连接到它。并且更改应用程序以便利用 memcached 也并不复杂。此外,由于 memcached
只是一个缓存,所以在出现问题时它不会停止应用程序的执行。如果使用正确的话,它所做的是减轻其余服务器基础设施的负载(减少对数据库和数据源的读操
作),这意味着无需更多的硬件就可以支持更多的客户机。
但请记住,它仅仅是个缓存!
结束语
在本文中,我们了解了 memcached 以及如何最佳地使用它。我们看到了信息如何存储、如何选择合理的键以及如何选择要存储的信息。我们还讨论了所有
memcached 用户都要遇到的一些关键的部署问题,包括多服务器的使用、当 memcached 实例消亡时该怎么做,以及(也许最为重要的)在哪些情况下不能使用
memcached。
作为一种开源的应用程序并且是目的简单而直白的应用程序,memcached 的功能和实用性均来自于这种简单性。通过为信息提供巨大的 RAM
存储空间、让它在网络上可用,然后再让它可通过各种不同的接口和语言访问到,memcached 可被集成到多种多样的安装和环境中。