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://xiahunao.cn/news/3249667.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Postman导出excel文件

0 写在前面 在我们后端写接口的时候&#xff0c;前端页面还没有出来&#xff0c;我们就得先接口测试&#xff0c;在此记录下如何使用postman测试导出excel接口。 如果不会使用接口传参可以看我这篇博客如何使用Postman 1 方法一 2 方法二 3 写在末尾 虽然在代码中写入文件名…

NVIDIA Container Toolkit 安装与配置帮助文档(Ubuntu,Docker)

NVIDIA Container Toolkit 安装与配置帮助文档(Ubuntu,Docker) 本文档详细介绍了在 Ubuntu Server 22.04 上使用 Docker 安装和配置 NVIDIA Container Toolkit 的过程。 概述 NVIDIA 容器工具包使用户能够构建和运行 GPU 加速容器。即可以在容器中使用NVIDIA显卡。 架构图如…

uniapp H5 如何根据接口返回form表单,跳转银联支付界面?

uniapp如何根据form表单&#xff0c;唤醒第三方支付? 文章目录 uniapp如何根据form表单&#xff0c;唤醒第三方支付?效果图实现 效果图 接口返回 form 表单数据 实现 // 例请求成功&#xff0c;返回数据 rechargePay({}).then(res > {// 接收接口返回数据let { result …

= null 和 is null;SQL中关于NULL处理的4个陷阱;三值逻辑

一、概述 1、NULL参与的所有的比较和算术运算符(>,,<,<>,<,>,,-,*,/) 结果为unknown&#xff1b; 2、unknown的逻辑运算(AND、OR、NOT&#xff09;遵循三值运算的真值表&#xff1b; 3、如果运算结果直接返回用户&#xff0c;使用NULL来标识unknown 4、如…

JRT实体视图查询

JRT的设计目标就是多数据库支持&#xff0c;对于爬行周边数据提供DolerGet解决爬取多维数据问题。但是对于通过父表字段筛选子表数据就不能通过DolerGet取数据了&#xff0c;因为查询到的父表数据没有子表数据的ID。 比如下面表&#xff1a; 我需要按登记号查询这个登记号的报…

【linux】服务器安装NVIDIA驱动

【linux】服务器安装NVIDIA驱动 【创作不易&#xff0c;求点赞关注收藏】&#x1f600; 文章目录 【linux】服务器安装NVIDIA驱动一、关闭系统自带驱动nouveau二、下载英伟达驱动三、安装英伟达驱动1、禁用X服务器和相关进程2、在TTY终端安装驱动3、验证是否安装成功4、重新启…

接口开发:Orcal数据库的批量修改sql

场景&#xff1a;在日常的CURD中一定会用到批量修改。在我们的项目中&#xff0c;使用的数据库是Orcal&#xff0c;由于之前基本都是使用Mysql的&#xff0c;使用的sql语句也基本都是用mysql的。但是在这次的接口编写时用mysql的批量修改出了问题&#xff0c;刚开始我还以为是写…

源码分析SpringCloud Gateway如何加载断言(predicates)与过滤器(filters)

我们今天的主角是Gateway网关&#xff0c;一听名字就知道它基本的任务就是去分发路由。根据不同的指定名称去请求各个服务&#xff0c;下面是Gateway官方的解释&#xff1a; Spring Cloud Gateway&#xff0c;其他的博主就不多说了&#xff0c;大家多去官网看看&#xff0c;只…

WDL(Wide Deep Learning for Recommender Systems)——Google经典CTR预估模型

一、文章简介 Wide & Deep Learning for Recommender Systems这篇文章介绍了一种结合宽线性模型和深度神经网络的方法&#xff0c;以实现推荐系统中的记忆和泛化。这种方法在Google Play商店的应用推荐系统中进行了评估&#xff0c;展示了其显著的性能提升。 推荐系统中的…

食堂采购系统开发:从需求分析到上线实施的完整指南

本篇文章&#xff0c;笔者将详细介绍食堂采购系统从需求分析到上线实施的完整过程&#xff0c;旨在为开发团队和管理者提供一个系统化的指南。 一、需求分析 1.用户需求 常见的需求包括&#xff1a; -采购计划管理 -供应商管理 -库存管理 -成本控制 -报表生成 2.系统功…

