memcached注意
缺乏安全认证以及安全管制
需要将memcached服务器放置在防火墙(iptables)之后

 

linux平台 (centos)安装memcached

安装依赖
yum -y install libevent libevent-devel

以下方式任选一种

方式1. 自动安装方式
yum -y install memcached

# 方式2. 源代码编译方式安装
wget https://memcached.org/latest
mv latest memcached-1.5.20.tar.gz
tar -zxvf memcached-1.5.20.tar.gz
cd memcached-1.5.20
./configure --prefix=/usr/local/memcached
make && sudo make install
# linux平台启动
./memcached -p 11211 -u root -m 64m
或者
./memcached -p 11211 -u root -m 64m -d
或者
./memcached -p 11211 -m 64m -d -u root -l 127.0.0.1 -c 256 -p /tmp/memcached.pid

# linux平台服务进程查看
ps -ef | grep memcached
# 根据端口查看
netstat -tunpl | grep 11211

# 关闭进程
kill -9 pid号

知识补充:
memcached命令启动
-d:启动一个守护进程
-m:分配给mecached服务的内存大小,单位mb
-u:运行memcached服务的系统用户
-l:服务监听的ip地址,可以有多个地址
-p:服务监听的端口,默认11211
-c:最大运行的并发客户端连接数,默认1024
-p:设置保存服务的pid文件

emcached客户端
yum -y install telnet
telnet 127.0.0.1 11211
    trying 127.0.0.1...
    connected to 127.0.0.1.
    escape character is '^]'.

ctrl + c 
退出客户端

windows 平台

32位系统下载地址
http://downloads.northscale.com/memcached-win32-1.4.4-14.zip

# 64位系统下载地址
http://downloads.northscale.com/memcached-win64-1.4.4-14.zip

# windows平台安装启动
c:\memcached\memcached.exe -d install
c:\memcached\memcached.exe -d start
c:\memcached\memcached.exe -d stop

运行 -> pkgmgr /iu:"telnetclient"

memcached常用命令

set命令
– 将数据值存储到内存当中,将value存储到key当中
– 如果key已经存在,则更新该key的值,否则存储一个新的值
– key:键名称
– flags:服务器与用户提供的数据一起存储的32位无符号整数,并在检索到项目时随数据一起返回
– exptime:在内存中保存数据的时间长度(单位:秒,0:永不过期)
– bytes:缓存数据的字节数
– noreply:不需要返回响应

    # 登录客户端
    telnet 127.0.0.1 11211

    # 存储命令

    # set 命令
    set www.test.com 1 0 4
    best
    stored

    set www.test.com 1 0 4 noreply
    best

    # get 命令
    get www.test.com

add命令
– 将数据值存储到内存当中,将value存储到key当中

add www.test.com 1 0 4
best
not_stored

add www.test.com 1 0 4 noreply
best

add new 1 0 4
test
stored

replace命令
– 将已存储的key使用新值替换,如果key不存在,则替换失败

replace www.test.com 1 0 4
best
stored

replace www.test.com 1 0 4 noreply
best

replace new2 1 0 4
test
not_stored

append命令
– 向已存储的key的值后追加数据

append www.test.com 1 0 4
best
stored

append www.test.com 1 0 4 noreply
best

append new3 1 0 4
test
not_stored

prepend命令
– 向已存储的key的值前追加数据

prepend www.test.com 1 0 4
best
stored

prepend www.test.com 1 0 4 noreply
best

prepend new3 1 0 4
test
not_stored

cas(check-and-set)命令
– 当上一次当前客户端取值后,其他客户端没有对该key进行修改,才可以将值写入
– flags:服务器与用户提供的数据一起存储的32位无符号整数,并在检索到项目时随数据一起返回
– exptime:在内存中保存数据的时间长度(单位:秒,0:永不过期)
– bytes:缓存数据的字节数,
– unique_cas_token:通过 gets 命令获取的一个唯一的64位值
– noreply:不需要返回响应

gets www.imooc.com
value www.imooc.com 1 4 36
best
end

cas www.imooc.com 1 0 4 36
test
stored

get命令
– 获取存储在 key(键) 中的 value(数据值) ,如果 key 不存在,则返回空

get www.test.com
value www.test.com 1 4
test
end

get www.test.com test
value www.test.com 1 4
test
value test 1 4
test
end

gets命令
– gets 命令获取带有 cas 令牌存 的 value(数据值) ,如果 key 不存在,则返回空

gets www.test.com
value www.test.com 1 4 36
test
end

gets www.test.com test
value www.test.com 1 4 36
test
value test 1 4 37
test
end

incr命令
– 用于对已存在的 key(键) 的数字值进行自增操作

set count 1 0 1
1
stored

incr count 1
2

incr count 1
3

decr命令
– 用于对已存在的 key(键) 的数字值进行自减操作

decr count 1
2

decr count 1
1

