介绍
官网介绍:memcached是一个高性能的分布式内存对象缓存系统。
简单来说memcached可以将你多台服务器的内存合并成一块内存,将这一整快合并后的内容维护成一个大大的hash表(key-value形式存内容),通过一致性Hash和虚拟节点来存,断电或重启服务时数据丢失。
内存合并
官网提供了如下的图,介绍了在分布式场景下的Memcached如何合并这些内存容量,每台服务器作为一个节点来接入。
存储格式
以key-value的方式进行存储,没有任何数据结构可言,所以value存图片或视频等等任何内容都可以,但值有大小限制默认1M,Key 字符串的长度不能超过 255 个字符。修改方式如下:
memcached -I 128k # Refuse items larger than 128k.
memcached -I 10m # Allow objects up to 10MB
存储方式
Slab:用于表示存储的最大size数据,仅仅只是用于定义(通俗的讲就是表示可以存储数据大小的范围)。默认情况下,前后两个slab表示存储的size以1.25倍进行增长。例如slab1为96字节,slab2为120字节
Page:分配给Slab的内存空间,默认为1MB。分给Slab后将会根据slab的大小切割成chunk
Chunk:用于缓存记录的内存空间
Slab calss:特定大小的Chunk集合
删除策略
Memcached采用的是LRU,但MemCache的LRU算法不是针对全局的,是针对slab的。
存储过程
通过一致性hash加虚拟节点,这方面有很多文章可以可以查看。
存储机制
Memcache 是 Slab Allocator 的方式存数据,好处就是解决了内存碎片可重复使用。Slab Allocator结合上面的存储方式以page为单位分为chunk,把一样大小的chunk分为一组,在存数据的时候会找与对应数据差不多的chunk进行存。这样大大减少了内存碎片的产生,但可能存在chunk比如有100k,实际数据为90k,那剩余10k就浪费掉了。
Java代码演示
<!-- https://mvnrepository.com/artifact/net.spy/spymemcached -->
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.3</version>
</dependency>
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.MemcachedClientIF;
public class MemcachedDemo {
public static void main(String[] args) {
try {
// 新增Memcached客户端
MemcachedClientIF memcachedClient = new MemcachedClient(AddrUtil.getAddresses("127.0.0.1:11211"));
String key = "key";
int expiryTime = 60; // 过期时间,单位:秒
String value = "Hello, shiwu!";
// 存数据指定过期时间
memcachedClient.set(key, expiryTime, value);
// 获取数据
Object cachedValue = memcachedClient.get(key);
if (cachedValue != null) {
System.out.println("value: " + cachedValue);
} else {
System.out.println("value 404");
}
// 关闭Memcached客户端
memcachedClient.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}