Memcached介绍与使用

引言

本文是笔者对Memcached这个高性能分布式缓存组件的实践案例,Memcached是一种高性能的分布式内存对象缓存系统,用于减轻数据库负载,加速动态Web应用,提高网站访问速度。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高应用程序的性能。

本文涉及到的源码gitee地址:源码地址

一、Memcached介绍

主要特点

  • 键值存储:Memcached 使用键值对存储模型,其中键是一个字符串,值可以是任何数据,通常用于存储数据库查询结果、网页或对象的序列化形式。

  • 内存存储:数据存储在内存中,这比从硬盘读取数据要快得多。但是,这也意味着数据是非持久化的,如果 Memcached 或操作系统重启,数据会丢失。

  • LRU 缓存替换策略:当内存不足时,Memcached 使用最近最少使用(Least Recently Used,LRU)算法来自动删除不常用的缓存项,以便为新数据腾出空间。

  • 简单协议:Memcached 使用一个简单的文本行协议,这使得它易于实现和集成。

  • 跨平台:Memcached 可以在多种操作系统上运行,包括 Linux 和 BSD 等。

  • 高可用性和可扩展性:Memcached 支持分布式部署,可以在多个服务器上运行,以增加容量和冗余。

  • 轻量级和快速:由于其简单的架构和内存存储特性,Memcached 能够提供非常低的延迟和高吞吐量。


适用场景

  • 缓存数据库查询结果。

  • 存储用户会话信息。

  • 缓存计算结果或频繁访问的内容。

  • 存储用户个性化数据。


不适用场景

  • 缓存的数据需要持久化

  • key 的长度大于 250 字符

  • 变化频繁且需要存入数据库

  • 过大的数据不适宜放在 Memcached 中


与 Redis 比较相同点

  1. 都是基于内存的数据库系统,最大存储量是根据机器内存大小而定

  2. 都有不同的过期策略,分布式数据的备份可以设置一主多从,也可以一主一从(Master-Slave)

  3. 都支持 key-value 数据缓存


与 Redis 比较不同点

  1. 数据持久化支持:Redis 虽然是基于内存的存储系统,但是它本身是支持内存数据的持久化的,而且提供两种主要的持久化策略:RDB 快照和 AOF 日志。而 Memcached 是不支持数据持久化操作的。

  2. 灾难恢复:Memcached 挂掉后,数据不可恢复。 Redis 数据丢失后可以通过 AOF 恢复

  3. IO 方面:Redis 使用的单线程 IO 复用网络模型, 而 Memcached 多线程非阻塞 IO 复用模型

  4. 数据支持类型:Redis 支持 key-value 数据类型,还有 list、set、zset、hash 等数据结构,而 Memcached 只支持 key-value 数据

  5. Value 值大小不同:Redis 最大可以达到 512mb;Memcached 只有 1mb。

  6. 数据一致性:Memcached 提供了 CAS 命令,可以保证多个并发访问操作同一份数据的一致性问题。Redis 没有提供 CAS 命令,并不能保证这点,不过 Redis 提供了事务的功能,可以保证一串命令的原子性,中间不会被任何操作打断。


二、java客户端介绍

主要有三种不同的 Java 客户端来支持 Memcached, 分别为 Memcached-java-clientSpymemcachedXMemcached

Memcached-java-client 客户端

  • Memcached-java-client 客户端推出较早,应用最广泛,阻塞式 IO,稳定性高,高并发下性能低。较早推出的 Memcached JAVA 客户端 API,应用广泛,运行比较稳定,使用阻塞 IO,不支持 CAS 操作,已停止更新。

Spymemcached 客户端

  • Spymemcached 客户端时基于 JDK 的 Concurrent 和 NIO,存取速度高,并发性能高,支持 CAS 操作,已停止更新。

XMemcached 客户端

  • XMemcached 客户端同样基于 NIO 实现,减少了线程创建和切换的开销,这一点在高并发下特别明显,一直更新。推荐使用。

三、下载安装Memcached

地址:memcached下载

在这里插入图片描述
把这个链接复制到新的标签页打开自动下载。下载后的压缩包解压如下

在这里插入图片描述

使用管理员权限打开cmd,进入此路径

