memcached基础总结

概述
memecached内存缓存软件,协议简单,基于libevent事件处理,内置内存存储方式,采用不互相通信的分布式;
安装memcached
yum -y install libevent libevent-devel安装libevent libevent-devel

wget http://memcached.org/files/memcached-1.4.33.tar.gz
tar 
cd memcached-1.x.x
./configure --prefix=/usr/local/memcached
make && make test &&  make install
安装memcache扩展
wget http://pecl.php.net/get/memcache-2.2.7.tgz
tar -zxvf memcache-2.2.7.tgz 
/usr/local/php/bin/phpize 
./configure --with-php-config=/usr/local/php/bin/php-config 
 make && make install
启动和参数说明
/usr/local/memcached/bin/memcached 
-p port:监听端口tcp port number,TCP端口
-m num:单个数据项最大可用内存,MB为单位,默认64M;(占用机器内存)
-u num:udp port端口udp端口监听。
-a <mask>:支持mask 0700
-d start :告诉memcached启动
-d restart:告诉启动memcached重启
-d stop|shutdown:启动memcached关闭
-d install:安装memcached服务;
-d uninstall:取消安装memcached服务
-r :最大核心文件限制
-u <username>:用什么身份启动
-c <num>:最大的连接数。
-v :输出错误信息;
-vv:输出所有的信息。
-vvv:超详细的所有信息
-h:打印帮助和退出。
-i:打印memcached和libevent license;
-p <file>:保存pid到文件。
-f <factor>:增长因子,默认1.25;
-n <bytes>:最小的空间分配给key-value,默认48;
-l <ip_addr>  监听的IP地址。(默认:INADDR_ANY,所有地址)  
连接
memcache客户端与服务器通信比较简单,使用基于文本的协议,而不是二进制协议;
可以通过telnet与memcached做交互;
telnet 127.0.0.1 11211 ctrl+]
命令
hash哈希:碰撞要低。
    某个范围内,随机出一个hash值,放到相关的内存地址;
    取出数据的时候,根据hash值来获取数据的内存地址取得地址;
新增add
add key flag expire length 回车
add name 1 30 3
lin
STORED
get name
VALUE name 1 3
lin
END
key:唯一键值;flag:标志,要求一个正整数。
expire:有效期;length:缓存长度字节单位;
flag:标志:标识存储数据的格式类型;比如:1-字符串,2-反转成数组,3,反序列对象等。
expire:设置秒数;时间戳(到某个点);设为0不失效;
默认memcache最长常量为30天。可能等不到30天,数据也可能会被挤出去;
老数据有可能被踢
读取数据get
get key:返回某个key值
删除delete
delete key
删除指定的key;
替换replace
replace key flag expire length
参数和add一样,修改某个key的值;
只能对已经存在的键进行修改
replace age 0 0 9
linjunbin
STORED
get age
VALUE age 0 9
linjunbin
END
设置和修改值set
参数和add,replace一样,功能有所区别,如果key存在则修改,不存在则添加。
incr,decr命令:增加/减少值的大小
incr/decr key num

注意:incr,decr操作是把32位无符号来+-操作,值在0-2的32次方范围内。
秒杀场景。每进来一个用户就新增1,直到进来达到限制数其他的直接拒绝静态页。

统计stats
stats
STAT pid 15992                      :进程号
STAT uptime 3289                    :运行的时间
STAT time 1485095107                :当前时间戳
STAT version 1.4.13                 :当前版本
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT curr_connections 11            :当前有几个连接
STAT total_connections 13           :总共连接几个
STAT connection_structures 12
STAT reserved_fds 20
STAT cmd_get 10                     :查询次数
STAT cmd_set 7                      :
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 8                     :获取成功次数
STAT get_misses 2       :失败的次数,获取不到值;可以计算缓存命中率
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 541
STAT bytes_written 667
STAT limit_maxbytes 268435456
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT bytes 222
STAT curr_items 3                   :当前几个key值
STAT total_items 6                  :自动启动起来存储的几个值
STAT evictions 0
STAT reclaimed 1
END
flush_all清空所有的存储对象
flush_all
memcached内存管理和删除机制

C语言:使用malloc,free来向操作系统申请和释放内存。

内存碎片化:在不断的申请和释放过程中,形成了一些很小的内存片段,无法再利用

slab allocator缓存内存碎片化

memcached用slab allocator机制来管理内存。

slab allocator原理:预告把内存划分成数个slab class仓库(每个slab clas大小1M)各个仓库切分成不同尺寸的小块(chunk);需要存内容的时候,判断内容大小,为其选择合理的仓库;

1M slab class = 4 byte (chunk) * 1000 * 250;

将尺寸相同的chunk放在同一组class;

关联参数:增长因子,表示chunk之间间隔倍数1.25默认。这个参数可以调整
系统选择合适的chunk

数据存储:chunk为固定大小,造成浪费这个问题,不能克服,只能缓解;根据要存入数据的大小来选择不同空闲chunk来存储。

注意:如果有100byte的内容要存,可是122大小的仓库中没有空闲的chunk满了,
      是不会寻找更大规格chunk来存(144),而是把122byte仓库的旧数据踢掉。
      LRU:删除机制less recently use
      过期机制与删除机制