stats命令
– 返回统计信息例如 pid(进程号)、版本号、连接数等

stats items命令
– 用于显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)

# stats cachedump 命令

stats cachedump 1 0
item www.test.com [4 b; 0 s]
item test [4 b; 0 s]
end

stats slabs命令
– 用于显示各个slab的信息,包括chunk的大小、数目、使用情况等

stats sizes命令
– 用于显示所有item的大小和个数

# 需要启动memcached时开启track_sizes
./memcached -u root -p 11211 -l 127.0.0.1 -d -o track_sizes

stats sizes
stat 96 1
end

# delete 命令

delete www.test.com
deleted

flush_all命令
– 用于清理缓存中的所有 key,value对
– time:指定时间后清除

 

安装php的memcached扩展

方式1:自动安装

yum -y install php-memcached

重启httpd服务
service httpd restart

移除yum安装的php-memcached
yum -y remove php-memcached

方式2:编译安装

# 安装依赖
yum -y install zlib-devel
yum -y install libmemcached-devel

# 编译安装
wget https://pecl.php.net/get/memcached-3.1.4.tgz 
tar zxvf memcached-3.1.4.tgz

cd memcached-3.1.4 
/usr/bin/phpize

./configure --with-php-config=/usr/bin/php-config 
 make && make install

# 修改php.ini
vim /etc/php.ini

# 添加
extension="memcached.so"

# 保存退出

# 重启httpd服务
service httpd restart

# 临时关闭
selinux
setenforce 0

# 永久关闭
selinux
vim /etc/selinux/config

# 修改
selinux
selinux=disabled

# 保存退出

php案例:构建高速缓存
– 如果缓存数据存在,请求memcached服务,查询缓存数据,显示给用户
– 如果缓存数据不存在,请求数据源数据,将数据存储至缓存中
第一次从数据库获取 

第二次从缓存读取

进入mysql 
mysql -uroot -p

创建数据库
create database cms;
use cms;

创建数据表
create table cms_users(
id int unsigned not null auto_increment primary key,
username varchar(50) not null default '',
age tinyint unsigned not null default 0,
sex tinyint unsigned not null default 0,
major varchar(100) not null default '',
created_time datetime null default current_timestamp
)engine=innodb default charset=utf8;

插入数据
insert into cms_users(username,age,sex,major) values('cyy',22,1,'math');
insert into cms_users(username,age,sex,major) values('cyy2',22,2,'chinese');
insert into cms_users(username,age,sex,major) values('cyy3',23,3,'english');
insert into cms_users(username,age,sex,major) values('cyy4',24,4,'business');
insert into cms_users(username,age,sex,major) values('cyy5',25,5,'php');

查看数据
select * from cms_users;

users.php

<?php
$start = microtime(true);

# 建立memcached连接
$mem = new memcached();
$mem->addserver('127.0.0.1', 11211);
$key_name = 'users';
$expire_time = 60;//过期时间

# 判断用户数据在缓存当中是否存在,如果存在,直接get,显示给用户
# 如果不存在,查询数据库,将数据写入到memcached当中,显示给用户

if (false === ($users = $mem->get($key_name))) {
    # 数据不存在于缓存当中,调用pdo查询db
    $users = fetchdatafromdb();
    # 将查询出的数据写入到memcached当中
    $mem->set($key_name, $users, time() + $expire_time);
}

function fetchdatafromdb() {
    echo 'fetching data from db....';
    # fetch users from mysql using pdo
    try {
        $dsn = "mysql:dbname=cms;host=localhost;port=3306";
        $pdo = new pdo($dsn, 'root', '123456', 
                [pdo::attr_errmode => pdo::errmode_exception]);
        $sql = 'select * from cms_users';
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        $users = $stmt->fetchall(pdo::fetch_assoc);
    } catch (pdoexception $pe) {
        echo $pe->getmessage();
    }
    return $users;
}

$sex_array = ['unknown', 'male', 'female'];
echo '<table border=1>';
echo '<tr><th>id</th><th>username</th><th>age</th><th>sex</th><th>major</th><th>created_time</th></tr>';
foreach ($users as $user) {
    echo '<tr>';
    echo '<td>'.$user['id'].'</td>';
    echo '<td>'.$user['username'].'</td>';
    echo '<td>'.$user['age'].'</td>';
    echo '<td>'.$sex_array[$user['sex']].'</td>';
    echo '<td>'.$user['major'].'</td>';
    echo '<td>'.$user['created_time'].'</td>';
    echo '</tr>';
}
echo '</table>';
$end = microtime(true);
echo "running time: ". ($end-$start);

小案例

<?php

$mem = new memcached();

# telnet 127.0.0.1 11211
$mem->addserver('127.0.0.1', 11211);

# stats
$stats = $mem->getstats();
# var_dump($stats);
$mem->set('php_client', ['one' => 1, 'two' => 2], time() + 60);
$res = $mem->get('php_client');
var_dump($res);