笔者下载的是1.4.4版本

memcached <1.4.5 版本安装

  1. 解压下载的安装包到指定目录。

  2. 在 1.4.5 版本以前 memcached 可以作为一个服务安装,使用管理员权限运行以下命令:

c:\memcached\memcached.exe -d install
注意:你需要使用真实的路径替代 c:\memcached\memcached.exe。

3、然后我们可以使用以下命令来启动和关闭 memcached 服务:

c:\memcached\memcached.exe -d start
c:\memcached\memcached.exe -d stop

在这里插入图片描述
然后使用sc query memcached查看命令是否成功:

在这里插入图片描述
打开 服务列表发现memcached服务已安装,并且是开机自启动,后续无需手动再执行
memcached.exe -d start命令了
在这里插入图片描述

四、各种类型客户端实践

先创建一个Memcached-Project的springboot应用,创建好后去resources下把application.properties改为application.yml

为了方便,三种java客户端,我都使用这个项目来展示。

4.1 Memcached-java-client

首先在pom引入如下依赖:

 <!--Memcached-java-client--><dependency><groupId>commons-pool</groupId><artifactId>commons-pool</artifactId></dependency><dependency><groupId>com.whalin</groupId><artifactId>Memcached-Java-Client</artifactId><version>3.0.2</version></dependency>

MemcachedConfig配置类:

package com.hulei.memcached.memcachedjavaclient;import com.whalin.MemCached.MemCachedClient;
import com.whalin.MemCached.SockIOPool;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author hulei* Memcached-java-client的配置*/
@Configuration
public class MemcachedConfig {@Value("${MemcachedJavaClient.memcached.servers}")private String[] servers;@Value("${MemcachedJavaClient.memcached.failover}")private boolean failover;@Value("${MemcachedJavaClient.memcached.initConn}")private int initConn;@Value("${MemcachedJavaClient.memcached.minConn}")private int minConn;@Value("${MemcachedJavaClient.memcached.maxConn}")private int maxConn;@Value("${MemcachedJavaClient.memcached.maintSleep}")private int maintSleep;@Value("${MemcachedJavaClient.memcached.nagel}")private boolean nagel;@Value("${MemcachedJavaClient.memcached.socketTO}")private int socketTO;@Value("${MemcachedJavaClient.memcached.aliveCheck}")private boolean aliveCheck;@Beanpublic SockIOPool sockIOPool () {SockIOPool pool = SockIOPool.getInstance();pool.setServers(servers);pool.setFailover(failover);pool.setInitConn(initConn);pool.setMinConn(minConn);pool.setMaxConn(maxConn);pool.setMaintSleep(maintSleep);pool.setNagle(nagel);pool.setSocketTO(socketTO);pool.setAliveCheck(aliveCheck);pool.initialize();return pool;}@Bean@ConditionalOnBean(SockIOPool.class)public MemCachedClient memCachedClient(){return new MemCachedClient();}}

yml配置:
在这里插入图片描述

MemcachedController测试类:

package com.hulei.memcached.memcachedjavaclient;import com.whalin.MemCached.MemCachedClient;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;@RestController
public class MemcachedController {@Resourceprivate MemCachedClient memCachedClient;@RequestMapping("/memcachedIndex")public String memcachedIndex() throws InterruptedException {// 放入缓存boolean flag = memCachedClient.set("a", 1);System.out.println(flag);// 取出缓存Object a = memCachedClient.get("a");System.out.println(a);// 3s后过期memCachedClient.set("b", "2", new Date(3000));Object b = memCachedClient.get("b");System.out.println(b);Thread.sleep(3000);b = memCachedClient.get("b");System.out.println(a);System.out.println(b);return "abcd";}
}

浏览器输入地址:http://localhost:8080/memcachedIndex,观察IDEA控制台输出:
在这里插入图片描述

4.2 SpyMemcached

pom中引入依赖:

