您的位置:首页 > 数据库 > Memcache

Memcached 缓存

2016-03-22 10:06 381 查看
Memcached

==================================================================================
http://blog.sina.com.cn/s/blog_493a845501013ei0.html 分布式缓存

1.简介

****************************************************

缓存是一种常驻于内存的内存数据库,内存的读取速度远远快于程序在磁盘读取数据的速度。

将经常访问的数据放到内存上面这样可以提高访问数据的速度,同时可以降低磁盘或数据库的压力。

Memcache优势:

1.实现分布式缓存(支持热部署),通过hashcode根据缓存服务器ip智能分配将数据缓存到服务器上。

2.实现最近最少访问的数据优先被移除缓存。

3.快速找到适配的存储空间,避免内存的浪费。

4.使用键值对存储数据,方便读取、修改等缓存的管理。

5.socket通信,缓存服务器和应用服务器分离。等等

参数说明

------------------------------------------------------------------------------------------------------

memcached -d -m 10 -u root -l 192.168.5.80 -p 11222 -c 256 -P /tmp/memcached.pid

参数说明:

-d选项是启动一个守护进程

-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB

-u是运行Memcache的用户,我这里是root

-l是监听的服务器IP地址

-p是设置Memcache监听的端口,最好是1024以上的端口

-c选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定

-P是设置保存Memcache的pid文件

2.失效策略

****************************************************

memcached的缓存失效策略是LRU(最近最少使用)加上到期失效策略。

当向memcached存储数据时,你可能会设置一个过期时间,可以是永久也可以是一段时间,

但是如果一旦给memcached分配的内存使用完毕,则首先会替换掉已失效的数据,其次是最近最少使用的数据。

*memcached的过期时间并不能随便设置,有一个最大时限就是30天,若超过30天后,存储时返回true,但是在取数据的时候取不到。(在取数据的时候才去做验证,看看数据是否失效)

*通常session的失效算法是“当前时间>=session最后访问时间+失效时间”

*只有在cache值update的时候(set/add/replace)才会更新,仅仅get操作是不会更新这个时间的! 对于失效的cache,严格来说,只有在get操作的时候,才真正回收(可供新的cache使用)

过期时间有两种格式:

1. 相对时间:多长时间,给出过期的时间长度

2. 绝对时间:到期时间,给出过期的最后期限

服务端的处理

时间处理源代码【memcached.c】如下:

#define REALTIME_MAXDELTA 60*60*24*30 // 定义30天的秒数

static rel_time_t realtime(const time_t exptime) {

if (exptime == 0) return 0; //设置为0,永久有效{逃不出LRU}

if (exptime > REALTIME_MAXDELTA) { // 超过30天,是绝对时间

if (exptime <= process_started) // 小于进程启动日期

return (rel_time_t)1; //

return (rel_time_t)(exptime - process_started); // 返回进程启动之后的时间差

} else { // 不超过30天,是相对时间

return (rel_time_t)(exptime + current_time); // exptime + (tvsec - process_started)

}

}

相对时间时,返回的值是:服务器当前时间之后的exptime - process_started秒

绝对时间时,返回的值是:服务器当前时间之后的(exptime -服务器当前时间) - process_started秒

可以看到,如果Client和Server时间不一致,使用绝对时间很容易导致缓存过期。

所以使用相对时间是比较安全的做法。

memcache设置的缓存时间如果超过30天,需要使用 time()+时间;设置为0,永久有效,但是如果内存不够用就LRU了

3.内存管理

****************************************************

Slab Allocatoion分配机制:

Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,已完全解决内存碎片问题。Slab Allocation的原理相当简单。将分配的内存分割成各种尺寸的块(chucnk),并把尺寸相同的块分成组(chucnk的集合)如图:



Slab Allocation 的主要术语

Page :分配给Slab 的内存空间,默认是1MB。分配给Slab 之后根据slab 的大小切分成chunk.

Chunk : 用于缓存记录的内存空间。

Slab Class:特定大小的chunk 的组。

Memcached服务器端保存着一个空闲的内存块列表,当有数据存入时根据接收到的数据大小,分配一个能存下这个数据的最小内存块。这种方式也会造成内存浪费,例如:将一个200字节的数据存入一个300字节的内存块中,会有100字节内存被浪费掉,不能使用。

在启动时指定“-f”参数,能在某种程度上控制内存组之间的大小差异。默认大小为1.25。

4.分布式

****************************************************

Memcached不互通信的分布式:memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。他的分布式主要是通过客户端实现的。

http://blog.csdn.net/u010558660/article/details/52767218 一致性hash算法与Java实现

==================================================================================

Java MemcachedClient

出处: http://hitery.iteye.com/blog/734639
2,incr,decr,counter方法没有过期时间参数

这使得用memcached无法保持那种需要具有实效的计数器。

某些场合,譬如记录用户的错误登录次数,我需要隔断时间就清零,danga限制我这么干。

当然,我们可以用set先存储一个Long值来绕过这个限制,但这会同时带来另一个问题:默认的MemcachedClient在序列化基本数据类型时用了特殊的格式

(NativeHandler,带来的问题就是存储的数据只能由java client来解析),因此数字在memcached服务器中无法使用incr,decr命令。

看了源码,我发现memcachedclient有个属性primitiveAsString可以控制这个序列化选择。万幸,把它设为true,我绕过去了。

官方网站推荐用spymemcached作为客户端。

-------------------------------------------------------------------------------------------------------------------

问题

MemcachedClient--Builderbuilder=new XMemcachedClientBuilder(AddrUtil.getAddresses("ip:11211"));

builder.setConnectionPoolSize(5);

MemcachedClient mClient = builder.build();

mClient.setPrimitiveAsString(true);

mClient.set("key", 5, 6); //参数:key,expDate,value

mClient.incr("key", 2); //参数:key,增值

//如果不设置mClient.setPrimitiveAsString(true);会报异常

//Exception: cannot increment or decrement non-numeric value
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息