Memcache

Memcache是一个高性能的分布式的内存对象缓存系统通过在内存里维护一个统一的巨大的hash表它能够用来存储各种格式的数据包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中然后从内存中读取从而大大提高读取速度。
Memcache是danga的一个项目最早是LiveJournal 服务的最初为了加速 LiveJournal 访问速度而开发的后来被很多大型的网站采用。
Memcached是以守护程序方式运行于一个或多个服务器中随时会接收客户端的连接和操作。
2特性和限制
编辑

在 Memcached中可以保存的item数据量是没有限制的只要内存足够 。
  Memcached单进程在32位系统中最大使用内存为2G若在64位系统则没有限制,这是由于32位系统限制单进程最多可使用2G内存,要使用更多内存可以分多个端口开启多个Memcached进程 ,
  最大30天的数据过期时间,设置为永久的也会在这个时间过期常量REALTIME_MAXDELTA 
  60*60*24*30控制 
  最大键长为250字节大于该长度无法存储常量KEY_MAX_LENGTH 250控制 
  单个item最大数据是1MB超过1MB数据不予存储常量POWER_BLOCK 1048576进行控制 
  它是默认的slab大小 
  最大同时连接数是200通过 conn_init()中的freetotal进行控制最大软连接数是1024通过 
  settings.maxconns=1024 进行控制 
  跟空间占用相关的参数settings.factor=1.25, settings.chunk_size=48, 影响slab的数据占用和步进方式
memcached是一种无阻塞的socket通信方式服务基于libevent库由于无阻塞通信对内存读写速度非常之快。
  memcached分服务器端和客户端可以配置多个服务器端和客户端应用于分布式的服务非常广泛。
  memcached作为小规模的数据分布式平台是十分有效果的。
memcached是键值一一对应key默认最大不能超过128个字 节value默认大小是1M也就是一个slabs如果要存2M的值连续的不能用两个slabs因为两个slabs不是连续的无法在内存中 存储故需要修改slabs的大小多个key和value进行存储时即使这个slabs没有利用完那么也不会存放别的数据。
目前memcached支持C/C++、Perl、PHP、Python、Ruby、Java、C#、Postgres、Chicken Scheme、Lua、MySQL和Protocol等语言客户端。
3接口介绍
编辑

Memcache客户端包含两组接口一组是面向过程的接口一组是面向对象的接口具体可以参考PHP手册
MemCache“LXXV. Memcache Functions” 这章。
Memcache面向对象的常用接口包括
Memcache::connect -- 打开一个到Memcache的连接
Memcache::pconnect -- 打开一个到Memcache的长连接
Memcache::close -- 关闭一个Memcache的连接
Memcache::set -- 保存数据到Memcache服务器上
Memcache::get --提取一个保存在Memcache服务器上的数据
Memcache::replace --替换一个已经存在Memcache服务器上的项目功能类似Memcache::set
Memcache::delete -- 从Memcache服务器上删除一个保存的项目
Memcache::flush -- 刷新所有Memcache服务器上保存的项目类似于删除所有的保存的项目
Memcache::getStats -- 获取当前Memcache服务器运行的状态
协议分析

