Memcached学习使用
Memcached简介
Memcached 是一个高性能的分布式内存对象缓存系统,常用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon)是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

Memcached作为高速运行的分布式缓存服务器具有以下特性:
1、协议简单(通信没有使用xml等格式,而是直接使用文本传输)
2、基于libevent的事件处理
3、内置内存存储方式(数据直接存在内存,这也是它数据无法持久化原因)
4、memcached不互相通信的分布式(它实现分布式是由客户端程序实现的,并不是服务器端实现的。)

Memcached服务器安装和使用
安装步骤
1、下载memcached window版本解压到磁盘路径下
2、以管理员身份进入cmd命令窗口,进入memcached安装路径使用(memcached -d install)命令
3、安装完成之后,可以使用memcached -h 帮助命令来查看所有命令
memcached命令:其实memcached作为一种简单高效的缓存服务器,其核心功能也是非常的简单只有添加、取值、和删除命令
添加命令:set key value(这是简单写法省略了有效时间、扩展信息等元素)
删除命令:delete key
读取命令:
get key
get keys
cas命令:checkd and set(先检查是否存在然后再赋值)
Memcached内存存储和内存管理
Slab Allocation机制:整理内存以便重复使用
Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。
Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合)

Slab Allocation的主要术语
Page:分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。
Chunk:用于缓存记录的内存空间。
Slab Class:特定大小的chunk的组。
在Slab中缓存记录的原理
memcached根据收到的数据的大小,选择最适合数据大小的slab(图2)。 memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk, 然后将数据缓存于其中。

备注:
Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。 例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。
memcached在数据删除方面有效利用资源
Lazy Expiration
memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录
是否过期。 这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。
LRU:从缓存中有效删除数据的原理
Least Recently Used(LRU)机制来分配空间(最近最少使用原则来删除数据)
Memcached分布式算法
memcached虽然称为“分布式”缓存服务器,但服务器端并没有"分布式"功能.
memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。
下面假设memcached服务器有node1~node3三台, 应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据。

实现原理(节点取模算法):
客户端先根据key值计算出hash值,然后使用余数取模算法来决定要存储到那个节点服务器。
假如"tokyo"计算出的hash值为4,4对3(3个节点服务器)取模为1然后客户端就决定将"tokyo"存储到node1节点服务器中。
备注:取模算法存在一个缺点就是,当服务器扩容的时候可能会引起短时间的很多缓存数据失效,即数据震荡。
实现原理(Consistent Hashing算法):
Consistent Hashing如下所示:首先求出memcached服务器(节点)的哈希值, 并将其配置到0~2SUP(32)的圆(continuum)上。 然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。 然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。 如果超过2SUP(32)仍然找不到服务器,就会保存到第一台memcached服务器上。

添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化 而影响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地点逆时针方向的 第一台服务器上的键会受到影响。
使Xmemcached 客户端操作memcached
MemcachedUtils(封装工具类)
memcachedUtils代码
package com.xuyi.maven.learnjavase.memcached;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
public class MemcachedUtils {
/** SLF4J日志对象 */
private static final Logger logger = LoggerFactory.getLogger(MemcachedUtils.class);
/** Memcached Client构造器 */
private static MemcachedClientBuilder memcachedClientBuilder;
/** Memcached Cliend对象 */
private static MemcachedClient memcachedClient;
/** 静态代码块,只初始化一个Memcached Client对象连接。类似JDBC连接 */
static {
memcachedClientBuilder = new XMemcachedClientBuilder("localhost:11211");
// 多地址格式:host1:port host2:port(注意:每个连接服务器之间是有个空格的)
try {
memcachedClient = memcachedClientBuilder.build();
} catch (IOException e) {
logger.error("get memcachedClient fail ", e);
}
}
/**
* 获得一个Memcached Client连接对象
*
* @return MemcachedClient
*/
public static MemcachedClient getMemcachedClient() {
return memcachedClient;
}
}
Xmemcached常用核心方法
Xmemcached添加key-value方法
/**
* 备注:将键值视为java Entry
* @see #add(String, int, Object, Transcoder, long)
* @param key 键
* @param exp 生存时间(单位秒) 备注:如果是0就是持久有效
* @param value 值
* @return
* @throws TimeoutException
* @throws InterruptedException
* @throws MemcachedException
*/
public boolean add(final String key, final int exp, final Object value)
throws TimeoutException, InterruptedException, MemcachedException;
Xmemcached取值方法
public <T> T get(final String key) throws TimeoutException,
InterruptedException, MemcachedException;
public <T> GetsResponse<T> gets(final String key) throws TimeoutException,
InterruptedException, MemcachedException;
备注:gets方法比普通的get方法多返回了一个数字。这个数字可以检查数据是否发生改变。当key对应的数据改变时,这个多返回的数字也会改变。
Xmemcached删除方法
public boolean delete(final String key) throws TimeoutException,
InterruptedException, MemcachedException;
参考
1、https://en.wikipedia.org/wiki/Memcached
2、http://huoding.com/2012/12/30/205
3、http://flychao88.iteye.com/blog/1977653
4、http://snowolf.iteye.com/blog/1447348
5、https://www.ibm.com/developerworks/cn/opensource/os-memcached/
6、https://github.com/killme2008/xmemcached