linux 学习笔记-077-NoSQL-memcached 命令行操作及其数据导出和导入,php 连接 memcached,memcached 中存储 sessions

发布于 2018-04-28  343 次阅读


memcached 命令行

memcached 使用 telnet 命令进去

01

安装 telnet 工具,其中 key1 和 key2 均是 key 名,30 表示过期时间为 30 秒,最后一位数字 2 或 3 表示需要存储的值为两个字节或三个字节

[root@am-01:~#] yum -y install telnet

[root@am-01:~#] telnet 127.0.0.1 11211

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

set key2 0 30 2

12

STORED

set key1 0 30 3

21

321

CLIENT_ERROR bad data chunk

ERROR

set key1 0 20 3

321

STORED

get key1

VALUE key1 0 3

321

END

get key2

END

02

memcached 命令行语法规则详解

<command name> <key> <flags> <exptime> <bytes>\r\n <data block>\r\n

注:\r\n 在 windows 下是 Enter 键

<command name> 可以是 set, add, replace

set 表示按照相应的<key>存储该数据,没有的时候增加,有的时候覆盖

add 表示按照相应的<key>添加该数据,但是如果该<key>已经存在则会操作失败

replace 表示按照相应的<key>替换数据,但是如果该<key>不存在则操作失败。

<key> 客户端需要保存数据的 key

<flags> 是一个 16 位的无符号的整数(以十进制的方式表示)。该标志将和需要存储的数据一起存储,并在客户端 get 数据时返回。客户端可以将此标志用做特殊用途,此标志对服务器来说是不透明的。

<exptime> 为过期的时间。若为 0 表示存储的数据永远不过期(但可被服务器算法:LRU 等替换)。如果非 0(unix 时间或者距离此时的秒数),当过期后,服务器可以保证用户得不到该数据(以服务器时间为标准)。

<bytes> 需要存储的字节数,当用户希望存储空数据时<bytes>可以为 0

<data block>需要存储的内容,输入完成后,最后客户端需要加上\r\n(直接点击 Enter)作为结束标志。

03

memcached 例子,分别为新建,修改,删除

[root@am-01:~#] telnet 127.0.0.1 11211

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

set key3 1 100 4

1234

STORED

get key3 

VALUE key3 1 4

1234

END



replace key3 1 50 5

12345

STORED

get key3

VALUE key3 1 5

12345

END



delete key3

DELETED

get key3

END

memcached 数据导出和导入

当想把 memcached 重启或者重启服务器的时候,为保证数据完整性,建议先把 memcached 缓存的数据导出到本地磁盘

01

导出,在这之前,为了令实验效果更明显,我们先写入几条数据吧

另外,telnet 使用 ctrl+]退出编辑界面,之后再使用 quit 退出 telnet 界面

[root@am-01:~#] telnet 127.0.0.1 11211

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

set name 1 0 6

asdfgh

STORED



set am 1 0 6

lkjhgf

STORED



set age 0 0 2

25

STORED



^]

telnet> quit

Connection closed.

02

数据导出,只有三条数据是因为其他数据都已经过期了

[root@am-01:~#] memcached-tool 127.0.0.1:11211 dump > /tmp/membak.txt

Dumping memcache contents

  Number of buckets: 1

  Number of items  : 3

Dumping bucket 1 - 3 total items

[root@am-01:~#] ls -l /tmp/membak.txt

-rw-r--r-- 1 root root 92 4 月  28 18:53 /tmp/membak.txt

[root@am-01:~#] cat /tmp/membak.txt

add am 1 1524843626 6

lkjhgf

add name 1 1524843626 6

asdfgh

add age 0 1524843626 2

25

03

数据导入,这里可以见到,导入数据的时候使用的是 add(add 表示按照相应的<key>添加该数据,但是如果该<key>已经存在则会操作失败),那么,假如在库中已经有需要倒入的数据,就会提示错误 NOT_STORED,所以要想试验成功,重启一下 memcached,因为 memcached 的数据存储在内存中,重启即清除

[root@am-01:~#] cat /tmp/membak.txt

add am 1 1524843626 6

lkjhgf

add name 1 1524843626 6

asdfgh

add age 0 1524843626 2

25

[root@am-01:~#] nc 127.0.0.1 11211 < /tmp/membak.txt

NOT_STORED

NOT_STORED

NOT_STORED

[root@am-01:~#] systemctl restart memcached.service

[root@am-01:~#] nc 127.0.0.1 11211 < /tmp/membak.txt

STORED

STORED

STORED

04

测试一下是否导入成功,其中"nc 127.0.0.1 11211"和"telnet 127.0.0.1 11211"作用是一样的

测试发现数据没导入成功,这是因为导出的数据均有个时间戳,而这个时间戳就是该条数据过期的时间点,如果当前时间已经超过该时间戳,那么是导入不成功的

[root@am-01:~#] nc 127.0.0.1 11211

get am

END

[root@am-01:~#] cat /tmp/membak.txt

add am 1 1524843626 6

lkjhgf

add name 1 1524843626 6

asdfgh

add age 0 1524843626 2

25

[root@am-01:~#] date -d @1524843626

2018 年 04 月 27 日 星期五 23:40:26 CST

[root@am-01:~#] date

2018 年 04 月 28 日 星期六 19:04:06 CST

05

那么,该怎么做才能正常导入数据呢?

修改备份数据的时间戳为当前时间的一小时后,即为当前系统时间的一小时后才会过期

可以见到,修改了时间戳的数据能成功导入了

[root@am-01:~#] systemctl restart memcached.service

[root@am-01:~#] date -d "+1 hour" +%s

1524917232

[root@am-01:~#] vim /tmp/membak.txt

add am 1 1524917232 6

lkjhgf

add name 1 1524917232 6

asdfgh

add age 0 1524843626 2

25

[root@am-01:~#] nc 127.0.0.1 11211 < /tmp/membak.txt

STORED

STORED

STORED

[root@am-01:~#] nc 127.0.0.1 11211

get am

VALUE am 1 6

lkjhgf

END

get name

VALUE name 1 6

asdfgh

END

get age

END

php 连接 memcached

php 能连接 mysql,从而实现和 mysql 的交互,同理,php 也能连接 memcached,从而实现跟 memcached 的交互

01

安装 php 的 memcache 扩展,使用-m 查看没有 memcached 扩展,那么,就安装一下吧

安装好之后,再次检测,可以见到扩展已经安装成功

[root@am-01:~#] /usr/local/php-fpm/sbin/php-fpm -m

[PHP Modules]

cgi-fcgi

Core

ctype

curl

date

dom

ereg

exif

fileinfo

filter

ftp

gd

hash

iconv

json

libxml

mbstring

mcrypt

mysql

mysqli

openssl

pcre

PDO

pdo_mysql

pdo_sqlite

Phar

posix

Reflection

session

SimpleXML

soap

SPL

sqlite3

standard

tokenizer

xml

xmlreader

xmlwriter

zlib



[Zend Modules]

[root@am-01:~#] cd /usr/local/src/

[root@am-01:/usr/local/src#] wget http://www.apelearn.com/bbs/data/attachment/forum/memcache-2.2.3.tgz

[root@am-01:/usr/local/src#] tar xvf memcache-2.2.3.tgz

[root@am-01:/usr/local/src#] cd memcache-2.2.3/

[root@am-01:/usr/local/src/memcache-2.2.3#] /usr/local/php-fpm/bin/phpize

Configuring for:

PHP Api Version:         20131106

Zend Module Api No:      20131226

Zend Extension Api No:   220131226

[root@am-01:/usr/local/src/memcache-2.2.3#] ./configure --with-php-config=/usr/local/php-fpm/bin/php-config

[root@am-01:/usr/local/src/memcache-2.2.3#] make

[root@am-01:/usr/local/src/memcache-2.2.3#] make install

Installing shared extensions:     /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/

[root@am-01:/usr/local/src/memcache-2.2.3#] vim /usr/local/php-fpm/etc/php.ini

extension="memcache.so"

[root@am-01:/usr/local/src/memcache-2.2.3#] /usr/local/php-fpm/sbin/php-fpm -m

[PHP Modules]

memcache

02

测试一下,下载一个 php 的脚本文件用做测试,运行一下脚本,可以见到测试是成功的

[root@am-01:/usr/local/src/memcache-2.2.3#] cd

[root@am-01:~#] curl www.apelearn.com/study_v2/.memcache.txt > 1.php

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100   785  100   785    0     0    133      0  0:00:05  0:00:05 --:--:--   233

[root@am-01:~#] /usr/local/php-fpm/bin/php 1.php

Get key1 value: This is first value<br>Get key1 value: This is replace value<br>Get key2 value: Array

(

    [0] => aaa

    [1] => bbb

    [2] => ccc

    [3] => ddd

)

<br>Get key1 value: <br>Get key2 value: <br>

Memcached 中存储 session

memcached 中存储 session 一般用在负载均衡,比如是 lnmp 架构,这种多 web 服务器,在用户登录的时候就遇到一个问题,第一次登录在 A 服务器上,第二次在 B 服务器上,这时候呢,就无法让某一个用户的登录状态始终在某服务器上. 如果我们使用的是 nginx 代理的话,可以使用 IP_HASH,  但如果是使用 LVS,那么就无法让某一个用户的登录状态始终在某服务器上.  但有个方法让 session 不再存到磁盘上,而是存到 memcached 里面去,而 memcached 可以作为一个公共的服务器,那它访问的时候使用其中某个内网 IP,而不是 127.0.0.1

01

先看下存储的 session 是什么样的,默认情况下,php-fpm 存储的 session 文件在/tmp 目录下

[root@am-01:~#] cd /data/wwwroot/default

[root@am-01:/data/wwwroot/default#] wget http://study.lishiming.net/.mem_se.txt

[root@am-01:/data/wwwroot/default#] mv .mem_se.txt session.php

[root@am-01:/data/wwwroot/default#] curl aaa.com/session.php

1524927005<br><br>1524927005<br><br>oi33iaddi6q20qfo06rhm26076

[root@am-01:/data/wwwroot/default#] ls -l /tmp/

-rw------- 1 php-fpm php-fpm 37 4 月  28 22:50 sess_oi33iaddi6q20qfo06rhm26076

02

让 session 不存放在/tmp 下,而存放在 memcached 中

在 php-fpm.conf 的 pool 中新增两行配置,一行指定存储类型,一行指定 memcached 的服务器 IP 和端口

最后重启 php-fpm 并测试下,可以见到,/tmp 目录下已经没有 session 了,这时 session 存放到了 memcached 里面

[root@am-01:~#] vim /usr/local/php-fpm/etc/php-fpm.d/aaa.conf

[am]

php_value[session.save_handler] = memcache

php_value[session.save_path] = "tcp://172.17.1.240:11211"

[root@am-01:/data/wwwroot/default#] systemctl restart php-fpm.service

[root@am-01:/data/wwwroot/default#] rm -rf /tmp/sess_oi33iaddi6q20qfo06rhm26076

[root@am-01:/data/wwwroot/default#] curl aaa.com/session.php

1524927367<br><br>1524927367<br><br>

[root@am-01:/data/wwwroot/default#] ls -l /tmp/

总用量 16

-rw-r--r-- 1 root  root   5 4 月  25 22:53 12.txt

-rw-r--r-- 1 root  root   0 4 月  26 23:33 1.log

-rw-r--r-- 1 root  root   0 4 月  26 23:14 21.txt

srw-rw-rw- 1 root  root   0 4 月  28 22:55 am.sock

-rw-r--r-- 1 root  root  26 4 月  26 23:20 ip.list

-rw-r--r-- 1 root  root  41 4 月  26 23:19 list.txt

-rw-r--r-- 1 root  root  92 4 月  28 19:08 membak.txt

srwxrwxrwx 1 mysql mysql  0 4 月  26 23:33 mysql.sock

srw-rw-rw- 1 root  root   0 4 月  28 22:55 php-fcgi.sock

03

查看 memcached 里面有没有 session,访问多几次 aaa.com/session.php 以便能生成更多的 session

这里先把 memcached 的数据导出来,然后查看数据文件,也可以 telnet 进入 memcached 去查询

[root@am-01:~#] curl aaa.com/session.php

1524927962<br><br>1524927962<br><br>jpr0souktgbciddr27vajj97j4

[root@am-01:~#] curl aaa.com/session.php

1524927963<br><br>1524927963<br><br>7lq8jn7qi3d80lg5ttmrbbc2a0

[root@am-01:~#] curl aaa.com/session.php

1524927964<br><br>1524927964<br><br>jmlmala7dprg8h1baqpeaf2kv5

[root@am-01:~#] curl aaa.com/session.php

1524927964<br><br>1524927964<br><br>amq1bkth49fh4fl2iaof9vi391

[root@am-01:~#] curl aaa.com/session.php

1524927965<br><br>1524927965<br><br>a9n4erfbgendft0nv77gvbjel3

[root@am-01:~#] memcached-tool 172.17.1.240:11211 dump > /tmp/data.txt

Dumping memcache contents

  Number of buckets: 1

  Number of items  : 5

Dumping bucket 3 - 5 total items

[root@am-01:~#] cat /tmp/data.txt

add jpr0souktgbciddr27vajj97j4 0 1524929402 37

TEST|i:1524927962;TEST3|i:1524927962;

add a9n4erfbgendft0nv77gvbjel3 0 1524929404 37

TEST|i:1524927965;TEST3|i:1524927965;

add 7lq8jn7qi3d80lg5ttmrbbc2a0 0 1524929403 37

TEST|i:1524927963;TEST3|i:1524927963;

add amq1bkth49fh4fl2iaof9vi391 0 1524929403 37

TEST|i:1524927964;TEST3|i:1524927964;

add jmlmala7dprg8h1baqpeaf2kv5 0 1524929403 37

TEST|i:1524927964;TEST3|i:1524927964;

[root@am-01:~#] telnet 127.0.0.1 11211

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

get a9n4erfbgendft0nv77gvbjel3

VALUE a9n4erfbgendft0nv77gvbjel3 0 37

TEST|i:1524927965;TEST3|i:1524927965;

END

扩展

把 session 存放到 memcached 的三种方式(lamp/lnmp 环境)

01

编辑 php.ini 添加两行(这种方法未必可以)

session.save_handler = memcache

session.save_path = "tcp://172.17.1.240:11211"

02

或者 httpd.conf 中对应的虚拟主机中添加

php_value session.save_handler "memcache" php_value

session.save_path "tcp://172.17.1.240:11211"

03

或者 php-fpm.conf 对应的 pool 中添加

php_value[session.save_handler] = memcache

php_value[session.save_path] = "tcp://172.17.1.240:11211"