本地缓存和分布式缓存有何区别?

缓存是提高服务性能的一把利剑,尤其在高并发、高请求量的服务中性能提升明显。如果后端服务只靠关系型数据库提供支撑,系统会很快达到处理瓶颈。缓存设计无处不在,通常来说可以分为本地缓存与分布式缓存。本地缓存框架主要有Guava cache、Caffeine等,它们利用本地服务器内存来存储接口的返回数据。本地缓存有一定的局限性,多个进程间不能共享缓存,且缓存都是单机保存不容易扩展,本地机器宕机后缓存不能持久化。相对于本地缓存,分布式缓存可以解决本地缓存存在的问题,缓存数据集中存储并可以被后端服务共享访问,对于缓存数据还可以进行副本存储,做到持久化存储。不过引入分布式缓存也会带来一些运维成本,还有数据不一致等问题。总体来说,分布式缓存可以提高服务性能,减少后端服务的压力,收益大于成本。通常分布式缓存组件有Redis、Couchbase等本节主要以Redis组件介绍为主。

本地缓存

本地缓存是指将数据缓存在应用程序所在的服务器或客户端的内存中。本地缓存通常是以键值对的形式存储数据,其中键用于唯一标识数据,值则是实际的缓存数据。下面是一些常见的本地缓存的特点:

  • 快速访问速度:本地缓存位于应用程序所在的内存中,访问速度非常快,可以显著减少对后端数据源的访问。

  • 单节点存储:本地缓存通常只存储在一个节点中,多个应用实例之间无法共享缓存数据。

  • 有限容量:本地缓存的容量受到内存大小的限制,一旦超过容量限制,可能会导致性能下降或者数据丢失。

本地缓存适用于以下场景:

  • 热点数据缓存:将常用的、对应用程序性能影响较大的数据缓存在本地,提高访问速度,减少对后端数据源的压力。

  • 临时数据存储:将临时生成的数据缓存在本地,避免频繁访问后端系统。

分布式缓存

分布式缓存是指将缓存数据分散存储在多个节点上,这些节点可以分布在不同的服务器或者网络中。分布式缓存通过将数据分片存储在多个节点上,提高了缓存的容量和可扩展性。下面是一些常见的分布式缓存的特点:

  • 数据共享与复制:分布式缓存部分数据会被复制到多个节点上,以提高数据的可靠性和可用性。

  • 高扩展性:分布式缓存可以根据需求动态添加和删除节点,以适应数据量的变化和访问负载的增加。

  • 网络开销:由于分布式缓存需要在网络上进行数据传输,可能会增加额外的网络开销,导致访问速度略低于本地缓存。

分布式缓存适用于以下场景:

  • 海量数据缓存:当应用程序需要缓存大量数据时,本地缓存的容量可能无法满足需求,这时可以使用分布式缓存来扩展缓存容量。

  • 高并发访问:当应用程序需要处理大量并发请求时,本地缓存的性能可能受到限制,这时可以使用分布式缓存来分担访问负载。

本地缓存 JDK Map

JDK Map 经常用于缓存实现:

  • HashMap

    HashMap 是一种基于哈希表的集合类,它提供了快速的插入、查找和删除操作。可以将键值对作为缓存项的存储方式,将键作为缓存项的唯一标识符,值作为缓存项的内容。

  • ConcurrentHashMap

    ConcurrentHashMap 是线程安全的 HashMap,它在多线程环境下可以保证高效的并发读写操作。

  • LinkedHashMap

    LinkedHashMap 是一种有序的 HashMap ,它保留了元素插入的顺序,可以按照插入顺序或者访问顺序进行遍历。

  • TreeMap

    TreeMap 是一种基于红黑树的有序 Map,它可以按照键的顺序进行遍历。

应用场景: 红包活动存储在 ConcurrentHashMap 中 ,通过定时任务刷新缓存 。

核心流程:

1、红包系统启动后,初始化一个 ConcurrentHashMap 作为红包活动缓存 ;

2、数据库查询所有的红包活动 , 并将活动信息存储在 Map 中 ;

3、定时任务每隔 30 秒 ,执行缓存加载方法,刷新缓存。

为什么红包系统会将红包活动信息存储在本地内存 ConcurrentHashMap 呢 ?

  • 红包系统是高并发应用,快速将请求结果响应给前端,大大提升用户体验;

  • 红包活动数量并不多,就算全部放入到 Map 里也不会产生内存溢出的问题;

  • 定时任务刷新缓存并不会影响红包系统的业务。