        <!--SpyMemcached--><dependency><groupId>net.spy</groupId><artifactId>spymemcached</artifactId><version>2.12.3</version></dependency>

SpyMemcachedConfig配置类:

package com.hulei.memcached.spymemcached;import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.spy.memcached.MemcachedClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;import java.io.IOException;
import java.net.InetSocketAddress;@Configuration
@Slf4j
public class SpyMemcachedConfig implements CommandLineRunner {@Value("${SpyMemcached.memcached.ip}")private String ip;@Value("${SpyMemcached.memcached.port}")private int port;@Getterprivate MemcachedClient client = null;@Overridepublic void run(String... args) {try {client = new MemcachedClient(new InetSocketAddress(ip,port));} catch (IOException e) {log.error("SpyMemcached初始化失败",e);throw new RuntimeException("SpyMemcached初始化失败");}}}

yml配置

在这里插入图片描述

SpyMemcachedController测试控制类:

package com.hulei.memcached.spymemcached;import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class SpyMemcachedController {@Resourceprivate SpyMemcachedConfig spyMemcachedConfig;@RequestMapping("/spyMemcachedIndex")public String spyMemcachedIndex() throws InterruptedException {/*这个过期时间单位是秒,最大值是60*60*24*30*/spyMemcachedConfig.getClient().set("spyMemcachedKey",1,"张三");System.out.println("基于spyMemcached实现,现在的值为 "+spyMemcachedConfig.getClient().get("spyMemcachedKey"));Thread.sleep(2000);System.out.println("1秒后缓存内容清除,现在的值为: "+spyMemcachedConfig.getClient().get("spyMemcachedKey"));return "SpyMemcached";}
}

浏览器输入地址:http://localhost:8080/spyMemcachedIndex,观察IDEA控制台输出:

在这里插入图片描述

4.3 XMemcached

pom中再引入依赖:

