Memcache入门

本文详细介绍了Memcache的背景、工作原理及安装使用方法,包括memcached服务的启动与基本命令,以及如何在PHP环境中使用memcached扩展进行缓存操作。此外,还探讨了memcached服务集群的构建与优化策略。
摘要由CSDN通过智能技术生成

Memcache入门

memcached介绍

memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,memcached自管理这些HashTable。为什么会有Memcache和memcached两种名称?
其实memcache是这个项目的名称,而memcached是它服务器端的主程序文件名。Memcache在高并发的情况下通过将热数据缓存到内存中来降低数据库的压力,这是目前很多网站使用Memcache的原因。

memcached的安装使用

安装Memcache

memcached的安装非常简单,去官方网站下载http://memcached.org/downloads最新的memcached资源,安装方式很简单,官方例子。唯一比较不能接受的一点是,城外的网都比较慢

wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install

启动memcached服务

进入到memcached的安装目录,然后通过daemon的方式启动起来。

localhost:Downloads MLS$ cd memcached-1.4.23
localhost:memcached-1.4.23 MLS$ ./memcached -d

检查memcached进程是否已经启动起来:

localhost:memcached-1.4.23 MLS$ ps -ef | grep memcached | grep -v grep
501  6978     1   0  9:37下午 ??         0:00.01 ./memcached -d

可以看到memcached服务以daemon的形式在后台运行,我们并没有制定端口和IP。memcached默认的端口11211,默认的IP就是本机地址127.0.0.1。当然memcached还给我们分配了默认的内存空间。

Linux下试玩memcached

我们可以使用telnet进入memcached的运行环境,进入之后就可以对memcached进行基本的操作了

localhost:memcached-1.4.23 MLS$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

注意,退出命令是quit回车

memcached基本命令的格式



注意,存活时间的单位是秒,0表示永久不过期,
操作命令包括以下操作:
set表示按照相应的存储该数据,没有的时候增加,有的覆盖。
add表示按照相应的添加该数据,但是如果该已经存在则会操作失败。
replace表示按照相应的替换数据,但是如果该不存在则操作失败
get获取一个key为name的数据
delete删除一个key为name的数据,返回DELETED表示删除成功

set操作

set操作注意最后一个表示字节长度的限制,如果设置的值得长度和实现指定的不符合,将抛出ERROR;如果返回STORED表示存储成功

set name 0 0 7
zhongyx
STORED

注意指定长度的时候要严格限制,比如下面这个命令就会发生错误

set key1 0 0 7
yongxiongzhong
CLIENT_ERROR bad data chunk
ERROR

get操作

比如获取一个key为name的数据

get name
VALUE name 0 7
zhongyx
END

delete操作

删除一个key为name的数据,返回DELETED表示删除成功

delete name
DELETED

replace操作

进行replace操作的时候,一定要确保已经设定过该key的缓存值,否则会返回一个错误,假设name是存在的情况

replace name 0 0 7 
yongxio
STORED

当尝试去replace一个不存在的值时候

replace name1 0 0 7
zhongyx
NOT_STORED

在PHP中使用memcached

memcached的命令模式已经熟悉的差不多了,但是,最终我们是需要将memcached的服务接入到我们的实际应用中,由于本人就是基于php的web开发,所以本人是在PHP的环境中使用memcached服务。整个安装过程有点繁琐

安装依赖库

https://launchpad.net/libmemcached/1.0/1.0.4/+download/libmemcached-1.0.4.tar.gz

tar -xzvf libmemcached-1.0.4.tar.gz  
cd libmemcached-1.0.4  
./configure  && make  && make install  

安装memcached扩展

这里采用php扩展库里面的资源。http://pecl.php.net/get/memcached-2.0.1.tgz下载

tar vxzf memcached-2.0.1.tgz  
cd memcache-2.0.1  
phpize  
./configure  && make  && make install  

装完后,最后显示Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20121212/,在该目录下生成memcached.so
我的so文件/usr/lib/php/extensions/no-debug-non-zts-20121212/memcached.so

php配置文件中加入memcached扩展

修改php.ini文件,添加memcached扩展php.ini文件最后一行添加以下代码

extension=/usr/lib/php/extensions/no-debug-non-zts-20121212/memcached.so

重启php,如果安装成功,可以访问phpinfo看到以下界面
getImage?fileId=56ed259eab644116760001aa

php中使用memcached服务

在php中使用memcached非常简单,如果安装了memcached扩展,直接在php中new Memcached之后就可以正式使用memcached服务了,在实际应用中,一般是setget为主

<?php
$mc = new Memcached();
$mc->addServer("localhost", 11211);

$mc->set("foo", "Hello!");
$mc->set("bar", "Memcached...");

$arr = array(
    $mc->get("foo"),
    $mc->get("bar")
);
var_dump($arr);
?>

第一个memcached应用例子

在早些年,不知道现在还有没有这种使用方法,看到php的相关教程中有以下使用例子,缓存是做在数据库层,也就是缓存的key是SQL语句的md5值,当需要从数据库中区数据的时候,需要看下memcached中时候有数据,如果通过取数据的SQL命中缓存,则直接返回结果。

<?php
$sql = "select * from user where id={$_GET['uid']}";

//检查缓存
$mc = new Memcached();
$mc->addServer("localhost", 11211);
$row = $mc -> get(md5($sql))
if($row){
    return $row; 
}

//查询数据库
$conn = new mysql('localhost', '3306', 'root', '123456');
....//此处省略数据库查询

$mc->set(md5($sql), $row);