RK3568笔记四十:设备树

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 设备树 (Device Tree) 的作用就是描述一个硬件平台的硬件资源&#xff0c;一般描述那些不能动态探测到的设备&#xff0c;可以被动态探测到的设备是不需要描述。 设备树可以被 bootloader(uboot) 传递到内核&#x…

CentOS6minimal安装nginx-1.26.1.tar.gz 笔记240718

CentOS6安装新版nginx 240718, CentOS6.1-minimal 安装 nginx-1.26.1.tar.gz 下载 nginx-1.26.1.tar.gz 的页面 : https://nginx.org/en/download.html 下载 nginx-1.26.1.tar.gz : https://nginx.org/download/nginx-1.26.1.tar.gz CentOS6.1已过期, 给它更换yum源, 将下面…

SpringCloud------Sentinel(微服务保护)

目录 雪崩问题 处理方式!!!技术选型 Sentinel 启动命令使用步骤引入依赖配置控制台地址 访问微服务触发监控 限流规则------故障预防流控模式流控效果 FeignClient整合Sentinel线程隔离-------故障处理线程池隔离和信号量隔离​编辑 两种方式优缺点设置方式 熔断降级-----…

简述乐观锁和悲观锁——Java

悲观锁和乐观锁 悲观就是任何事都认为会往坏处发生&#xff0c;乐观就是认为任何事都会往好处发生。 打个比方&#xff0c;假如一个公司里只有一台打印机&#xff0c;如果多个人同时打印文件&#xff0c;可能出现混乱的问题&#xff0c;他的资料打印在了我的资料上&#xff0…

【视频讲解】神经网络、Lasso回归、线性回归、随机森林、ARIMA股票价格时间序列预测|附代码数据

全文链接&#xff1a;https://tecdat.cn/?p37019 分析师&#xff1a;Haopeng Li 随着我国股票市场规模的不断扩大、制度的不断完善&#xff0c;它在金融市场中也成为了越来越不可或缺的一部分。 【视频讲解】神经网络、Lasso回归、线性回归、随机森林、ARIMA股票价格时间序列…

Unity动画系统(4)

6.3 动画系统高级1-1_哔哩哔哩_bilibili p333- 声音组件添加 using System.Collections; using System.Collections.Generic; using UnityEngine; public class RobotAnimationController : MonoBehaviour { [Header("平滑过渡时间")] [Range(0,3)] publ…

AI智能名片S2B2C商城小程序在社群去中心化管理中的应用与价值深度探索

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;社群经济作为一种新兴的商业模式&#xff0c;正逐渐成为企业与用户之间建立深度连接、促进商业增长的重要途径。本文深入探讨了AI智能名片S2B2C商城小程序在社群去中心化管理中的应用&#xff0c;通过详细分析社群去中心化…

科普文:多线程如何使用CPU缓存?

一、前言 计算机的基础知识聊的比较少&#xff0c;但想要更好的理解多线程以及为后续多线程的介绍做铺垫&#xff0c;所以有必要单独开一篇来聊一下 CPU cache。 二、CPU 前面有一篇文章关于 CPU是如何进行计算 感兴趣的同学&#xff0c;可以先移步了解一下&#xff0c;不了…

连接Redis异常:JedisMovedDataException

redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 5798 192.168.187.138:6379 在使用JAVA API连接redis的时候&#xff0c;出现了异常&#xff1a; 问题的原因 JAVA API实现是redis集群实现方式&#xff0c;而在配置文中就配置的是单结点的方式。 Moved表示使…

从人工巡检到智能防控:智慧油气田安全生产的新视角

一、背景需求 随着科技的飞速发展&#xff0c;视频监控技术已成为各行各业保障安全生产、提升管理效率的重要手段。特别是在油气田这一特殊领域&#xff0c;由于其工作环境复杂、安全风险高&#xff0c;传统的监控方式已难以满足实际需求。因此&#xff0c;基于视频监控AI智能…