笔者见过很多单体应用都使用这种方案,该方案的特点是简洁易用,工程实现也容易 。

本地缓存框架 

虽然使用 JDK Map 能快捷构建缓存,但缓存的功能还是比较孱弱的。

因为现实场景里,我们可能需要给缓存添加缓存统计过期失效淘汰策略等功能。

于是,本地缓存框架应运而生。

流行的 Java 缓存框架包括:Ehcache , Google Guava ,  Caffeine Cache 。

虽然本地缓存框架的功能很强大,但是本地缓存的缺陷依然明显。

1、高并发的场景,应用重启之后,本地缓存就失效了,系统的负载就比较大,需要花较长的时间才能恢复;

2、每个应用节点都会维护自己的单独缓存,缓存同步比较头疼

分布式缓存之Redis

    Redis是一个开源的、基于内存的Key-Value缓存数据库。Redis因其丰富的数据类型、高性能I/O、串行执行命令、数据持久化等特性而流行开来,Redis非常适合做分布式缓存数据库。Redis有5种基本数据类型:

lString:字符串类型,是Redis中最常用的数据类型。Key与Value都有一定的大小限制,如果太大会影响性能。字符串类型通常可以保存sessionId等信息,在计算器、分布式锁、全局ID等这类场景中使用。

lHash:哈希类型,类似JAVA中的HashMap这种数据结构。哈希类型的底层数据结构有ziplist和hashtable,当哈希类型元素个数小于配置限制以及值小于配置的限制时采用ziplist结构,否则使用hashtable结构。哈希类型通常可以保存一些配置信息,例如某个活动ID下的配置信息等。

lList:列表类型,底层包括两种实现:ziplist与linkedlist。列表类型通常用作消息队列来使用。

lSet:集合类型,底层实现是intset或hashtable。集合中元素不能重复,通常用作一类数据的集合来存储,例如社交媒体关注的“大V”集合等。

lSorted set:有序集合,底层实现包括ziplist或skiplist。有序集合常用场景主要是在有排序需求的地方,例如按销量排序的商品、热搜榜等。

其他数据类型包括:

lBitmap:位图类型,主要按位存储,可以按位进行计算。位图非常类似BloomFilter,可以判断某个值是否存在这种使用场景。

lHyperloglog:HyperLogLog主要的应用场景就是进行基数统计。

lGeo:主要存储地理位置信息数据。

  了解了Redis的一些数据结构类型,针对具体的场景选用不同的数据类型来使用。Redis虽然基于内存存储数据,但是也有持久化机制,将缓存数据持久化到磁盘上。Redis有两种持久化机制:RDB(Redis DataBase)和AOF(Append Only File)。RDB是每隔一定时间对Redis进行快照然后存储下来。AOF是将Redis的执行命令存储下来。相对来说RDB恢复数据更快,但是会丢失一定时间内的数据。AOF只会丢失最后执行的几条执行命令,所以恢复的数据更全一些。当然新的版本已经有RDB和AOF两种混合的持久化方式。

     Redis的在生产环境部署通常有几种模式:主从模式、哨兵模式以及集群模式。主从模式可以是一主多从,写缓存通过主库来操作,从库同步主库的数据并用来读取数据。哨兵模式是为了高可用,监控主库,当主库挂掉的时候,在从库中选择一个节点变为主库,这样避免了主库宕机不用使用的情况。Redis为了更好的扩展,提供了分片模式,设置了16384个槽,对缓存key进行hash计算,根据hash值分配到不同的槽与分片节点上。

    Spring Boot提供了对Redis的集成,提供了RedisTemplate类,完成Redis命令的执行,自动配置RedisTemplate代码如下:


public class RedisCacheConfiguration {/*** 配置Redis连接工厂*/@Beanpublic JedisConnectionFactory getJedisConnectionFactory(RedisConfigProperties redisConfigProperties) {JedisConnectionFactory jedisConnectionFactory = null;try {RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisConfigProperties.getHost(),redisConfigProperties.getPort());redisStandaloneConfiguration.setPassword(redisConfigProperties.getPassword());redisStandaloneConfiguration.setDatabase(redisConfigProperties.getDatabase());jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);jedisConnectionFactory.getPoolConfig().setMaxTotal(50);jedisConnectionFactory.getPoolConfig().setMaxIdle(50);jedisConnectionFactory.getPoolConfig().setMaxWaitMillis(redisConfigProperties.getTimeout());} catch (RedisConnectionFailureException e) {e.getMessage();}return jedisConnectionFactory;}@Bean(name = "redisTemplate")public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}
}
 本地缓存与分布式缓存的比较