如果你不喜欢 php_memcache.dll 扩展或者服务器目前不支持这个扩展那么就可以考虑自己构建.
Memcahe的客户端要先了解Memcache协议的交互这样才能开发自己的客户端这里简单的分析一下Memcache的协议。更详细的协议内容请在Memcache服务器端的源码的 doc/protocol.txt文件中
Memcache既支持TCP协议也支持UDP协议不过我们这里是以TCP协议的协议作为主要考虑对象想了解UDP协议的过程请参考 doc/protocol.txt文件。
[ 错误指令]
Memcache的协议的错误部分主要是三个错误提示指令
普通错误信息比如指令错误之类的
ERROR
客户端错误
CLIENT_ERROR <错误信息>
服务器端错误
SERVER_ERROR <错误信息>
[ 数据保存指令]
数据保存是基本的功能就是客户端通过命令把数据返回过来服务器端接收后进行处理。
指令格式
<命令> <键> <标记> <有效期> <数据长度>
<命令> - command name
主要是三个储存数据的三个命令 set, add, replace
set 命令是保存一个叫做key的数据到服务器上
add 命令是添加一个数据到服务器但是服务器必须保证这个key是不存在的能够保证数据不会被覆盖
replace 命令是替换一个已经存在的数据如果数据不存在就是类似set功能
<键> - key
就是保存在服务器上唯一的一个表示符必须是跟其他的key不冲突否则会覆盖掉原来的数据这个key是为了能够准确的存取一个数据项目
<标记> - flag
标记是一个16位的无符号整形数据用来设置服务器端跟客户端一些交互的操作
<有效期> - expiration time
是数据在服务器上的有效期限如果是0则数据永远有效单位是秒Memcache服务器端会把一个数据的有效期设置为当前Unix时间+设置的有效时间
<数据长度> - bytes
数据的长度block data 块数据的长度一般在这个个长度结束以后下一行跟着block data数据内容发送完数据以后客户端一般等待服务器端的返回。
数据保存成功
STORED
数据保存失败一般是因为服务器端这个数据key已经存在了
NOT_STORED
[ 数据提取命令]
从服务器端提取数据主要是使用get指令格式是
get <键>*
<键>* -key
key是是一个不为空的字符串组合发送这个指令以后等待服务器的返回。如果服务器端没有任何数据则是返回
END
证明没有不存在这个key没有任何数据如果存在数据则返回指定格式
VALUE <键> <标记> <数据长度>
<数据块>
返回的数据是以VALUE开始的后面跟着key和flags以及数据长度第二行跟着数据块。
<键> -key
是发送过来指令的key内容
<标记> - flags
是调用set指令保存数据时候的flags标记
<数据长度> - bytes
是保存数据时候定位的长度
<数据块> - data block
数据长度下一行就是提取的数据块内容
[ 数据删除指令]
数据删除指令也是比较简单的使用delete指令格式是
delete <键> <超时时间>
<键> - key
key是你希望在服务器上删除数据的key键
<超时时间> - timeout
按照秒为单位这个是个可选项如果你没有指定这个值那么服务器上key数据将马上被删除如果设置了这个值那么数据将在超时时间后把数据清除该项缺省值是0表示永不过期。
删除数据后服务器端会返回
DELETED
删除数据成功
NOT_FOUND
这个key没有在服务器上找到
如果要删除所有服务器上的数据可以使用flush_all指令格式
flush_all
这个指令执行后服务器上所有缓存的数据都被删除并且返回
OK
这个指令一般不要轻易使除非你确实想把所有数据都干掉删除完以后可以无法恢复的。
[其他指令]
如果想了解当前Memcache服务器的状态和版本等信息可以使用状态查询指令和版本查询指令。
如果想了解当前所有Memcache服务器运行的状态信息可以使用stats指令格式
stats
服务器将返回每行按照 STAT开始的状态信息包括20行20项左右的信息包括守护进程的pid、版本、保存的项目数量、内存占用、最大内存限制等等信息。
如果只是想获取部分项目的信息可以指定参数格式
stats <参数>
这个指令将只返回指定参数的项目状态信息。
如果只是想单独了解当前版本信息可以使用version指令格式
version
将返回以 VERSION 开头的版本信息
如果想结束当前连接使用quit指令格式
quit
将断开当前连接
另外还有其他指令包括incr, decr 等我也不太了解作用就不做介绍了如果感兴趣可以自己去研究。
在中型网站中的应用

使用Memcache的网站一般流量都是比较大的为了缓解数据库的压力让Memcache作为一个缓存区域把部分信息保存在内存中在前端能够迅速的进行存取。那么一般的焦点就是集中在如何分担数据库压力和进行分布式毕竟单台Memcache的内存容量的有限的。我这里简单提出我的个人看法未经实践权当参考。
[分布式应用]
Memcache本来支持分布式我们客户端稍加改造更好的支持。我们的key可以适当进行有规律的封装比如以user为主的网站来说每个用户都有UserID那么可以按照固定的ID来进行提取和存取比如1开头的用户保存在第一台Memcache服务器上以2开头的用户的数据保存在第二台Memcache服务器上存取数据都先按照User ID来进行相应的转换和存取。
但是这个有缺点就是需要对User ID进行判断如果业务不一致或者其他类型的应用可能不是那么合适那么可以根据自己的实际业务来进行考虑或者去想更合适的方法。
[ 减少数据库压力]
这个算是比较重要的所有的数据基本上都是保存在数据库当中的每次频繁的存取数据库导致数据库性能急剧下降无法同时服务更多的用户比如MySQL特别频繁的锁表那么让Memcache来分担数据库的压力吧。我们需要一种改动比较小并且能够不会大规模改变前端的方式来进行改变目前的架构。
一个用PHP编写的可视化的MemCached管理系统
MemAdmin是一款可视化的Memcached管理与监控工具使用PHP开发体积小操作简单。
主要功能
服务器参数监控STATS、SETTINGS、ITEMS、SLABS、SIZES实时刷新
服务器性能监控GET、DELETE、INCR、DECR、CAS等常用操作命中率实时监控
支持数据遍历方便对存储内容进行监视
支持条件查询筛选出满足条件的KEY或VALUE
数组、JSON等序列化字符反序列显示
兼容memcache协议的其他服务如Tokyo Tyrant (遍历功能除外)
支持服务器连接池多服务器管理切换方便简洁。

client---------------〉web---------------〉memcache
			------------------〉db

