小白零基础入门上手memcached
Posted 琉忆编程库
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小白零基础入门上手memcached相关的知识,希望对你有一定的参考价值。
点击蓝字关注这个神奇的编程库~
你好,是我,琉忆。
消失了差不多3个星期的我又回来了,这次回来带着一个我花了2周时间研究+实践应用到工作中的memcache给大家。
1.什么是memcache?
Memcached
是一个开源、免费、高性能的分布式对象缓存系统,通过减少对数据库的读取以提高Web
应用的性能;Memcached
基于一个存储键/值对的hashmap
。其守护进程(daemon
)是用 C 写的,但是客户端可以用任何语言来编写,并通过memcached
协议与守护进程通信。当某个服务器停止运行或崩溃了,所有存放在该服务器上的键/值对都将丢失。
Memcached
的服务器端没有提供分布式功能,各个Memcached
应用不会互相通信以共享信息。想要实现分布式通过,可以多搭建几个Memcached
应用,通过算法实现此效果;
Memcached
里有两个重要概念:
slab
:为了防止内存碎片化,Memcached
服务器端会预先将数据空间划分为一系列slab
;举个例子,现在有一个100立方米的房间,为了合理规划这个房间放置东西,会在这个房间里放置 30 个 1 立方米的盒子、20 个 1.25 立方米的盒子、15 个 1.5 立方米的盒子...这些盒子就是slab
;LRU
:最近最少使用算法;当同一个slat
的格子满了,这时需要新加一个值时,不会考虑将这个新数据放到比当前slat
更大的空闲slat
,而是使用LRU
移除旧数据,放入这个新数据;
2.memcache的特性、应用场景、机制
(1)特性
单个item 最大的数据 1M
单进程最大的使用内存 2G ,需要更多内存时可开多个端口
memcached 是多线程,非阻塞io复用的网络模型,redis 是单线程
键长最大250字节
(2)常见的运用场景
memcached来保持session,实现session共享(session跨服务器的一种解决方案)
memcached可以用于缓存数据减少对数据库的重复请求加载,提高网页的访问速度。
(3)内存管理机制(默认是使用Slab Allocatoion机制分配、管理内存)
将内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合)
page 是分配Slab的内存空间 默认是1M 根据Slab大小切分成chunk
chunk:用户缓存记录的内存空间
Slab class:特定chunk的组
MEMCACHE_COMPRESSED为压缩选项缩后数据一般为原数据大小的30%左右,节省了70%的传输性能消耗所得会大于文件压缩带来的性能损耗;存的数据的确有大于几百字节的,如果都是小于100字节的键值对,压缩可能反而带来膨胀,Memcached中都是按照固定大小分块存储的,最小也要88 B。所以对于过小数据带来的压缩膨胀并不是太大的问题;
3.memcache的存储方式及内容大小
(1)以key-value的方式存储
(2)key可达250B,value可达1M
(3)value是以字符串的形式保存的:
(4)php标量数据类型,保存时会隐式转换为字符串;
(5)php其他数据类型, 保存时自动序列化,取出时自动反序列化. //该过程是php的memcache扩展开启后,底层实现的
(6)item过期时间是时间戳时,无限制;以s为单位时,不能超过30天的秒数
不能持久化,要的就是速度
4.memcache的安装
(1)memcache在linux系统的安装
在linux操作系统下安装2.0.2版本memcached或3.0.3版本的memcache(如果是php7就要安装3.0.3版本的才支持)。
安装教程:linux安装memcached
(2)memcache在windows系统的安装
在windows操作系统下安装的memcache服务器是只能使用memcache类的,而在linux服务器里面安装后使用的是memcached,两个是不同的库,使用方法也不同。个人建议安装memcached,方法更多更方便。
安装教程:windows安装memcache服务
5.memcache的命令使用
(1)get
Memcached get 命令获取存储在 key(键) 中的 value(数据值) ,如果 key 不存在,则返回空。
(2)set
Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中。
如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用。
(3)delete
Memcached delete 命令用于删除已存在的 key(键)。
(4)add
Memcached add 命令用于将 value(数据值) 存储在指定的 key(键) 中。
如果 add 的 key 已经存在,则不会更新数据(过期的 key 会更新),之前的值将仍然保持相同,并且您将获得响应 NOT_STORED。
(5)replace
Memcached replace 命令用于替换已存在的 key(键) 的 value(数据值)。
如果 key 不存在,则替换失败,并且您将获得响应 NOT_STORED。
(6)addServer
用于使用memcache前连接memcache使用。
(7)
stats | 返回MemCache通用统计信息(下面有详细解读) |
stats items | 返回各个slab中item的数目和最老的item的年龄(最后一次访问距离现在的秒数) |
stats slabs | 返回MemCache运行期间创建的每个slab的信息(下面有详细解读) |
version | 返回当前MemCache版本号 |
flush_all | 清空所有键值,但不会删除items,所以此时MemCache依旧占用内存 |
quit | 关闭连接 |
(8)memcached才拥有的命令:
(a)setMulti
批量设置memcached
(b)deleteMulti
批量删除memcached数据
(c)getMulti
批量获取数据
(d)getResultCode
获取执行Memcached返回的编码
(e)getResultMessage
获取memcached的执行编码信息
6.memcached的实践
<?php /*require "memcached/" $m = new Memcached(); $arr = array( array("127.0.0.1",11211), array("127.0.0.2",11211) ); // $m->addServer("127.0.0.1",11211); //单个服务器 $m->addServers($arr);//多个服务器连接 // 获取进程状态 print_r($m->getStatus()); // 获取服务端版本号 print_r($m->getVersion());*/ /* // 添加一个key值 $m->add("mkey","123",600); // 替换key值,没有对应key就报错 $m->replace("mkey","123",600); // 数据不存在就创建,存在就不覆盖 $m->set("mkey","123",600); // 删除数据 $m->delete("mkey"); // 刷新,情况所有键 $m->flush(); // 获取对应key值 $m->get("mkey"); $m->set('num',5,0); $m->increment("num",5);//每次加5 echo $m->get("num"); // 每次减5 $m->decrement("num",5);*/ // 下面是memcached的独有方法 /* setMulti deleteMulti getMulti getResultCode getResultMessage */ // 循环多条数据,一般是: $m->set('n1','m1',0); $m->set('n2','m2',0); $m->set('n3','m3',0); // ->可以改成这样: $data = array( 'key' => 'value', 'key2' => 'value2', 'key3' => 'value3' ); $m->setMulti($data,0); // 一次读取多个的方法 $m->getMulti(array('key','key2','key3')); // 一次删除多条 $m->deleteMulti(array('key','key2')); // 可以获取上一次操作返回的编码 echo $m->getResultCode(); //一个数字存在,返回0表示成功,失败需要看手册 echo $m->getResultMessage();//可以告诉失败的结果信息
7.memcache的命令使用
缓存雪崩现象
缓存雪崩一般是由某个缓存节点失效,导致其他节点的缓存命中率下降,缓存中缺失的数据去数据库查询,短时间内,造成数据库服务器崩溃;
重启DB
,短期又被压垮,但缓存数据也多一些;DB
反复多次启动多次,缓存重建完毕,DB
才稳定运行;或者,是由于缓存周期性的失效,比如每 6 小时失效一次,那么每 6 小时,将有一个请求“峰值”,严重者甚至会令DB崩溃;
缓存的无底洞现象(multiget-hole)
该问题由 facebook
的工作人员提出的, facebook
在 2010 年左右,memcached
节点就已经达3000 个.缓存数千 G 内容。
他们发现了一个问题,memcached
连接频率,效率下降了,于是加 memcached
节点,添加了后,发现因为连接频率导致的问题,仍然存在,并没有好转,称之为“无底洞现象”。
问题分析
以用户为例: user-133-age
, user-133-name
,user-133-height
.....N 个 key,当服务器增多,133 号用户的信息,也被散落在更多的节点,所以,同样是访问个人主页,得到相同的个人信息, 节点越多,要连接的节点也越多。
对于 memcached
的连接数,并没有随着节点的增多,而降低。 于是问题出现。
multiget-hole 解决方案
把某一组key
,按其共同前缀,来分布。比如 user-133-age
, user-133-name
,user-133-height
这 3 个 key,在用分布式算法求其节点时,应该以 ‘user-133
’来计算,而不是以 user-133-age/name/height
来计算。
这样,3 个关于个人信息的 key,都落在同 1 个节点上,访问个人主页时,只需要连接 1 个节点。
永久数据被踢现象
网上有人反馈为"memcached
数据丢失",明明设为永久有效,却莫名其妙的丢失了。
分析原因:
如果
slab
里的很多chunk
,已经过期,但过期后没有被get
过, 系统不知他们已经过期。永久数据很久没
get
了, 不活跃, 如果新增item
,则永久数据被踢了。当然,如果那些非永久数据被
get
,也会被标识为expire
,从而不会再踢掉永久数据;
解决方案:永久数据和非永久数据分开放;
如果觉得好可以分享给更多的人。
谢谢您的支持。
更多精彩内容可关注:shuaiqi100.com【或点击阅读原文】
精品文章推荐
欢
迎
关
注
琉 忆编程库
shuaiqi100.com
长按二维码可关注
点击阅读原文,一起玩耍
以上是关于小白零基础入门上手memcached的主要内容,如果未能解决你的问题,请参考以下文章