固定大小chunk带来的内存浪费

比如存储100byte数据到122chunk中,无疑浪费了22byte就浪费了,无法彻底解决,只能缓解问题。

注意:开发者可以对网站缓存中的item长度进行统计,并制定合理的slab class中的chunk大小。通过增长因子调整。
-m 64 -p 11211 -vvv -f 增长因子
grow factor调优
默认值1.25倍数。使用-f参数进行调整。
注意:当f=1.25时,从输出结果来看,某些相邻slab class大小比值并非1.25,这些误差为了保持字节数对齐而故意调整的。
memcached的过期数据惰性删除
当某个值过期后,并没有从内存删除,因此,stats统计时,curr_item有其信息;
当某个新值去占用她的位置时,当成空chunk来占用。
当get值时,判断是否过期,如果过期返回空,并且清空,curr_item就减少了。
惰性删除:减少cpu时间和检测成本;
memcached此处用的LRU删除机制
如果122byte大小的chunk都满了,要插入新的值120byte,会挤掉122bytechunk里面的值;
memcached用的LRU删除机制,最近最少使用;least recently used;
当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用。

注意:即使key设置了永久有效也会被踢出;

memcached中的一些参数限制
key长度:250 btye(二进制协议支持65535个字节)
value的限制1M,一般都是存储一些文本,
内存的限制:32位下最大设置2G

如果有30G数据要缓存,一般不会单实例装30G,一般建议开启多个实例,不同服务器端口,或者不同机器;

深入理解memcache

支持高并发
memcached使用多路复用I/O模型epoll,select等。多路复用I/O是一种消息通知模式。
用户连接好I/O准备后,系统会通知我们这个连接可以进行I/O操作,不会阻塞在某个用户连接。
所以,memcached能支持高并发;
-t:参数表示支持线程数,并非线程数越多越好,一般设置为CPU核数,这样效率最高。
线程数越多系统需要县城调度时间就越多,而把线程数设置成CPU核数,系统需要的线程调度时间最少。
使用slab分配算法保存数据
memecache默认只能存储不大于1M的数据(修改源码可以存多1m,把power_block宏设置更大数)
使用Slab分配算法,把固定大小1M内存块分成N小块;
(具体后续查看分析源码)
删除过期item
memcache为每个item设置一个过期时间,并非过期就删除,而是访问时过期数据才删除。懒删除机制;
memcached多线程模型
memcached是一个多线程缓存服务器程序,线程分为:
1、主线程:接收客户端连接,并把连接分配给工作线程处理。
2、工作线程:worker thread,处理客户端连接请求。

主线程accept函数接收到来的连接,把连接push工作线程的CQ队列中,并向工作线程发送一个信号,通知工作线程有新的客户端连接需要处理。
当工作线程接收到主线程信号,便会把CQ队列上的客户端连接注册到libevent进行侦听,
libevent会侦听客户端连接的读写时间,并调用相关的回调函数drive_machine进行处理。
示例-小试牛刀
<?php
$mc = new Memcache();
$mc->connect('127.0.0.1', '11211');//连接mamcache服务器
$val = $mc->get('name');
if(empty($val)) {
    $mc->set('name', 'linjunbin', 0, 10);//缓存数据
}else{
    $mc->delete('name');//删除数据
}
$mc->close();//断开连接
PHP扩展访问memecached服务器
connect():返回bool类型连接单个服务器
    host:服务器域名或者IP
    port:服务器TCP端口,默认11211
    timeout:连接持续超时时间,默认值1s,过长的连续持续时间可能导致失去所有的缓存优势。
addServer():用于向对象添加一个服务器;

注意:addserver()没有连接到服务器动作,所以在memcached进程没有启动时候,执行addserver成功也会返回true;

bool Memcache:addServer( host,int port[,bool persistent,int weight, int timeout,int retry_interval, bool status,callback failure_callback])

persistent:是否使用常连接,默认为true;
weight:权重,在多个服务器设置中占得比例;
timeout:连接memcached服务器失效的秒数
retry_interval:服务器连接失败的重试平率,默认是15S一次,设置-1为自动重试
status:控制服务器是否被标记为online,
fail_callback:失败时候的回调函数,函数的两个参数失败服务器hostname和port
//示例
    foreach ((array) $hosts as $i => $host) {
            $port = isset($ports[$i]) ? $ports[$i] : $ports[0];
            $this->options['timeout'] > 0 ?$this->handler->addServer($host, $port, $this->options['persistent'], 1, $this->options['timeout']) :$this->handler->addServer($host, $port, $this->options['persistent'], 1);
        }
memcache:getServerStatus:用于获取一个服务器在线或者离线状态。
int Memcache::getServerStatus(string $host, int $port);
0:表示服务器离线,非0:表示服务器在线;

getStats:用于获取服务器的统计信息。返回一个关联数组统计信息;
array Memcache::getStats(string $type, int $slabid, int $limit)
type:期望统计的信息类型,reset,malloc,maps等。
slabid:与type参数联合指定slab分块拷贝数据;
limit:从服务器获取的实体条数;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值