SpringBoot 精通系列-SpringBoot如何操作Memcache
导语
随着公司的业务速度的提高,数据持久化的问题就凸显出来,很多的场景下使用的是缓存技术来解决请求数据库的压力,这种也是缓存技术使用最多的场景之一,当然在高并发、分布式Session场景下,也会使用缓存技术来提高系统的可用性。在工作中比较常用的是Redis,当然在有些场景下使用的是Memcache。这里首先来介绍一下关于Memcache 的使用
文章目录
- Memcache介绍
- Memcache 特点
- 协议简单
- 基于Libevent的事件处理机制
- 内置的内存存储方式
- 不适用场景列举
- Memcache 安装
- 快速开始
- 1. 增加依赖管理
- 2.添加配置文件
- 3.注入组件
- 4.编写配置文件
- 5.编写测试类
- 总结
Memcache介绍
首先来说Memcache是一个开源高性能的分布式内存对象key-value缓存系统,用于加速动态的Web应用,从而减轻数据库的负载能力,在工作场景中很多人把它当做一个内存式的数据库在使用。那么内存式到底是什么呢?我们都知道,在计算机主要靠CPU来进行计算,内存用来存储CPU操作的数据。在计算机硬件中还有一个叫做硬盘的东西。那么这三者之间是怎么交互的。首先要知道计算机内存式有限的,这个是不可否认的,其次CPU的计算速度与内存以及外部存储之间是存在一定的差距的,所以就使用了一种高速缓存Cache的技术。来匹配内存与CPU之间的速度不匹配的问题。也就是说在计算机中能跟内存挂钩的都是速度比较搞的。Memcache被称为是内存式的缓存,那么它的效率一定是毋庸置疑。
它可以应对任意多个连接,使用非阻塞的网络IO,由于它的工作机制就是跟上面说的一样是直接操作内存,在内存中开辟的空间,然后建立Hash表,并且有Memcache自己来管理这些Hash表,这样的方式来进行缓存操作,再加上非阻塞的IO。执行的效率上要比一般的缓冲设计结构更高效。
Memcache 特点
协议简单
Memcache在服务端和客户端之间的通信中采用的是最为简单的文本协议,可以通过Telnet就可以在Memcache上存取数据。
基于Libevent的事件处理机制
Libevent是一套跨平台的事件处理接口的封装。首先要知道在不同操作系统中对于事件的操作是不一样的,例如在不同的Linux版本中操作IO事件有poll、epoll。在Windows中的select。当然在低版本的Linux中也有使用select的。那么这些在不同平台上的IO事件处理,在Memcache中都得到了解决,使用Libevent进行网络并发连接的处理,能够保证在高并发的情况下,任然可以保持快速响应的能力。
内置的内存存储方式
之前提到的Memcache中保存的数据都存储在Memcache内置的内存空间中,由于数据存储在内存中,所以当出现宕机或者是出现重启的时候就会导致内存中的数据丢失,都知道内存中的数据并不是持久化存储的。Memcache LRU(Least Recently Used)算法自动删除不使用的缓存,不过这个功能是可以进行配置的,Memcache通过启动“-M”参数可以禁止LRU,当是为了高效实用建议不要禁用。
不适用场景列举
- 缓存对象不能大于1MB,毕竟操作的是内存太大的话会导致内存消耗加速
- key 的长度大于250字符,还是上面的原因
- Memcache 未提供任何的安全策略,也就是说有些数据可以这里获取
- 不支持持久化,因为操作的是内存。
Memcache 安装
这里介绍的是在Ubuntu下的安装。
安装Memcache服务端
sudo apt-get install memcached
root@nihui-PC:~# apt-get install memcached
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
建议安装:libcache-memcached-perl libmemcached libanyevent-perl libyaml-perl libterm-readkey-perl
下列【新】软件包将被安装:memcached
升级了 0 个软件包,新安装了 1 个软件包,要卸载 0 个软件包,有 184 个软件包未被升级。
需要下载 122 kB 的归档。
解压缩后会消耗 295 kB 的额外空间。
获取:1 http://packages.deepin.com/deepin panda/main amd64 memcached amd64 1.5.6-1 [122 kB]
已下载 122 kB,耗时 0秒 (277 kB/s)
正在选中未选择的软件包 memcached。
(正在读取数据库 ... 系统当前共安装有 192272 个文件和目录。)
正准备解包 .../memcached_1.5.6-1_amd64.deb ...
正在解包 memcached (1.5.6-1) ...
正在设置 memcached (1.5.6-1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /lib/systemd/system/memcached.service.
正在处理用于 systemd (238-5) 的触发器 ...
正在处理用于 man-db (2.8.3-2) 的触发器 ...
安装完Memcache服务端以后,我们需要启动该服务:
memcached -d -m 128 -p 11111 -u root
这里需要说明一下memcached服务的启动参数:
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
root@nihui-PC:~# memcached -d -m 128 -p 11111 -u root
root@nihui-PC:~#
root@nihui-PC:~# ps -ef|grep memcache
memcache 5395 1 0 12:07 ? 00:00:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -P /var/run/memcached/memcached.pid
root 6272 1 0 12:09 ? 00:00:00 memcached -d -m 128 -p 11111 -u root
root 6621 3648 0 12:11 pts/1 00:00:00 grep memcache
root@nihui-PC:~#
会发现其中启动了两个 Memcache实例,其中一个是使用上面的命令启动的,一个是默认启动的。
Memcache客户端
Memcache Clinet 目前支持3种。
- Memcached Client for Java停止更新
- SpyMemcached 停止更新
- XMemcached 主流
XMemcached介绍
是使用最为广泛的Memcache Java客户端,是一个全新的 Java Memcache Client。Memcache 通过它自定义协议与客户端交互,而XMemcached就是它的Java客户端实现,相比较于其他客户端来说XMemcached 的优点如下
XMemcached主要特性
XMemcached 支持设置连接池、宕机报警、使用二进制文件、一致性Hash、进行数据压缩等操作,总结下来有以下一些点
- 性能优势,使用的NIO
- 协议支持广泛
- 支持客户端分布,提供了一致性Hash 实现
- 允许设置节点权重,XMemcached允许通过设置节点的权重来调节Memcached的负载,设置的权重越高,该Memcached节点存储的数据就越多,所要承受的负载越大
- 动态的增删节点,Memcached允许通过JMX或者代码编程来实现节点的动态的添加或者删除操作。方便扩展或者替换节点。
- XMemcached 通过 JMX 暴露的一些接口,支持Client本身的监控和调整,允许动态设置调优参数、查看统计数据、动态增删节点等;
- 支持链接池操作。
- 可扩展性强,XMemcached是基于Java NIO框架 Yanf4j 来实现的,所以在结构上相对清晰,分层明确。
快速开始
上的内容都是用来给大家做铺垫的,下面才是真正的干货。首先先来感受一下SpringBoot是怎么集成Memcache。
1. 增加依赖管理
添加关于memcache的依赖
<!-- https://mvnrepository.com/artifact/com.googlecode.xmemcached/xmemcached --><dependency><groupId>com.googlecode.xmemcached</groupId><artifactId>xmemcached</artifactId><version>2.4.5</version></dependency>
详细配置如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.nh.memcache</groupId><artifactId>memcache</artifactId><version>0.0.1-SNAPSHOT</version><name>memcache</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!-- https://mvnrepository.com/artifact/com.googlecode.xmemcached/xmemcached --><dependency><groupId>com.googlecode.xmemcached</groupId><artifactId>xmemcached</artifactId><version>2.4.5</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2.添加配置文件
当然在添加配置文件的时候,SpringBoot默认没有支持自动配置所以需要使用SpringBoot提供的配置文件机制来编写自己的配置文件。
首先编写一个配置文件的Properties对象用来与配置文件进行映射
/*** @Classname XMemcachedProperties* @Description TODO* @Date 2019/9/21 12:41 PM* @Created by nihui*/
@Component
@ConfigurationProperties(prefix = "memcached")
public class XMemcachedProperties {private String servers;private int poolSize;private long opTimeout;public String getServers() {return servers;}public void setServers(String servers) {this.servers = servers;}public int getPoolSize() {return poolSize;}public void setPoolSize(int poolSize) {this.poolSize = poolSize;}public long getOpTimeout() {return opTimeout;}public void setOpTimeout(long opTimeout) {this.opTimeout = opTimeout;}
}
编写Memcache的配置类使用@Configration注解进行标注表明这个是一个配置类
/*** @Classname MemcachedBuilder* @Description TODO* @Date 2019/9/21 12:44 PM* @Created by nihui*/
@Configuration
public class MemcachedBuilder {protected static Logger logger = LoggerFactory.getLogger(MemcachedBuilder.class);@Resourceprivate XMemcachedProperties xMemcachedProperties;@Beanpublic MemcachedClient getMemcachedClinet(){MemcachedClient memcachedClient = null;try {MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(xMemcachedProperties.getServers()));builder.setConnectionPoolSize(xMemcachedProperties.getPoolSize());builder.setOpTimeout(xMemcachedProperties.getOpTimeout());memcachedClient = builder.build();}catch (IOException e){logger.error("init MemcachedClient failed"+e);}return memcachedClient;}
}
3.注入组件
如上代码在配置类中注入一个MemcacheClient的Bean对象,并且设置了一些基本的参数,而这些参数都是由配置文件来提供
@Beanpublic MemcachedClient getMemcachedClinet(){MemcachedClient memcachedClient = null;try {MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(xMemcachedProperties.getServers()));builder.setConnectionPoolSize(xMemcachedProperties.getPoolSize());builder.setOpTimeout(xMemcachedProperties.getOpTimeout());memcachedClient = builder.build();}catch (IOException e){logger.error("init MemcachedClient failed"+e);}return memcachedClient;}
4.编写配置文件
根据上面配置类的内容,可以知道需要配置如下的三个参数,服务地址、线程池大小、超时时间,当然为了高可用的话还可以将服务地址设置成一个数组。这里是测试就先不用高可用。
memcached.servers=10.2.116.178:11111
memcached.poolSize=10
memcached.opTimeout=6000
5.编写测试类
这里使用默认的SpringBoot自带的测试类进行测试。测试缓存的get和set方法。
@RunWith(SpringRunner.class)
@SpringBootTest
public class MemcacheApplicationTests {@Autowiredprivate MemcachedClient memcachedClient;@Testpublic void contextLoads() throws Exception {memcachedClient.set("hello",0,"Hello,xmemcached");String value = memcachedClient.get("hello");System.out.println("hello = "+ value);memcachedClient.delete("hello");}}
可以看到存储数据是通过set方法还有设置了其三个参数,第一个参数表示key,第一个参数表示expire时间单位是秒,超过这个时间memcached将这个数据替换出去,0表示永久存储,默认是一个月,第三个参数就是实际存储的数据,可以是任意的Java可序列化类型,当然也可以继承序列化接口Serializable,或者是可以序列化为指定类型,当然这里要满足Value的大小设定,超过大小将不会被缓存。
总结
上面简单的介绍了关于Memcache以及如何使用SpringBoot来整合Memcache,当然上面只是举例了一个简单的小例子。后面的博客中还会有更多的关于memcache 的使用在等着大家,希望大家可以多多支持。
SpringBoot 精通系列-SpringBoot如何操作Memcache相关推荐
- SpringBoot 精通系列-SpringBoot整合Redis的常用操作
导语 在之前的博客中介绍过关于Memcache的使用,这篇文章中主要介绍关于Redis的有关概念及如何与SpringBoot整合使用. 首先Redis是目前使用最为广泛的缓存中间件,相比较Me ...
- SpringBoot精通系列-Spring Boot中如何配置Https
导语 Https作为一个比较安全的协议,现在已经越来越普及了,特别是在完成小程序或者是公众号开发的时候,https基本上都是刚需了.但是一个HTTPS的证书是比较费钱的事情,个人开发者可以通过云 ...
- SpringBoot 精通系列-如何使用Spring Boot Security进行权限控制
导语 如何设计一个高效健全的安全策略是保证企业数据安全的的关键,笔者见过设计的比较优秀的安全管理策略也见过设计的比较Low的安全管理策略.如何保证高效的安全策略,在Java中Spring官方提供了 ...
- SpringBoot 精通系列-如何优雅地使用Mybatis的XML配置
导语 首先Mybatis作为如今最为流行的ORM框架之一,那么首先需要了解的就是什么是ORM框架. 文章目录 ORM框架 为什么需要ORM这种技术呢? Mybatis简介 Mybatis的几个重要 ...
- SpringBoot 精通系列-使用Swagger2构建RESTful APIs
导语 在之前的博客中曾经说过关于SpringBoot RESTful架构的知识,也提供了一个简单的小例子,当然在实际工作中更多的使用的是Swagger来实现一个RESTful的API.那么下面就来 ...
- SpringBoot 精通系列-构建一个RESTful Web 服务
导语 现在越来越多的企业推荐使用的是RESTful风格来构建企业应用接口,那么什么是RESTful呢? 文章目录 什么是RESTful SpringBoot对于RESTful有哪些支持 快速实例 ...
- SpringBoot精通系列-开发案例之配置Druid数据库连接池
导语 在使用SpringBoot的时候默认情况下提供了若干的数据库连接池,例如(dbcp,dbcp2,tomcat,hikari)等等,当然并不支持我们接下来所说的Druid,Druid是来自与阿 ...
- SpringBoot 精通系列-创建SpringBoot的入门项目
导语 在之前的博客中介绍过一些关于SpringBoot的使用方式,对于SpringBoot来说是一个全新的框架,它出现的目的是用来简化新的Spring应用的初始搭建以及开发过程.通过特殊的控制方式 ...
- SpringBoot精通系列-如何封装Spring Boot异常捕获
导语 在Spring Boot开发过程中,不难避免的就是异常处理,有些异常是通过try catch方式捕获,或者是通过Throw直接抛出,但是这种方式的话对于客户端是不友好的,所以希望是通过编码的 ...
最新文章
- C++判断exe是32位还是64位
- python不支持_为什么 Python 不支持函数重载?而其他语言大都支持?
- c语言程序设计中北大学,《中北大学软件学院2013届C语言程序设计实训题目.doc...
- This generally means that another instance of this process was already runni
- 双向广搜 8数码问题
- C++ 11 深度学习(四)结构、权限修饰符
- vue-cli使用swiper4在ie以及safari报错
- java公平索非公平锁_java中的非公平锁不怕有的线程一直得不到执行吗
- 锐捷校园网环境下设置统信UOS(Linux)自动连接网络
- 收藏已久免费下载软件的黑科技网站
- 百度地图线路查询路线样式自定义
- unity材质球复制
- mysql触发器new old用法详解
- Incapsula CDN到底好在哪
- asyncio 系列五、asyncio的事件循环
- ids for this class must be manually assigned before calling save()报错解决方法
- 用Python批量下载视频
- 代理服务器可能有问题,或地址不正确(已解决)
- 【Python测试】期末测试
- php 循环 解方程,解方程. 40%X=12080%X-60%X=1.26X+48=168X+20%X=24X-x5=1