        <!--XMemcached --><dependency><groupId>com.googlecode.xmemcached</groupId><artifactId>xmemcached</artifactId><version>2.4.8</version></dependency>

XMemcachedConfig配置类:

package com.hulei.memcached.xmemcached;import lombok.extern.slf4j.Slf4j;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@Slf4j
public class XMemcachedConfig {@Value("${XMemcached.memcached.server}")private String server;@Value("${XMemcached.memcached.opTimeout}")private Integer opTimeout;@Value("${XMemcached.memcached.poolSize}")private Integer poolSize;@Value("${XMemcached.memcached.failureMode}")private boolean failureMode;@Value("${XMemcached.memcached.enabled}")private boolean enabled;@Bean(name = "memcachedClientBuilder")public MemcachedClientBuilder getBuilder() {MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder(server);// 内部采用一致性哈希算法memcachedClientBuilder.setSessionLocator(new KetamaMemcachedSessionLocator());// 操作的超时时间memcachedClientBuilder.setOpTimeout(opTimeout);// 采用二进制传输协议(默认为文本协议)memcachedClientBuilder.setCommandFactory(new BinaryCommandFactory());// 设置连接池的大小memcachedClientBuilder.setConnectionPoolSize(poolSize);// 是否开起失败模式memcachedClientBuilder.setFailureMode(failureMode);return memcachedClientBuilder;}/*** 由Builder创建memcachedClient对象,并注入spring容器中*/@Bean(name = "memcachedClient")public MemcachedClient getClient(@Qualifier("memcachedClientBuilder") MemcachedClientBuilder memcachedClientBuilder) {MemcachedClient client;try {client =  memcachedClientBuilder.build();} catch(Exception e) {log.error("创建MemcachedClient对象失败", e);throw new RuntimeException("创建MemcachedClient对象失败", e);}return client;}
}

yml配置
在这里插入图片描述

XMemcachedController测试服务类:

package com.hulei.memcached.xmemcached;import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.rubyeye.xmemcached.MemcachedClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@Slf4j
public class XMemcachedController {@Resourceprivate MemcachedClient memcachedClient;@RequestMapping("/XMemcachedIndex")public String XMemcachedIndex() {try {//新增操作memcachedClient.set("XMemcachedKeyOne",0,"张三");System.out.println((String)memcachedClient.get("XMemcachedKeyOne"));//删除操作memcachedClient.delete("XMemcachedKeyOne");System.out.println((String)memcachedClient.get("XMemcachedKeyOne"));//设置存活时间memcachedClient.set("XMemcachedKeyTwo",1,"李四");Thread.sleep(2000);System.out.println((String)memcachedClient.get("XMemcachedKeyTwo"));//更新操作memcachedClient.set("XMemcachedKeyThree",0,"王五");System.out.println((String)memcachedClient.get("XMemcachedKeyThree"));memcachedClient.set("XMemcachedKeyThree",0,"王五他儿子");System.out.println((String)memcachedClient.get("XMemcachedKeyThree"));} catch (Exception e) {log.error("XMemcachedIndex error",e);}return "xMemcachedIndex";}
}

浏览器输入地址:http://localhost:8080/XMemcachedIndex,观察IDEA控制台输出:
在这里插入图片描述

五、总结

通过以上三个java客户端的案例,演示了Memcached的实际用法,整体较为简单,笔者把三个客户端的代码用一个项目演示,需要源码的请从文章顶部获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/873123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IAR嵌入式开发解决方案已全面支持芯科集成CX3288系列车规RISC-V MCU,共同推动汽车高品质应用的安全开发

中国上海&#xff0c;2024年7月16日 — 全球领先的嵌入式系统开发软件解决方案供应商IAR与芯科集成电路&#xff08;以下简称“芯科集成”&#xff09;联合宣布&#xff0c;最新版本IAR Embedded Workbench for RISC-V 3.30.2功能安全版已全面支持芯科集成CX3288系列车规RISC-V…

解决vue多层弹框时存在遮挡问题

本文给大家介绍vue多层弹框时存在遮挡问题&#xff0c;解决思路首先想到的是找到对应的遮挡层的css标签&#xff0c;然后修改z-index值&#xff0c;但是本思路只能解决首次问题&#xff0c;再次打开还会存在相同的问题&#xff0c;故该思路错误&#xff0c;下面给大家带来一种正…

中间件的理解

内容来源于学习网站整理。【一看就会】什么是前端开发的中间件&#xff1f;_哔哩哔哩_bilibili 每日八股文~白话说mq&#xff0c;消息中间件_哔哩哔哩_bilibili 例如&#xff1a; 1&#xff09;两个人打电话&#xff0c;中间的通信网络就是中间件。 2&#xff09;菜鸟驿站&…

流式数据库 |RisingWave 的架构、容错、数据持久化

在上一篇文章中&#xff0c;已经为大家分享了 RisingWave 相关核心概念和术语。本文将在此基础上为大家介绍 RisingWave 的架构、容错以及数据持久化。 1. 架构 RisingWave 的架构如下图所示。它由三个主要部分组成&#xff1a;Meta 节点、Compute 节点和 Compactor 节点。 …

linux环境安装mongoDB

一、安装单体mogodb 目标&#xff1a;在Linux中部署一个单机的MongoDB&#xff0c;作为生产环境下使用。 提示&#xff1a;和Windows下操作差不多。 步骤如下&#xff1a; &#xff08;1&#xff09;先到官网下载压缩包 mongod-linux-x86_64-4.0.10.tgz 。 &#xff08;2&…

SpringBoot Bean管理

我们知道可以通过Spring当中提供的注解Component以及它的三个衍生注解&#xff08;Controller、Service、Repository&#xff09;来声明IOC容器中的bean对象&#xff0c;同时我们也学习了如何为应用程序注入运行时所需要依赖的bean对象&#xff0c;也就是依赖注入DI。 本篇主要…

c++初阶知识——内存管理与c语言内存管理对比

目录 前言&#xff1a; 1.c&#xff0b;&#xff0b;内存管理方式 1.1 new和delete操作自定义类型 2.operator new与operator delete函数 2.1 operator new与operator delete函数 3.new和delete的实现原理 3.1 内置类型 3.2 自定义类型 new的原理 delete的原理 new…

gite+picgo+typora打造个人免费笔记软件

文章目录 1️⃣个人笔记软件2️⃣ 配置教程2.1 使用软件2.2 node 环境配置2.3 软件安装2.4 gite仓库设置2.5 配置picgo2.6 测试检验2.7 github教程 &#x1f3a1; 完结撒花 1️⃣个人笔记软件 最近换了环境&#xff0c;没有之前的生产环境舒适&#xff0c;写笔记也没有劲头&…

图——图的遍历(DFS与BFS算法详解)

前面的文章中我们学习了图的基本概念和存储结构&#xff0c;大家可以通过下面的链接学习&#xff1a; 图的定义和基本术语 图的类型定义和存储结构 这篇文章就来学习一下图的重要章节——图的遍历。 目录 一&#xff0c;图的遍历定义&#xff1a; 二&#xff0c;深度优先…

【代码随想录】【算法训练营】【第58天 2】 [卡码102]沉没孤岛

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 58&#xff0c;周四&#xff0c;ding~ 题目详情 [卡码102] 沉没孤岛 题目描述 卡码102 沉没孤岛 解题思路 前提&#xff1a;修改孤岛的值 思路&#xff1a;DFS or BFS&#xff0c;使用visite…

探寻大模型回答9.9和9.11犯错的根本原因

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

每日OJ_牛客_排序子序列

目录 牛客_排序子序列 题解及代码 牛客_排序子序列 排序子序列_牛客笔试题_牛客网 题解及代码 本题依次比较整个数组 v[i1]>v[i] &#xff0c;则进入非递减序列判断&#xff0c;直到遍历到下一个值不大于等于为止count&#xff0c;然后进行下一位置的判断v[i1]<v[i]…

算法之判断对称二叉树

94. 二叉树的中序遍历101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;fa…

特斯拉新一代人形机器人Optimus二代:听说行走速度能够提升30%?

在当今这个快速变化的时代&#xff0c;人工智能已成为我们探索未来的一大驱动力。特斯拉以其在电动汽车领域的创新而闻名&#xff0c;而Optimus智能机器人的发布&#xff0c;更是将这种创新精神带到了一个新的领域 1. 智能机器人&#xff1a;Optimus的起源 2021年8月&#xff…

虚拟摄像头怎么用?安卓虚拟相机替换本地摄像头教程(内含3个虚拟摄像头)

虚拟摄像头是一个软件摄像机&#xff0c;电脑没有物理摄像头时可以借助虚拟摄像头进行视频通话。当我们电脑没有自带的摄像头时&#xff0c;必须要外接摄像头才可以进行网络会议、视频直播。普通的摄像头像素不高&#xff0c;直接将手机充当电脑摄像头效果更佳哦。 虚拟摄像头我…

自动驾驶算法——Vehicle Control(一)

“ 在过去的几年里&#xff0c;无人驾驶汽车已成为人工智能领域的主要主力之一。鉴于交通死亡人数众多、老年人和残疾人的行动能力有限以及交通拥堵和拥堵问题日益严重&#xff0c;自动驾驶汽车有望解决我们社会最重要的问题之一&#xff1a;移动的未来。然而&#xff0c;让汽车…

数学建模(1)

论文&#xff1a;做流程图 论文查重不能高于30% 论文 分模块备战 摘要不能超过一页的四分之三 数学建模的六个步骤: 【写作】---学术语言 团队练题

科普文:TaobaoVM信息收集

网上关于TaobaoVM的信息很少&#xff0c;只有一个简介&#xff0c;就没有其他信息。毕竟这是别人企业自己的jvm&#xff0c;不可能公开。 Taobao VM 由AliJVM团队发布。阿里&#xff0c;国内使用Java最强大的公司&#xff0c;覆盖云计算、金融、物流、电商等众多领域&#xf…

zabbix“专家坐诊”第246期问答

问题一 Q&#xff1a;有哪位大哥知道这是啥情况&#xff0c;6.4主动检查接口显示未知&#xff1f; A&#xff1a;看看agent配置文件的主采集有没有填写正确IP。 Q&#xff1a;我刚刚客户端重新授权&#xff0c;发现可以预警了&#xff0c;但是还是灰色的&#xff0c;我尝试输…

spring事件发布器ApplicationEventPublisher的使用

1、前言 spring中有一个事件发布器,使用了观察者模式,当有事件发布的时候,事件监听者会立刻收到发布的事件。今天我们来介绍下这个事件发布器怎么使用。 2、简单使用 2.1、创建事件实体类 事件实体类需要继承ApplicationEvent。我们模拟老师发布事件的诉求。 public class T…