Memcached单机版搭建
Memcached集群版本搭建(包含代理)
Maven依赖
<!--memcached依赖包-->
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>1.3.6</version>
</dependency>
缓存配置类
package com.milla.study.netbase.expert.cache.memcached.config;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
import net.rubyeye.xmemcached.utils.AddrUtil;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
/**
* @Package: com.milla.study.netbase.expert.config.cache.memcached
* @Description: <单机集群等各种配置>
* @Author: milla
* @CreateDate: 2020/07/30 17:27
* @UpdateUser: milla
* @UpdateDate: 2020/07/30 17:27
* @UpdateRemark: <>
* @Version: 1.0
*/
@Configuration
public class MemcachedConfig {
@Bean
@Qualifier("cluster")
public MemcachedClient cluster() throws IOException {
String servers = "192.168.16.37:11211 192.168.16.37:11212 192.168.16.37:11213";
MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil
.getAddresses(servers));
// 默认的客户端计算就是 key的哈希值模以连接数
// KetamaMemcachedSessionLocator 一致性hash算法
builder.setSessionLocator(new KetamaMemcachedSessionLocator());
MemcachedClient client = builder.build();
return client;
}
@Bean
@Qualifier("single")
public MemcachedClient single() throws IOException {
return new XMemcachedClient("192.168.16.37", 11211);
}
@Bean
@Qualifier("proxy")
public MemcachedClient proxy() throws IOException {
return new XMemcachedClient("192.168.16.37", 10010);
}
}
控制类(为了保持连接持久测试)
package com.milla.study.netbase.expert.cache.memcached.controller;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeoutException;
/**
* @Package: com.milla.study.netbase.expert.cache.memcached.controller
* @Description: <>
* @Author: milla
* @CreateDate: 2020/07/30 17:31
* @UpdateUser: milla
* @UpdateDate: 2020/07/30 17:31
* @UpdateRemark: <>
* @Version: 1.0
*/
@RestController
public class MemcachedController {
@Autowired
@Qualifier("single")
MemcachedClient single;
@Autowired
@Qualifier("cluster")
MemcachedClient cluster;
@Autowired
@Qualifier("proxy")
MemcachedClient proxy;
@GetMapping("single/{key}")
public Object single(@PathVariable String key) throws InterruptedException, MemcachedException, TimeoutException {
return single.get(key);
}
@GetMapping("single/{key}/{value}")
public Object singleAdd(@PathVariable String key, @PathVariable String value) throws InterruptedException, MemcachedException, TimeoutException {
return single.set(key, 0, value);
}
@GetMapping("cluster/{key}")
public Object cluster(@PathVariable String key) throws InterruptedException, MemcachedException, TimeoutException {
return cluster.get(key);
}
@GetMapping("cluster/{key}/{value}")
public Object clusterAdd(@PathVariable String key, @PathVariable String value) throws InterruptedException, MemcachedException, TimeoutException {
return cluster.set(key, 0, value);
}
@GetMapping("proxy/{key}")
public Object proxy(@PathVariable String key) throws InterruptedException, MemcachedException, TimeoutException {
return proxy.get(key);
}
@GetMapping("proxy/{key}/{value}")
public Object proxyAdd(@PathVariable String key, @PathVariable String value) throws InterruptedException, MemcachedException, TimeoutException {
return proxy.set(key, 0, value);
}
}
测试结果
- 单机版本 :可添加缓存数据,将缓存服务器杀掉,缓存连接异常,获取不到数据
- 集群版本 :可添加数据,数据随算法缓存到目标服务器,杀掉该服务器后,缓存数据消失,重新添加数据,会存储到其他剩余缓存服务器,杀掉该服务器后,缓存数据仍然丢失,以此逻辑类推直至最后没有服务不再能存储,出现异常
- 集群间不通信,数据并不共享,不做数据备份或主从复制
- 经测试,如集群增加keyA-valueA ,排查数据进入A节点,杀掉A节点后,数据丢失,继续向集群中添加该数据,数据进入其他节点B,从集群获取数据可以获取到,此时恢复A节点,再次获取数据为空(此时B中存在之前的数据),此时再次向集群添加keyA-valueAA(与之前值不通),依然会进入A节点,获取时数据没有问题,但是再次杀掉A节点后,获取数据为B节点的数据———数据一致性
- 代理版本 : //TODO 结果以后补充