本地缓存和分布式缓存各有优缺点,根据具体的应用场景和需求选择合适的缓存方式。下面是它们在一些关键方面的比较:

  • 数据一致性:本地缓存通常可以提供更高的数据一致性,因为数据存储在一个节点中。而分布式缓存由于数据复制和网络传输等原因,可能会导致一定的数据不一致性。

  • 容量和可扩展性:本地缓存的容量受限于内存大小,无法动态扩展。而分布式缓存可以通过添加或删除节点来动态调整容量,以适应数据量和访问负载的变化。

  • 访问速度:本地缓存由于位于内存中,访问速度非常快。而分布式缓存需要通过网络进行数据传输,可能略慢于本地缓存。

  • 可用性和容错性:本地缓存通常只存储在一个节点上,一旦节点故障,可能会导致缓存不可用。而分布式缓存利用数据复制和冗余机制,提高了系统的可用性和容错性。

  • 管理和维护成本:本地缓存相对简单,无需关注多个节点之间的数据同步和一致性。而分布式缓存需要进行节点管理和数据复制等操作,增加了管理和维护的成本。

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

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

相关文章

Java基础——自学习使用(反射)

一、反射的定义 反射是java基础的核心&#xff0c;反射是获取类信息的能力。类信息包括&#xff1a;方法、变量、接口、父类、构造器、类名等。 Java的反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;它允许程序在运行时检查或修改类、接口、字段以及方法…

【书生大模型实战营】MindSearch CPU-only 版部署

MindSearch CPU-only 版部署 MindSearch CPU-only 版部署任务步骤 MindSearch CPU-only 版部署 任务 将 MindSearch 部署到 HuggingFace 并美化 Gradio 的界面&#xff0c;并提供截图和 Hugging Face 的Space的链接。 步骤 按照官方教程&#xff0c;实现在网页上打开MindSe…

Java中等题-盛最多水的容器(力扣)

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。 我一开…

继电器实现上下电

一、依赖库 import serial 二、代码 import serialdef batonoff(com,status):继电器开关:param status::return:ser serial.Serial(com, baudrate9600, timeout0.1)if ser.is_open:if status "on":ser.write(data[0xA0, 0x01, 0x01, 0xA2])print(打开继电器)els…

Nginx负载均衡数据流分析

1、各机器ip信息 客户端IP&#xff1a;192.168.3.239 Nginx代理服务器IP&#xff1a;192.168.3.241 服务端IP&#xff1a;192.168.3.238 2、架构图&#xff08;略&#xff09; 3、 下图是在服务端上面的抓包分析。 下图是在客户端上面的抓包分析&#xff1a; 下图是在代理服务…

Python基础笔记

一、python基础1.1 基础知识1.1.1 注释 注释&#xff1a;在程序中对程序代码进行解释说明的文字。 作用&#xff1a;注释不是程序&#xff0c;不能被执行&#xff0c;只是对程序代码进行解释说明&#xff0c;让别人可以看懂程序代码的作用&#xff0c;能够大大增强程序的可读性…

【数论 状态机dp】2572. 无平方子集计数

本文涉及知识点 C动态规划 数论 质数、最大公约数、菲蜀定理 LeetCode 2572. 无平方子集计数 给你一个正整数数组 nums 。 如果数组 nums 的子集中的元素乘积是一个 无平方因子数 &#xff0c;则认为该子集是一个 无平方 子集。 无平方因子数 是无法被除 1 之外任何平方数整…

数据结构,单向链表

数据结构是计算机科学中的一个核心概念&#xff0c;它研究的是数据的组织、管理和存储方式&#xff0c;以及在这些数据上进行操作时的算法。数据结构为数据的高效访问和修改提供了基础。 数组&#xff08;Array&#xff09;&#xff1a;一种线性数据结构&#xff0c;可以存储固…

开源 AI 智能名片 O2O 商城小程序:引入淘汰机制,激发社交电商新活力

摘要&#xff1a;本文深入探讨在社交电商领域中&#xff0c;开源 AI 智能名片 O2O 商城小程序如何通过设置淘汰机制&#xff0c;实现“良币驱逐劣币”&#xff0c;激励士气&#xff0c;为社交电商企业注入新的活力。通过分析缺乏淘汰机制的弊端以及设置淘汰机制的优势&#xff…