1、检查客户端的请求数据是否在memcached中如有直接把请求数据返回不再对数据库进行任何操作路径操作为①②③⑦。
2、如果请求的数据不在memcached中就去查数据库把从数据库中获取的数据返回给客户端同时把数据缓存一份到memcached中memcached客户端不负责需要程序明确实现路径操作为①②④⑤⑦⑥。
3、每次更新数据库的同时更新memcached中的数据保证一致性。
4、当分配给memcached内存空间用完之后会使用LRULeast Recently Used最近最少使用策略加上到期失效策略失效数据首先被替换然后再替换掉最近未使用的数据。
Memcached特征
协议简单
   它是基于文本行的协议直接通过telnet在memcached服务器上可进行存取数据操作
基于libevent事件处理
    Libevent是一套利用C开发的程序库它将BSD系统的kqueue,Linux系统的epoll等事件处理功能封装成一个接口与传统的select相比提高了性能。
内置的内存管理方式
    所有数据都保存在内存中存取数据比硬盘快当内存满后通过LRU算法自动删除不使用的缓存但没有考虑数据的容灾问题重启服务所有数据会丢失。
分布式
   各个memcached服务器之间互不通信各自独立存取数据不共享任何信息。服务器并不具有分布式功能分布式部署取决于memcache客户端。

命令行直接操作命令

存有六个命令项。
Set添加一个新条目到memcached或是用新的数据替换替换掉已存在的条目 
Add当KEY不存在的情况下它向memcached存数据否则返回NOT_STORED响应 
Replace当KEY存在的情况下它才会向memcached存数据否则返回NOT_STORED响应 
Cas:改变一个存在的KEY值 但它还带了检查的功能 
Append:在这个值后面插入新值 
Prepend:在这个值前面插入新值取有两个命令项
Get:取单个值 从缓存中返回数据时将在第一行得到KEY的名字flag的值和返回的value长度真正的数据在第二行最后返回END如KEY不存在第一行就直接返回END 
Get_multi一次性取多个值










Memcached的内存算法
    Memcached利用slab allocation机制来分配和管理内存它按照预先规定的大小将分配的内存分割成特定长度的内存块再把尺寸相同的内存块分成组数据在存放时根据键值 大小去匹配slab大小找就近的slab存放所以存在空间浪费现象。
    传统的内存管理方式是使用完通过malloc分配的内存后通过free来回收内存这种方式容易产生内存碎片并降低操作系统对内存的管理效率。

Memcached的缓存策略
    Memcached的缓存策略是LRU最近最少使用加上到期失效策略。当你在memcached内存储数据项时你有可能会指定它在缓存的失效时间默认为永久。当memcached服务器用完分配的内时失效的数据被首先替换然后也是最近未使用的数据。在LRU中memcached使用的是一种Lazy Expiration策略自己不会监控存入的key/vlue对是否过期而是在获取key值时查看记录的时间戳检查key/value对空间是否过期这样可减轻服务器的负载。
Memcached的分布式算法
    当向memcached集群存入/取出key/value时memcached客户端程序根据一定的算法计算存入哪台服务器然后再把key/value值存到此服务器中。也就是说存取数据分二步走第一步选择服务器第二步存取数据



分布式算法(Consistent Hashing)
    选择服务器算法有两种一种是根据余数来计算分布另一种是根据散列算法来计算分布。
余数算法
    先求得键的整数散列值再除以服务器台数根据余数确定存取服务器这种方法计算简单高效但在memcached服务器增加或减少时几乎所有的缓存都会失效。
散列算法
    先算出memcached服务器的散列值并将其分布到0到2的32次方的圆上然后用同样的方法算出存储数据的键的散列值并映射至圆上最后从数据映射到的位置开始顺时针查找将数据保存到查找到的第一个服务器上如果超过2的32次方依然找不到服务器就将数据保存到第一台memcached服务器上。如果添加了一台memcached服务器只在圆上增加服务器的逆时针方向的第一台服务器上的键会受到影响。



Memcache的管理与性能监控
可以通过命令行直接管理与监控也可通过nagios,cacti等web软件进行监控
命令行
1.Shell>telnet 127.0.0.1 1211 //如果在启动时指定了IP及端口号这里要作相应改动
连接成功后命令 
2.Stats:统计memcached的各种信息 
3.Stats reset:重新统计数据 
4.Stats slabs显示slabs信息可以详细看到数据的分段存储情况 
5.Stats items显示slab中的item数目 
6.Stats cachedump 1 0列出slabs第一段里存的KEY值 
7.Set|get保存或获取数据 
8.STAT evictions 0表示要腾出新空间给新的item而移动的合法item数目 
其它常用软件使用
1.Shell>./Memcached-tool 127.0.0.1:11211 
2.Shell>./Memcached-tool 127.0.0.1:11211 display 
Web软件
1.Memcache.php 
2.Nagios插件 
3.Cacti模块


你可能感兴趣的:(缓存,存储)