这种方式应该算是一种最简单的方式了,比较简单,不过这种方式也有它的缺点

  1. 现在的数据库操作一般都采用PDO方式的预处理语句
  2. select * 和 select username会存储不一样的缓存中,结果冗余,而且命中率低
  3. 很难排查问题,获取缓存的key比较难

第二个memcached的应用例子

目前比较多的缓存放在业务层,通过业务逻辑去缓存内容,比如缓存一个用户的数据,是通过uid为维度的缓存,和SQL没有任何关系。这样可以带来好处

  1. 缓存变得好管理,一个uid就一个缓存数据
  2. 命中率增高,因为参数变成了一个uid
  3. 可以很容易的知道用户缓存的key

所在这这种缓存的模型里面,维护将变得更加便捷,下面这个例子和上面的例子有点差别

<?php
$id = $_GET['uid'];
$key = 'USER:UID:'.$id;//一般会加缓存前缀

$mc = new Memcached();
$mc->addServer("localhost", 11211);
$row = $mc->get($key);
if($row){
    return $row;
}

//继续走数据库逻辑,并将数据写入mc
$row->set($key, $row);

memcached服务集群

为什么要使用集群

在一些简单的网站中,如果仅仅是为了加速网站,那单台memcached服务挂了问题也不大。但是,如果网站的访问量特别大,当memcached服挂掉了,大量的读操作直接奔向DB,那数据库肯定会奔溃掉。在稍微稳定的网站中,是绝对不允许单点故障的。所以,如果需要构建一个稳定的缓存服务,必须

  1. 避免单点故障,服务要始终是可用的
  2. 提升缓存服务的响应速度

需要一个代理

在一个大型的memcached服务集群中,少则几个memcached服务的IP地址,多则几十个memcached服务的IP地址。假如一共有20台机器提供memcached服务,加入一台服务挂了怎么办,加入需要换掉其中的10台服务怎么办,假如需要做到自动摘除挂掉的服务怎办。很显然,让应用层去处理这些情况很不实际,所以我们需要一个中间层,来自twitter的工程师为我们解决了这个问题。他们开发了代理memcached的twemproxy,目前我们团队正在使用的nutcraker

nutcraker的使用

下载安装nutcraker

下载地址:https://twemproxy.googlecode.com/files/nutcracker-0.3.0.tar.gz
解压之后,运行安装命令

cd nutcracker-0.3.0/
./configure 
make && make install
配置nutcracker

配置文件在conf/nutcracker.yml

beta:
  listen: 127.0.0.1:22122  #nutcraker代理监听的端口
  hash: fnv1a_64  #hase算法
  hash_tag: "{}" 
  distribution: ketama
  auto_eject_hosts: false #是否在节点无法响应的时候临时找出,区分save data的slave和cache data的slave 
  timeout: 400 #超时
  servers: #配置真正的mc存储
   - 127.0.0.1:6380:1 server1
   - 127.0.0.1:6381:1 server2
   - 127.0.0.1:6382:1 server3
   - 127.0.0.1:6383:1 server4

这个配置表示127.0.0.1:22122这个端口的nutcraker服务代理了servers的4台正真的memcache存储,这个4台memcached服务分别为

  • 127.0.0.1:6380:1
  • 127.0.0.1:6381:1
  • 127.0.0.1:6382:1
  • 127.0.0.1:6383:1
    也就是说在应用层,只有127.0.0.1:22122这个接口暴露给我们去使用memcached服务了,我们不关系这个服务下操纵了多少台正真的memcached服务
启动nutcraker服务

采用daemon的方式运行,如果你是用memcache测试的话,注意将配置文件中的redis:true注释掉

#启动
localhost:memcached-1.4.23 MLS$ src/nutcracker -d
#查看
localhost:memcached-1.4.23 MLS$ ps -ef | grep nutcracker
 501 17738     1   0  2:26下午 ??         0:00.01 src/nutcracker -d
 501 19559   580   0  2:54下午 ttys002    0:00.00 grep nutcracker
启动4台真正的memcached服务

如果只启动nutcracker服务是没有用的,它只是一个代理,西部要把nutcracker代理的正真的memcached服务起来,才能正常工作运转,其中方法如下

启动4台memcache服务
localhost:memcached-1.4.23 MLS$ ./memcached -d -p 6380;./memcached -d -p 6381;./memcached -d -p 6382;./memcached -d -p 6383
#查看
localhost:memcached-1.4.23 MLS$ ps -ef | grep memcached
  501 17541     1   0  2:23下午 ??         0:00.03 ./memcached -d -p 6380
  501 17580     1   0  2:24下午 ??         0:00.03 ./memcached -d -p 6381
  501 17585     1   0  2:24下午 ??         0:00.03 ./memcached -d -p 6382
  501 17587     1   0  2:24下午 ??         0:00.03 ./memcached -d -p 6383
测试nutcraker服务

连接nutcraker服务并且向nutcraker服务代理写一个数据

localhost:nutcracker-0.3.0 MLS$ telnet 127.0.0.1 22122
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set key1 0 0 5
hello
STORED

存储是分布式的,并不是每一台真正的memcached服务上都有数据,而是命中其中的一台,然后将数据缓存起来,通过去每台memcached服务查看数据可以看到

6380端口
localhost:memcached-1.4.23 MLS$ telnet 127.0.0.1 6380
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get key1
VALUE key1 0 5
hello
END

6381端口
localhost:memcached-1.4.23 MLS$ telnet 127.0.0.1 6381
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get key1
END

6382端口
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get key1
END

6383端口
localhost:memcached-1.4.23 MLS$ telnet 127.0.0.1 6383
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get key1
END

转载于:https://www.cnblogs.com/jianbingguozi/p/6937688.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值