本地缓存与分布式缓存
一、缓存的概念
在服务端编程当中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成,从而减少了对数据库的访问,解决了高并发场景中数据库容易成为性能瓶颈的问题;以及基于内存的访问速度高于磁盘的访问速度的原理(数据库读取数据一般需要从磁盘读取),提高了数据的访问速度和程序性能。
根据缓存是否与应用进程属于同一进程,可以将内存分为本地缓存和分布式缓存。本地缓存是在同一个进程内的内存空间中缓存数据,数据读写都是在同一个进程内完成;而分布式缓存是一个独立部署的进程并且一般都是与应用进程部署在不同的机器,故需要通过网络来完成分布式缓存数据读写操作的数据传输。
二、本地缓存
本地缓存的优缺点
-
访问速度快,但无法进行大数据存储
本地缓存相对于分布式缓存的好处是,由于数据不需要跨网络传输,故性能更好,但是由于占用了应用进程的内存空间,如 Java 进程的 JVM 内存空间,故不能进行大数据量的数据存储。 -
集群的数据更新问题
与此同时,本地缓存只支持被该应用进程访问,一般无法被其他应用进程访问,故在应用进程的集群部署当中,如果对应的数据库数据,存在数据更新,则需要同步更新不同部署节点的本地缓存的数据来包保证数据一致性,复杂度较高并且容易出错,如基于 Redis 的发布订阅机制来同步更新各个部署节点。 -
数据随应用进程的重启而丢失
由于本地缓存的数据是存储在应用进程的内存空间的,所以当应用进程重启时,本地缓存的数据会丢失。所以对于需要持久化的数据,需要注意及时保存,否则可能会造成数据丢失。
适用场景
所以本地缓存一般适合于缓存只读数据,如统计类数据。或者每个部署节点独立的数据,如长连接服务中,每个部署节点由于都是维护了不同的连接,每个连接的数据都是独立的,并且随着连接的断开而删除。如果数据在集群的不同部署节点需要共享和保持一致,则需要使用分布式缓存来统一存储,实现应用集群的所有应用进程都在该统一的分布式缓存中进行数据存取即可。
本地缓存的实现
缓存一般是一种key-value的键值对数据结构,所以需要使用字典数据结构来实现,在 Java 编程中,常用的字典实现包括 HashMap 和 ConcurretHashMap。
与此同时,本地缓存由于需要被不同的服务端线程并发读写,故需要保证线程安全。由于 HashMap 不是线程安全的,而 ConcurrentHashMap 是线程安全的,故一般会使用 ConcurrentHashMap 来作为 Java 编程中的本地缓存实现。除此之外,也有其他更加智能的本地缓存实现,如可以定时失效,访问重新加载等特性,典型实现包括 Google 的 guava 工具包的 Cache 实现,这些也是线程安全的。
三、分布式缓存
分布式缓存的优缺点
-
支持大数据量存储,不受应用进程重启影响
分布式缓存由于是独立部署的进程,拥有自身独立的内存空间,不会受到应用进程重启的影响,在应用进程重启时,分布式缓存的数据依然存在。同时对于数据量而言,由于不需要占用应用进程的内存空间,并且一般支持以集群的方式拓展,故可以进行大数据量的数据缓存。 -
数据集中存储,保证数据一致性
当应用进程采用集群方式部署时,集群的每个部署节点都通过一个统一的分布式缓存进行数据存取操作,故不存在本地缓存中的数据更新问题,保证了不同节点的应用进程的数据一致性问题。 -
数据读写分离,高性能,高可用
分布式缓存一般支持数据副本机制,可以实现读写分离,故可以解决高并发场景中的数据读写性能问题。并且由于在多个缓存节点冗余存储数据,提高了缓存数据的可用性,避免某个缓存节点宕机导致数据不可用问题。 -
数据跨网络传输,性能低于本地缓存
由于分布式缓存是独立部署的进程,并且一般都是与应用进程位于不同的机器,故需要通过网络来进行数据传输,这样相对于本地缓存的进程内部的数据读取操作,性能会较低。
分布式缓存的实现
分布式缓存的典型实现包括 MemCached 和 Redis。
- MemCached
MemCached 相对于本地缓存的主要差别是以独立进程方式存在,数据集中存储,数据不随应用程序的重启而丢失。而 key-value 键值对的 value 也是一个简单的对象类型,即 value 可以是任意格式的数据,如简单的数字、字符串、对象等,也可以是文件、图像、视频等复杂格式的数据,但是不支持数据结构的特性。
所以 MemCached 进程相当于是在内存维护了一个非常大的哈希表来存储数据,对应的数据操作复杂度都是 O(1),即常量级别,这也是 MemCached 高性能的一个实现方式,键值对存取速度都非常快。 - Redis
Redis 是在此基础上,更一步丰富了key-value 键值对的 value 的数据结构类型,即可以在 Redis 中完成 value 的相关数据操作,如 Set 集合去重、有序集合 ZSet 实现数据排序等,这样就不需要在应用程序额外进行这些操作,实现了开箱即用。并且 Redis 是单线程的,不存在并发数据读写的线程安全问题,以及更重要的是保证的数据读写操作的顺序性。
除此之外,Redis 支持主从同步(读写分离)、集群分片拓展、数据持久化等特性,这也是 MemCached 不支持的。所以在高并发场景并且数据能够容忍极端情况下的少量丢失,或者说丢失后可以恢复,如通过日志或者重新计算等, Redis 也可以作为数据库来使用,提高高并发场景中的访问性能。
相关文章:
本地缓存与分布式缓存
一、缓存的概念 在服务端编程当中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成,从而减少了对数据库的访问,解决了高并发场景中数据库容易成为性能瓶颈的问题;以及基于内存的访问速度高…...
LabVIEW如何获取波形图上游标所在位置的数值
LabVIEW如何获取波形图上游标所在位置的数值 获取游标所在位置数值的一种方法是利用波形图的游标列表属性。 在VI的程序框图中,右键单击波形图并选择创建引用 ,然后将创建的引用节点放在程序框图上。 在程序框图上放置一个属性节点,并将其…...
八股文面试day6
什么是代理?为什么要用动态代理? 代理模式大概意思是:为其他对象提供一个代理项或者是占位符,以控制对这个对象的访问 代理模式核心思想:创建一个代理对象,在客户端和目标对象之间的一个中介,…...
【Unity】EventSystem.current.IsPointerOverGameObject()对碰撞体起作用
本来我是用 EventSystem.current.IsPointerOverGameObject()来检测是否点击在UI上的,但是发现,他对我的碰撞体也是返回ture,研究半天。。。。找不出问题,然后发现我的相机上挂载了PhysicsRaycaster,去掉之后就好了,至于…...
形态学操作—闭运算
闭运算(Closing)是图像形态学中的一种操作,它结合了膨胀(Dilation)和腐蚀(Erosion)操作。闭运算的原理是先对图像执行腐蚀操作,然后再进行膨胀操作。这个过程能够消除图像中的小孔洞…...
HEVC-SCC rgb file input
关键字 csc allocateCSCBuffer()-> m_apcPicYuvCSC xCheckRDCostIntraCSC():更简单, enum ACTRDTestTypes { ACT_TWO_CLR 0, //two color space ACT_TRAN_CLR 1, //transformed color space ACT_ORG_CL…...
XG916Ⅱ轮式装载机后驱动桥设计机械设计CAD
wx供重浩:创享日记 对话框发送:装载机 获取完整论文报告工程源文件 本次设计内容为XG916Ⅱ装载机后驱动桥设计,大致上分为主传动的设计,差速器的设计,半轴的设计,最终传动的设计四大部分。其中主传动锥齿轮…...
pcr扩增原理中的变性 退火 延申扩增
一、PCR简介 聚合酶链式反应(PCR)是一种用于放大扩增特定的DNA片段的分子生物学技术,它可看作是生物体外的特殊DNA复制,PCR的最大特点是能将微量的DNA大幅增加。 二、PCR原理 1.背景 DNA的半保留复制是生物进化和传代的重要途…...
C语言——输入一个4位正整数,输出其逆数。
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int i,j 0;int a1,a2,a3,a4;printf("输入一个4位正整数:\n");scanf("%d",&i);a1 i/1000; a2 i/100%10; a3 i/10%10; a4 i%10; printf("千位a1%d,百位a…...
jQuery_02 引入jQuery,初试牛刀
引入jquery文件 我们在官网上点击dowmload那个 会发现进入了一个网页,里面全部是代码,你可能还在想为什么下载不了,其实jquery不跟vue一样,整个jquery就是一个js文件而已,所以直接ctrla 全选 ctrlc复制 ,然…...
pandas获取年月第一天、最后一天,加一秒、加一天、午夜时间
Timestamp对象 # ts = pandas.Timestamp(year=2023, month=10, day=15, # hour=15, minute=5, second=50, tz="Asia/Shanghai") ts = pandas.Timestamp("2023-10-15 15:05:50", tz="Asia/Shanghai") # 2023-10-15 15:05…...
Unsupervised Condition GAN
Unsupervised Condition GAN主要有两种做法: Direct Transformation 直接输入domain X图片,经过Generator后生成对应的domain Y的图像。这种转化input和output不能够差太多。通常只能实现较小的转化,比如改变颜色等。 Projection to Commo…...
Crypto(11)HECTF-rsarsa(明文存在线性关系)
题目如下: from functools import reduce from Crypto.Util.number import * import random from secret import flag,hintdef generate_PQ(bits):x getPrime(bits) >> bits//2 << bits//2#右移bit//2位后左移bit//2位while True:p x random.getran…...
论文阅读 Forecasting at Scale (二)
最近在看时间序列的文章,回顾下经典 论文地址 项目地址 Forecasting at Scale 3.2、季节性 3.3、假日和活动事件3.4、模型拟合3.5、分析师参与的循环建模4、自动化预测评估4.1、使用基线预测4.2、建模预测准确性4.3、模拟历史预测4.4、识别大的预测误差 5、结论6、致…...
刷题感悟w
题目很长的一定要慢慢把题目的意思搞清楚 有重复操作不知道怎么办 可以用数组去标记 你好!在C中,replace 函数通常是用于替换容器(例如 std::vector 或 std::string)中的特定元素的函数。以下是 std::replace 函数的一般用法&…...
记一次linux操作系统实验
前言 最近完成了一个需要修改和编译linux内核源码的操作系统实验,个人感觉这个实验还是比较有意思的。这次实验总共耗时4天,从对linux实现零基础,通过查阅资料和不断尝试,直到完成实验目标,在这过程中确实也收获颇丰&…...
java操作富文本插入到word模板
最近项目有个需求,大致流程是前端保存富文本(html的代码)到数据库,后台需要将富文本代码转成带格式的文字,插入到word模板里,然后将word转成pdf,再由前端调用接口下载pdf文件! 1、思…...
JMeter---BeanShell实现接口前置和后置操作
在JMeter中,可以使用BeanShell脚本来实现接口的前置和后置操作。 下面是使用BeanShell脚本实现接口前置和后置操作的步骤: 1、在测试计划中添加一个BeanShell前置处理器或后置处理器。 右键点击需要添加前置或后置操作的接口请求,选择&quo…...
【Linux】共享内存
文章目录 一、共享内存的原理详谈共享内存的实现过程二、共享内存的接口函数1.shmget2. shmatshmdtshmctl 进程间使用共享内存通信三、共享内存的特性 关于代码 一、共享内存的原理 共享内存是由操作系统维护和管理的一块内存。 共享内存的本质是内核级的缓冲区。 一个进程向…...
五、双向NAT
学习防火墙之前,对路由交换应要有一定的认识 双向NAT1.1.基本原理1.2.NAT Inbound NAT Server1.3.域内NATNAT Server —————————————————————————————————————————————————— 双向NAT 经过前面介绍,…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
