memcached安装及配置

一、memcached介绍

Memcached是国外社区网站LiveJournal团队开发的,高性能分布式内存缓存服务器,其目的是为了通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。

  • 数据结构简单(key-value),数据存放在内存里,不支持持久化
  • 多线程
  • 基于c/s架构,协议简单
  • 基于libevent的事件处理
  • 自主内存存储处理(slab allowcation)
  • 数据过期方式:Lazy Expiration 和 LRU

二、Memcached的数据流向

  1. web从DB上获取到查询结果
  2. 把结果存储到memcached中
  3. 再次用到该结果,从缓存中读取

三、Slab Allocation的原理

Slab Allocation机制:整理内存以便重复使用。
在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。 但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。
Slab Allocation的原理相当简单。将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合)。而且,slab allocator还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复利用。
每个chunk集合被称为slab。
Memcached的内存分配以Page为单位,Page默认值为1M,可以在启动时通过-I参数来指定。
Slab是由多个Page组成的,Page按照指定大小切割成多个chunk。

四、Growth factor

增长因子,Memcached在启动时通过-f选项可以指定 Growth Factor因子。该值控制chunk大小的差异,默认值为1.25。
通过memcached-tool命令查看指定Memcached实例的不同slab状态,可以看到各Item所占大小(chunk大小)差距为1.25。

五、Memcached的数据过期方式

1. Lazy Expiration

Memcached 内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期,这种技术被称为lazy(惰性)expiration。因此,Memcached不会在过期监视上耗费CPU时间。

2. LRU

Memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当内存空间不足时(无法从slab class获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。

六、Memcached的安装

memcached安装与一般应用程序相同,configure、make、make install就行了。
当然也可以使用安装系统包含的rpm包,虽然这个包的版本可能会有些老旧。

yum install -y memcached libmemcached libevent

默认启动:

systemctl start memcached

以及手动启动,可以定义参数:

/usr/bin/memcached -u memcached -p 11211 -m 64 -c 最大并发数

选项说明:

  • -u 指定运行的用户
  • -p 使用的TCP端口。默认为11211
  • -m 最大内存大小。默认为64M
  • -vv 用very vrebose模式启动,调试信息和错误输出到控制台
  • -d 作为daemon在后台启动

还可以在/etc/sysconfig/memcached文件中修改配置参数,以便在默认启动的时候,指定监听端口、内存、最大连接数以及监听主机。

七、查看服务状态

在memcached中,运行state命令可以查看memcached服务的状态信息。
使用memcached-tool工具查看:

memcached-tool 127.0.0.1:11211 stats
#127.0.0.1:11211   Field       Value
         accepting_conns           1
               auth_cmds           0
             auth_errors           0
                   bytes           0
              bytes_read          20
           bytes_written        2052
              cas_badval           0
                cas_hits           0
              cas_misses           0
               cmd_flush           0
                 cmd_get           0
                 cmd_set           0
               cmd_touch           0
             conn_yields           0
   connection_structures          11
        curr_connections          10
              curr_items           0
               decr_hits           0
             decr_misses           0
             delete_hits           0
           delete_misses           0
       evicted_unfetched           0
               evictions           0
       expired_unfetched           0
                get_hits           0
              get_misses           0
              hash_bytes      524288
       hash_is_expanding           0
        hash_power_level          16
               incr_hits           0
             incr_misses           0
                libevent 2.0.21-stable
          limit_maxbytes    67108864
     listen_disabled_num           0
                     pid        3051
            pointer_size          64
               reclaimed           0
            reserved_fds          20
           rusage_system    0.032412
             rusage_user    0.064825
                 threads           4
                    time  1523207503
       total_connections          14
             total_items           0
              touch_hits           0
            touch_misses           0
                  uptime        2088
                 version      1.4.15

其中cmd_get表示总的get次数,get_hits表示get的总命中次数,命中率 = get_hits/cmd_get。
get_hits是一个历史数据,curr_items是当前存储的数据。
get_hits/curr_items=命中率(实际访问成功)

还有其它两种命令也可以查看:

# 需要安装nmap-ncat(yum install nc)
echo stats |nc 127.0.0.1 11211

如果安装了libmemcached这个面向C/C++语言的客户端库,就会安装memstat这个命令。使用方法很简单,可以用更少的步骤获得与telnet相同的信息,还能一次性从多台服务器获得信息。

memstat --servers=127.0.0.1:11211

八、Memcached命令行

可以使用telnet工具进入memcached:

telnet 127.0.0.1 11211

# memcached的基本语法格式:
# <command name> <key> <flags> <exptime> <bytes>
# <data block>

# 设置
set key2 0 30 2
ab
STORED
  • (set、add、replace) set表示按照相应的存储该数据,没有的时候增加,有的时候覆盖;add表示按照相应的添加该数据,但是如果该已经存在则会操作失败;replace表示按照相应的替换数据,但是如果该不存在则操作失败。
  • 客户端需要保存数据的key;
  • 是一个16位的无符号的整数(以十进制的方式表示)。该标志将和需要存储的数据一起存储,并在客户端get数据时返回。客户端可以将此标志用做特殊用途,此标志对服务器来说是不透明的;
  • 为过期的时间,若为0表示存储的数据永远不过期(但可被服务器算法:LRU 等替换)。如果非0(unix时间或者距离此时的秒数),当过期后,服务器可以保证用户得不到该数据(以服务器时间为标准)。
  • 需要存储的字节数,当用户希望存储空数据时可以为0;
  • 需要存储的内容,输入完成后,最后客户端需要加上\r\n(直接点击Enter)作为结束标志。

获取

get key2
VALUE key2 0 2
ab
END

九、Memcached数据导出和导入

因为memcached的数据结构原因,memcached服务器在重启的时候,需要提前备份数据,不然会造成数据丢失。
导出:

memcached-tool 127.0.0.1:11211 dump > data.txt

导入:

nc 127.0.0.1 11211 < data.txt
# 若nc命令不存在,yum install nc

注意:
导出的数据是带有一个时间戳的,这个时间戳就是该条数据过期的时间点,如果当前时间已经超过该时间戳,那么是导入不进去的;
如果过期时间设置为零,那么在数据导出的时候服务会自动标记时间戳,再次导入之后便会过期,无法导入。

十、memcached连接PHP

PHP 有两个 Memcached 客户端:“PHP Memcache 扩展” 和 “PHP Memcached 扩展”,这就是是我们搞混的地方。其中memcache最早是在2004年2月开发的,最后更新是在2013年4月,而 memcached 最早是在2009年1月开发的,最后更新是在2014年1月更新的,所以一些老的代码可能还在用memcache扩展。memcached后来出现,并且大部分框架都支持memcached,现在相对较流行。

1. memcached模块

首先是memcached模块,目前这模块的pecl版本不支持php7,好在经过寻找,在GitHub社区找到了它的分支。在安装它之前需要先安装libmemcached,而且对版本也是有要求,建议安装最新的1.0.18,否则会出现如下错误:

checking for libmemcached location... configure: error: memcached support requires libmemcached. Use --with-libmemcached-dir=<DIR> to specify the prefix where libmemcached headers and library are located
ERROR: `/var/tmp/memcached/configure --with-libmemcached-dir=no' failed

libmemcached的安装过程如下:

cd /usr/local/src
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar zxf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure
make && make install

其次安装php-memcached-3.0.4:

cd /usr/local/src/php-7.1.6/ext/
wget https://github.com/php-memcached-dev/php-memcached/archive/v3.0.4.tar.gz
tar zxf v3.0.4.tar.gz
cd php-memcached-3.0.4
/usr/local/php7/bin/phpize
./configure --with-php-config=/usr/local/php7/bin/php-config 

这里可能会报错:

configure: error: no, sasl.h is not available. Run configure with --disable-memcached-sasl to disable this check

再次配置编译参数:

./configure --with-php-config=/usr/local/php7/bin/php-config --disable-memcached-sasl
# 编译安装:
make && make install
# 返回如下信息说明安装成功
Installing shared extensions:     /usr/local/php7/lib/php/extensions/no-debug-zts-20160303/

查看这个目录即可看到该模块已经添加进去

ls /usr/local/php7/lib/php/extensions/no-debug-zts-20160303/
memcached.so

然后在PHP的配置文件中添加这样一条,重启httpd即可

extension = "memcached.so"

2. memcache模块

在根据php官网给出的地址安装memcache最新版本的时候,make后报错:

/usr/local/src/memcache-2.2.3/memcache.c:40:40: fatal error: ext/standard/php_smart_str.sh: No such file or directory
#include "ext/standard/php_smart_str.h"

php_smart_str.h是给字符串预处理动态申请内存空间,类似于操作系统中内存以页为单位分配,它的好处是对齐内存地址,提高访问速度。
而在PHP7版本中,已经把此文件升级为php_smart_string.h,好在memcached后续版本已经更上php7的脚步,开发出了pecl-memcache,其源码发布在GitHub社区:

cd /usr/local/src/php-7.1.6/ext/
git clone https://github.com/websupport-sk/pecl-memcache.git
cd pecl-memcache
/usr/local/php7/bin/phpize
./configure --with-php-config=/usr/local/php7/bin/php-config
make && make install

然后也是在php.ini配置文件中加入:

extension = "memcache.so"

标签: NoSQL

添加新评论