一篇入门C语言【文件】

本科期间C语言的课本无论哪个版本都会有【文件】这一章节&#xff0c;不过好多学校基本上不讲或者就出一道选择题&#xff0c;讲得很浅&#xff0c;今天这篇详细总结一下这部分的知识~ 一.原理解析 文件是指存在在外部介质&#xff08;如磁盘、磁带&#xff09;上的数据集合。操…

NPDP|如何在传统行业中做好产品管理的策略与建议

在当今这个快速变化的数字时代&#xff0c;传统行业面临着前所未有的挑战与机遇。产品管理作为连接市场需求与企业生产的核心环节&#xff0c;其重要性不言而喻。对于传统行业而言&#xff0c;做好产品管理不仅意味着保持竞争力&#xff0c;更是实现转型升级、拥抱未来的关键。…

【类模板】成员函数模板

一、成员函数模板的基本含义 不管是普通的类&#xff0c;还是类模板&#xff0c;都可以为其定义成员函数模板&#xff0c;以下的情况就是类模板和成员函数模板都有各自独立的一套参数&#xff1a; template<typename T1> class A { public:T1 m_ic;static constexpr int…

0.3 学习Stm32经历过的磨难

文章目录 用库函数传参 能否按位或STM32库函数XXX_GetFlagStatus和XXX_GetITStatus的区别 用库函数传参 能否按位或 答案是看清况&#xff0c;而不是一股脑的写&#xff01;&#xff08;血泪的经验啊&#xff09; 可行的情况&#xff1a; //如gpio初始化结构体中的gpiopin参…

c++list

list介绍 list是序列容器&#xff0c;允许对序列中任意位置的恒定时间插入和擦除操作&#xff0c;以及双向迭代。 list容器被实现为双向链表;双向链表可以将它们包含的每个元素存储在不同且不相关的存储位置。 list的使用 list中的接口比较多&#xff0c;此处类似&#xff0…

RedisStack十部曲之二:Redis的核心概念

文章目录 键空间修改和查询键键过期遍历键空间 客户端缓存在计算机科学中有两个难题客户端缓存的Redis实现跟踪模式的工作机制统一的键命名空间 两种连接方式缓存策略Opt-in 模式Opt-out 模式广播模式NOLOOP选项避免竟态条件当与服务器失去连接怎么办什么值得缓存 流水线请求/响…

使用QTcpSocket在两台ubuntu之间实现通讯

重点提取&#xff1a; 1.保证服务端和客户端端口号一致 2.保证服务端和客户端在同一网段(可以通过网线连接) 3保证客户端界面输入的ip是服务段的ip 实现步骤&#xff1a; 首先&#xff0c;构造服务端界面和客户端界面如下 服务端界面 客户端界面 其次具体代码 在.pro文件…

FRP内网穿透与神卓互联,优势对比

本文介绍分析了当前市面上两款常用的内网穿透工具 frp内网穿透介绍 一、概述 frp&#xff08;Fast Reverse Proxy&#xff09;是一款高性能的反向代理应用&#xff0c;主要用于实现内网穿透功能。通过frp&#xff0c;用户可以将内网中的服务器或服务暴露到公网上&#xff0c;…

【ACM独立出版|EI快检索-高录用|IEEE Fellow支持】2024年数字经济与计算机科学国际学术会议(DECS2024)

【ACM独立出版&#xff5c;EI快检索-高录用&#xff5c;IEEE Fellow支持】 2024年数字经济与计算机科学国际学术会议&#xff08;DECS2024&#xff09; *ACM独立出版&#xff0c;快检索&#xff0c;高录用 *见刊后1个月左右完成EI&Scopus检索 *国内211大学、世界QS名校…

#驱动开发

内核模块 字符设备驱动 中断、内核定时器 裸机开发和驱动开发的区别&#xff1f; 裸机开发 驱动开发&#xff08;基于内核&#xff09; 相同点 都能够控制硬件&#xff08;本质&#xff1a;操作寄存器&#xff09; 不同点 用C语言给对应的地址里面写值 按照一定的框架格式…

hackme靶机通关攻略

1、登录靶机&#xff0c;查询是否有注入点 2、判断闭合方式 输入OSINT and 11 # 输入OSINT and 12 # 得出闭合方式为单引号 2、查询数据库名 输入-1 union select database(),2,3 # 3、查询数据库中的表 输入-1 union select group_concat(table_name),2,3 from informa…