当前位置: 首页 > news >正文

【Redis】基础2:作为缓存

文章目录

  • 1. 一些概念
  • 2. 主动更新策略/缓存设计模式
    • 2.1 cache-aside pattern(lazy loading)
    • 2.2 read-through pattern(针对读操作)
    • 2.3 write-through pattern
    • 2.4 write behind pattern(write back pattern)
    • 2.5 write around pattern
    • 2.6 delay double delete
    • 2.7 refresh ahead
    • 2.8 总结
      • 2.8.1 对于读场景
      • 2.8.2 对于写场景
      • 2.8.3 因为数据更新而引发的cache更新
  • 3. 一个cache系统的例子
    • 3.1 查询数据场景
    • 3.2 更新数据场景(先更新DB,再删除cache,原子操作)
      • 3.2.1 更新数据库时考虑的问题:
  • 4. 缓存面临的问题
    • 4.1 缓存穿透(cache penetration)
    • 4.2 缓存雪崩(cache avalanche)
    • 4.3 缓存击穿(cache breakdown)
      • 4.3.1 如何使用互斥锁来应对缓存击穿问题
      • 4.3.2 如何使用逻辑过期应对缓存击穿问题
    • 4.4 缓存系统设计的其他问题
      • 4.4.1 读扩散和写扩散问题
      • 4.4.2 redis热点key问题
      • 4.4.3 一致性问题

1. 一些概念

缓存作用:降低后端负载;提高性能,快速响应;注意点:缓存和数据库之间一致性问题;使用缓存需要额外编写代码;缓存需要额外维护。

缓存如何更新:内存淘汰;超时更新;主动更新

  • 低一致性数据(不经常变动的数据):内存淘汰

  • 高一致性数据(经常变动且准确性要求高的数据):主动更新+超时更新

设计一个缓存系统需要考虑的方面:工作流程的实现(应用层代码);缓存的运维(高可用);缓存层和数据库层的一致性问题;缓存的典型问题及其应对措施。

2. 主动更新策略/缓存设计模式

主动更新是指或者是应用主动更新cache,或者是db变动触发cache更新。常见主动更新的策略/缓存设计模式有:cache aside,read/write through, write back,refresh ahead。

ref: https://hazelcast.com/blog/a-hitchhikers-guide-to-caching-patterns/

2.1 cache-aside pattern(lazy loading)

工作流程:

  • 读流程:读cache -> hit则返回,miss则访问DB(读穿透缓存) -> DB返回数据给app,app写cache。注意应用层要分别和cache以及DB交互。
    在这里插入图片描述

  • 写流程:app先写cache再写DB,或者app先写DB再写cache。不过考虑直接删除缓存更好,参考第3.2节。

在这里插入图片描述

优劣势:pros:容易理解和实现;对被高频访问的数据友好。cons:不一致风险;交互环节多(受网络环境影响)。

场景:读密集;通用缓存设计。

2.2 read-through pattern(针对读操作)

工作流程:读cache -> hit则返回,miss则访问DB(读穿透缓存) -> 对于miss数据,由cache而不是app去查DB,DB向cache而不是app返回数据,最后由cache向app返回数据。注意cache和DB封装成一个服务,由这个服务来负责cache和DB的一致性。应用层只需要维护和这个服务的交互(这和cache aside pattern不同)。

在这里插入图片描述

优劣势:pros: 对应用而言,只用和缓存层交互,速度快;读伸缩性好(只用和缓存层交互,缓存层应对高频读请求的良好伸缩性得以体现)。cons: 可能存在数据不一致;cache miss时速度慢。

场景:读密集;可容忍较高cache miss延时。

2.3 write-through pattern

工作流程:应用写cache -> cache 同步地写数据到DB。

在这里插入图片描述

优劣势:pros:数据一致性好;读延时低(因为最新的数据总在cache中)。cons:写延时高;写入的数据不一定被高频读,占用cache空间;一致性风险。

场景:低频写操作;程序局部性好(写的数据很快会被访问)。

2.4 write behind pattern(write back pattern)

工作流程:应用写cache -> cache异步地写数据到DB。

在这里插入图片描述

优劣势:pros:低写延时(异步,批量写DB);cons:cache数据可能在变更到DB之前而失效;实现复杂。

场景:写密集;数据改动持久化不那么重要(数据在多次改动期间没有被访问,事实上只有最后一次改动是有意义的,只需要将最后一次改动落实到数据库中);一致性风险。

2.5 write around pattern

工作流程:应用写DB -> 应用读cache,hit则直接返回,miss则读DB --> 应用写cache。注意和cache aside的区别,

优劣势:pros:应用直接写数据到DB,降低cache层数据丢失风险;cons:高读延时;高cache miss rate。

场景:没有数据更新;低频读。

2.6 delay double delete

工作流程:数据即将发生更新时,删除缓存,后续请求直接到数据库;更新数据库;延迟一段时间以便数据库完成更新操作;延迟时间过后再删除缓存(首次删除缓存后,更新数据库之前仍可能有使用数据库旧值的请求,因而旧值缓存被重新建立,需要再次删除)。

场景:读多写少;对数据一致性要求高但允许短暂(延迟时间内)不一致。

2.7 refresh ahead

在请求前将数据库最新的数据缓存起来,即数据库只要更新,不管是否访问,都会为最新的数据创建cache。

cache asdie/read through --> cache invalidation ( set expire time ) --> remove update from app, make it external --> polling db to update cache(增加DB压力) --> DB trigger (由数据库内的事件触发而执行数据库操作,如果要执行redis操作,需要额外的系统调用;没有标准实现) --> change data capture(从mysql的append-only log中提取变化事件)

在这里插入图片描述

Debezium具备CDC特性,但以kafka为中转(kafka会持久化,有额外的磁盘IO;数据网络流通环节增加,有额外的网络IO),Hazelcast Jet基于Debezium,但可以直接写入cache,避免中转。Hazelcast Jet通过Debezium connector能够读取DB的event,并将其转换为kv格式写入cache。

在这里插入图片描述

2.8 总结

2.8.1 对于读场景

  • cache aside和read through的区别:cache miss时,需要从DB读数据并写cache,cache aside安排app完成这个任务,read through安排cache完成这个任务。

2.8.2 对于写场景

  • cache aside,write through, write behind,write behind,write around的区别:cache aside,write through和write behind都是将要更新的数据写入cache,在由cache同步数据到DB,write around是将要更新的数据先写入数据库,再更新cache。

  • write through, write behind的区别:对于cache数据更新到DB的任务,write through使用同步方式,write behind使用异步方式

2.8.3 因为数据更新而引发的cache更新

考虑到查询cache miss也会重建cache,因而往往考虑更新完DB就删除cache。参考3.2节。

3. 一个cache系统的例子

将以cache aside模式为例,这是实际项目中经常使用的模式。后续介绍三大缓存问题的实例都以cache aside为基础。

3.1 查询数据场景

def get_data(key):result = None# None means cache missing, {'key':'xxx', 'value': 'xxx'} means regular cachecache_result = get_data_cache(key)if cache_result:result = cache_result['value']return result# cache missingdb_result = get_data_db(key)  # db_result=None means data does not existif db_result:result = db_result['value']set_cache(key, result, ex=300)return result

3.2 更新数据场景(先更新DB,再删除cache,原子操作)

3.2.1 更新数据库时考虑的问题:

  • 更新数据库时选择删除缓存还是更新缓存?(删除缓存)
    • 如果多次更新数据库的期间没有查询操作,那么每次更新缓存没有意义;而采取删除缓存策略,则第一次更新数据库就删掉缓存,后续操作都不用再操作缓存,直到下一次查询才创建缓存。
  • 如何保证更新数据库和删除缓存同时成功同时失败?(原子操作)
    • 把更新数据库和删除缓存操作打包为原子操作。单体服务中可以使用进程级,线程级,协程级锁来实现,分布式服务则采用分布式事务方案(TCC)
    • 保证更新数据库和删除缓存操作的原子性,使用锁构建临界区:多线程(线程锁 threading.Lock),多进程(锁multiprocessing.Lock,带锁的数据结构multiprocessing.Value等,信号量multiprocessing.Semaphore),协程(asyncio.Lock)。
  • 先操作数据库还是先删除缓存?(先更新数据库再删除缓存)
    • 先删缓存在更新数据库的不一致情形:线程1先删除缓存,并发执行的线程2查缓存不存在,用数据库旧值创建缓存,随后线程1再执行更新数据库,此时数据库中为新值而缓存中为旧值。注意线程1的更新数据库操作是相对复杂缓慢,很有可能插入线程2的操作,因此该策略下数据不一致的情形发生概率很高。
    • 先更新数据库再删缓存的不一致情形:假设缓存失效,线程1查询缓存不命中而查数据库得到旧值,线程2再更新数据库为新值,然后再删除缓存(缓存本来就失效,相当于空操作),最后线程1使用旧值创建缓存。于是缓存为旧值,数据库为新值。注意线程1查询数据库再到更新缓存是相对简单高效的,在这两个操作极短的间隔内完成数据库更新操作概率很小,并且这个数据不一致情况要求事先缓存失效。
# cahce aside
def update_data(item, lock):if not is_validate(item):return False, 'fail to update data!'with lock:set_data_db(item)del_data_cache(key=item['id'])return True, 'update successfully!'

4. 缓存面临的问题

4.1 缓存穿透(cache penetration)

数据既不在缓冲中也不在数据库中,请求到达数据库而增大数据库压力。

  • 缓存空对象:如果访问缓存没有,数据库也没有,则创建一个空缓存(设置较短的ttl,以防大量空缓存占用内存)。实际开发中主要使用此方法。实现简单,但有一定内存开销。注意如果缓存命中,还要有判空逻辑。
  • 布隆过滤:在应用和缓存之间加一层缓存,称为布隆过滤。布隆过滤判断不存在则直接返回,布隆过滤判断存在则继续访问缓存,访问数据库,尽管数据也可能在缓存和数据库中都不存在。内存占用小但是实现复杂(可以使用redis的bitmap数据结构实现)且仍可能存在缓存穿透。
  • key的设计:增强key复杂度;增加key的格式校验过滤环节
  • key的访问:加强用户权限校验;热点数据限流
# cache-aside + cache penetration prevention
def get_data(key):result = None# None means cache missing, {'key':'xxx', 'value': 'xxx'} means regular cache, {'key':'key', 'value': None} means null cachecache_result = get_data_cache(key)if cache_result:result = cache_result['value']return result# cache missingdb_result = get_data_db(key)if db_result:result = db_result['value']set_data_cache(key, result, ex=300)return result

4.2 缓存雪崩(cache avalanche)

同一时段大量key过期(部分key失效),或者redis服务宕机(全部key失效),则大量数据访问请求到达数据库,数据库压力增大。

  • 给不同key添加随机ttl。
  • 流量控制:熔断、限流策略;业务配置多级缓存截留(浏览器 -> nginx -> redis -> jvm -> DB)。
  • 利用redis集群实现高可用,防止服务宕机带来缓存雪崩问题。

4.3 缓存击穿(cache breakdown)

也被称为热点key问题。热点key失效,导致并发数据请求到达数据库层,导致数据库执行缓慢甚至崩溃。

  • 互斥锁确保只有一个线程重建热点key缓存:对重建这种key的缓存的操作加上互斥锁,只有拿到锁的线程才能去重建它。具体过程:查询缓存未命中 --> 申请互斥锁 --> 获得锁的线程执行key缓存重建操作 --> 释放锁,其他线程查询缓存未命中 --> 申请互斥锁失败 --> 等待一会儿重新查询缓存。该方案一致性好,实现简单,没有额外内存开销,但并发性能差。
  • 逻辑过期:对于热点key不在设置过期时间,而是加上过期字段。线程1查询热点key根据过期字段发现过期,于是申请并得到互斥锁后开启线程2来独立地执行热点key更新操作(该线程更新完毕后会释放互斥锁),线程1随后返回旧的缓存值。线程2还未执行完毕,线程3访问热点key缓存,发现过期,申请互斥锁失败(说明有人在更新热点key缓存了),返回旧的缓存值。该方案并发性能好,但是实现复杂,有额外内存开销,一致性差。
  • 热点key过期时间:不过期;续期。
  • 多级缓存:通过本地缓存,api网关缓存来减少对服务端缓存的依赖。

4.3.1 如何使用互斥锁来应对缓存击穿问题

使用redis中setnx命令(如果key不存在才执行成功,key存在的话则执行失败),多个线程同时执行setnx,只有第一个执行的线程能够执行成功,其他线程都执行失败,这可以模拟获取互斥锁。使用del来实现释放锁。注意给互斥锁添加过期时间,避免释放锁出问题而一致不释放锁。

# cache-aside + cache penetration prevention + cache breakdown prevention
def request_mutex_lock(key):# 互斥锁过期时间300s,以防持有者不释放锁导致死锁result = redis_client.SETNX(key, 1, ex=600)return resultdef release_mutex_lock(key):redis_client.DEL(key)def get_data(key):result = None# None means cache missing, {'key':'xxx', 'value': 'xxx'} means regular cache, {'key':'key', 'value': None} means null cachecache_result = get_data_cache(key)if cache_result:result = cache_result['value']return result# cache missingmutex_lock = request_mutex_lock(key)  # rebuild key needing lock firstif mutex_lock == 0:# fail to get mutex lock, wait a while and retrytime.sleep(0.1)return get_data(key)# rebuild cachedb_result = get_data_db(key)if db_result:result = db_result['value']set_data_cache(key, result, ex=300)release_mutext_lock(key)return result

4.3.2 如何使用逻辑过期应对缓存击穿问题

创建key时不用设置过期时间,依赖value中中ex字段来判断是否过期。

# cache-aside + cache penetration prevention + cache breakdown prevention
def request_mutex_lock(key):# 互斥锁过期时间300s,以防持有者不释放锁导致死锁result = redis_client.SETNX(key, 1, ex=600)return resultdef release_mutex_lock(key):redis_client.DEL(key)def rebuild_cache(key):db_result = get_data_db(key)if db_result:result = db_result['value']set_data_cache(key, result)  # 不再设置key的ex,依赖逻辑exrelease_mutext_lock(key)def get_data(key):result = None# None means cache missing, {'key':'xxx', 'value': 'xxx'} means regular cache, {'key':'key', 'value': None} means null cachecache_result = get_data_cache(key)result = cache_result['value']ex = cache_result['ex']if ex <= time.now():return result# cache missingmutex_lock = request_mutex_lock(key)  # rebuild key needing lock firstif mutex_lock == 0:# fail to get mutex lock, wait a while and retryreturn result# rebuild cachethread_pool.submit(rebuild_cache(key))return result

4.4 缓存系统设计的其他问题

4.4.1 读扩散和写扩散问题

  • 读扩散:数据更新后还没同步到其他结点,读出来的是旧值。本质是数据复制延迟带来不一致。
  • 写扩散:数据更新后同步到其他结点的过程。本质是通过冗余写换取读性能提升。

4.4.2 redis热点key问题

  • 识别:INFO命令;redis 监控工具
  • 解决:让hot key使用更合适的数据结构(hot key有序存多个元素,考虑使用sorted set而不是list);压缩值降低网络带宽压力;使用客户端侧缓存;服务端使用redis + mencached;
  • ref: https://abhivendrasingh.medium.com/understanding-and-solving-hotkey-and-bigkey-and-issues-in-redis-1198f98b17a5

4.4.3 一致性问题

单体架构下cache和DB一致性问题: 传统缓存设计模式无法保证一致性。要保证一致性只能加锁(做成读者-写者模型)。

分布式架构下cache和DB一致性问题:分布式锁;CDC

相关文章:

【Redis】基础2:作为缓存

文章目录 1. 一些概念2. 主动更新策略/缓存设计模式2.1 cache-aside pattern&#xff08;lazy loading&#xff09;2.2 read-through pattern&#xff08;针对读操作&#xff09;2.3 write-through pattern2.4 write behind pattern&#xff08;write back pattern&#xff09;…...

豆包,Kim,deepseek对比

以下是豆包、Kimi、DeepSeek的对比与应用&#xff1a; 对比 - 核心技术&#xff1a;DeepSeek-R1完全依赖强化学习驱动&#xff0c;跳过监督微调阶段。Kimi k1.5采用“轻量级SFT预热RL优化”的混合策略。 - 多模态支持&#xff1a;Kimi k1.5支持文本与图像的多模态联合推理。De…...

L2-005 集合相似度

L2-005 集合相似度 - 团体程序设计天梯赛-练习集 给定两个整数集合&#xff0c;它们的相似度定义为&#xff1a;Nc​/Nt​100%。其中Nc​是两个集合都有的不相等整数的个数&#xff0c;Nt​是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。 …...

33.状态压缩动态规划

一、算法内容 1.简介 若元素数量比较小&#xff08;不超过 20 20 20&#xff09;时&#xff0c;想要存储每个元素取或不取的状态时&#xff0c; 可以借助位运算将状态压缩。 需要借助状态压缩过程的动态规划就是状态压缩 DP&#xff08;很多地方会简称为状压 DP&#xff09;…...

WSL 中 nvidia-smi: command not found的解决办法

前言 在使用基于 Linux 的 Windows 子系统&#xff08;WSL&#xff09;时&#xff0c;当我们执行某些操作后&#xff0c;可能会遇到输入 nvidia-smi 命令却无法被系统识别的情况。 例如&#xff0c;在终端中输入nvidia-smi 后&#xff0c;系统返回提示 -bash: nvidia-smi: co…...

Linux 进程控制

文章目录 1. 进程创建1.1 fork1.2 写时拷贝 2.进程终止2.1 退出码2.2 进程如何返回退出码 3. 进程等待3.1 wait3.1.1 阻塞等待3.1.2 退出码与退出信号 3.2 waitpid 1. 进程创建 1.1 fork 我们可以使用fork函数来创建子进程&#xff0c;创建子进程后&#xff0c;父子进程之间就…...

使用MobaXterm远程登录Ubuntu系统:SSH服务配置教程

一、MobaXterm介绍 MobaXterm官网&#xff1a;https://mobaxterm.mobatek.net/ MobaXterm类似于Xshell&#xff0c;是一个工具箱&#xff0c;功能比Xshell多。 直接去官网下载安装就可以&#xff0c;本文主要介绍开启Ubuntu的ssh服务&#xff0c;并通过MobaXterm实现远程登录…...

直线模组精度测试的标准是什么?

直线模组的精度测试是确保其性能和稳定性的重要环节。那么&#xff0c;大家知道直线模组精度测试的标准是什么吗&#xff1f; 1、定位精度&#xff1a;以最大行程为基准长度&#xff0c;用从基准位置开始实际移动的距离与指令值之间的最大误差的绝对值来表示。一般来说&#xf…...

RK3568 Debian调试记录

文章目录 1、环境介绍2、前言3、debian目录结构3.1、脚本调用顺序 4、编译debian4.1、构建debian编译所需的环境4.2、编译debian4.3、打包 5、系统启动6、debian适配6.1、新增板级配置单6.2、USB6.3、Wi-Fi / BT6.4、屏幕旋转6.5、触摸旋转6.6、时钟 7、测试8、总结 1、环境介绍…...

来自 Bisheng 关于微调的内容总结

来自 Bisheng 关于微调的内容总结 0. 引言1. 关于微调的总结 0. 引言 这篇文章的内容&#xff08;主要是截图&#xff09;是来自 Bisheng 关于微调的内容总结&#xff0c;内容来源于 B 站Up主七吟覃_BISHENG负责人的视频&#xff0c;感兴趣的可以观看原视频。 1. 关于微调的总…...

Git 工具的安装

目录 Git 工具介绍 Git 工具安装 创建本地仓库 配置本地仓库 Git 版本控制基本原理 本期开始&#xff0c;我们将学习如何使用 Git 工具&#xff0c;实现多版本控制。 Git 工具介绍 要了解 Git 工具我们得先了解版本控制器的概念。 有这样一个场景&#xff0c;如下图所…...

任务管理系统,Java+Vue,含源码与文档,科学规划任务节点,全程督办保障项目落地提效

前言&#xff1a; 在当今快节奏的工作环境中&#xff0c;高效的任务管理是确保项目按时完成、资源合理分配及团队协作顺畅的关键。任务管理系统作为提升工作效率的重要工具&#xff0c;通过数字化手段帮助用户组织、跟踪和完成各类任务。本文将详细阐述任务管理系统的五大核心…...

JavaScript基础知识合集笔记1——数据类型

文章目录 JavaScript中的数据类型基本数据类型引用类型存储区别 JavaScript中的数据类型 基本数据类型和复杂类型 基本数据类型 基础类型包含六种&#xff1a;Number、Bigint、String、Boolean、Undefined、null、symbol Number(特殊值NaN&#xff0c;意为“不是数值”) c…...

2025.04.26-美团春招笔试题-第四题

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 04. 图像智能降维处理 问题描述 卢小姐是一家图像处理公司的算法工程师,她正在开发一种高效的图像压缩算法。该算法基于奇异值分解(SVD)技术,通过保留图像矩阵中最重要的特征,在…...

测试基础笔记第十三天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、流程控制语句-判断语句1.判断语句2.逻辑运算符3.elif多重判断4.if的嵌套5.if与逻辑运算符结合1.and2.or3.not 设计测试用例二、流程控制语句-循环语句1.while语…...

【昇腾】PaddleOCR转om推理

文章目录 1. 使用Paddle框架推理1.1 安装1.2 推理 2. paddle 转 ONNX3. 转om4. Ais_bench 命令推理5. Ais_bench 编写推理代码 概要&#xff1a; PyTorch官方提供了昇腾插件包&#xff0c;安装后虽然可以支持PytorchOCR和PaddlePaddle的推理任务&#xff0c;但性能通常低于GPU。…...

【数据融合】基于拓展卡尔曼滤波实现雷达与红外的异步融合附matlab代码

一、问题分析与技术难点 1. 传感器特性对比 传感器测量维度优势局限性噪声模型雷达距离 $ r $、方位角 $ \theta $、速度 $ v $测距精度高、全天候工作角度分辨率低、易受多径干扰高斯噪声&#xff0c;协方差矩阵 $ R_r \text{diag}(\sigma_r^2, \sigma_\theta^2, \sigma_v^…...

第一部分:网页的骨架 —— HTML

这目录 前言1. 初识 HTML&#xff1a;搭建地基和框架1.1 小例子&#xff1a; 创建一个最简单的 HTML 页面&#xff0c;包含 "Hello World"。1.2 练习 2. 常用文本与内容标签&#xff1a;填充墙体和房间2.1 小例子&#xff1a; 创建一个包含个人简介&#xff08;使用标…...

RTMP 协议解析 1

介绍 &#x1f4d6; 什么是 RTMP&#xff1f; RTMP协议&#xff08;Real-Time Messaging Protocol&#xff0c;实时消息传输协议&#xff09;是由Adobe公司&#xff08;最初由Macromedia开发&#xff09;设计的一种用于实时传输音频、视频和数据流的网络协议&#xff0c;主要…...

c++初始化数组

1.前言 话说数组是n年前的事了&#xff0c;我为啥现在又提到它呢&#xff1f;因为很多人不会初始化数组&#xff0c;所以今天我来教教大家 2.初始化数组 初始化数组就是定义数组&#xff0c;就像这样 int a[5]{0}; 这样是a[0]到a[5]全都等于0 如果要输出这个数组&#xf…...

支持Win和Mac的批量图片压缩方法

软件介绍 如果你的图片太大&#xff0c;传输或上传总是卡壳&#xff0c;那就需要一款好用的图片压缩工具了。今天推荐的这款工具支持Windows和Mac双系统&#xff0c;简直是图片压缩界的"变形金刚"&#xff01; 图压&#xff08;图片压缩双系统版&#xff09; …...

autodl(linux)环境下载git-lfs等工具及使用

一、git-lfs工具下载 #初始化git.lfs命令 curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs git lfs install 二、 huggingface-cli工具下载及使用 Linux设置huggingface的镜像&#xff1a; ex…...

云原生--核心组件-容器篇-3-Docker核心之-镜像

1、定义与作用 定义&#xff1a; Docker镜像是一个只读的模板&#xff0c;包含运行应用程序所需的所有内容&#xff0c;包括代码、依赖库、环境变量、配置文件等。简单来说&#xff0c;Docker镜像是一个轻量级、独立、可执行的软件包&#xff0c;它包含了运行某个软件所需的所有…...

Dify与n8n深度对比:AI应用开发与自动化工作流的双轨选择

Dify与n8n深度对比&#xff1a;AI应用开发与自动化工作流的双轨选择 在数字化转型加速的2025年&#xff0c;Dify和n8n作为两大主流工具&#xff0c;分别代表了AI应用开发与自动化工作流领域的顶尖解决方案。本文将从核心定位、功能特性、使用场景等维度展开对比&#xff0c;为…...

AI算法优化建筑形态与能耗管理 实现方案和技术架构

以下是基于AI算法优化建筑形态与能耗管理的实现方案与技术架构,结合行业实践与前沿技术趋势,分层次解析核心要素及实施路径: 一、技术架构设计 1. 数据采集与感知层 多源数据融合 传感器网络:部署温湿度、CO₂浓度、光照、人流密度等传感器,构建实时数据采集体系(如北京…...

【互联网架构解析】从物理层到应用层的全栈组成

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现&#xff08;Python网络请求&#xff09;运行结果验证 三、性能对比测试方法论量化数据对比结果分…...

Redis和MQ的区别

redis是一个高性能的key-value数据库&#xff0c;支持消息推送功能&#xff0c;可以当做一个轻量级的队列服务器使用。 redis只是提供一个高性能的、原子操作内存键值队&#xff0c;具有高速访问能力&#xff0c;虽然可以做消息队列的存储&#xff0c;但不具备消息队列的任何功…...

多系统安装经验,移动硬盘,ubuntu grub修改/etc/fstab 移动硬盘需要改成nfts格式才能放steam游戏

笔记本一个系统&#xff0c;移动硬盘两个系统&#xff0c;当前系统sda4.jpg 移动硬盘需要再装一个linux会有boot/efi&#xff0c;启动的时候grub界面才能识别&#xff0c;单linux没有efi别的电脑识别不到 没efi甚至启动不了grub 按下f6.jpg 看看笔记本grub能不能识别得到移动硬…...

4.26学习——web刷题

把攻防世界的web做了20道左右&#xff0c;挑了几道学到东西的题目记录一下 攻防世界warmup 进到环境中读取源代码发先有个提示&#xff1a;source.php&#xff0c;进去看看 <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$wh…...

Go 语言中的实时交互式编程环境

在 Go 语言中&#xff0c;确实有几种方法可以实现类似 Python REPL 的实时交互式编程体验&#xff0c;让你可以实时编写代码并查看输出&#xff0c;而无需每次都编译运行整个程序。 但是需要注意的是&#xff0c;由于 Go 是编译型语言&#xff0c;完全的实时交互体验不如解释型…...

动态规划求解leetcode300.最长递增子序列(LIS)详解

给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1&#…...

冯·诺依曼和哈佛架构​​​​两种架构的总线组成及核心特点

在计算机体系结构中&#xff0c;哈佛架构和冯诺依曼架构是两种不同的存储与总线设计范式&#xff0c;它们的总线组成和访问方式有显著差异。以下是两种架构的总线组成及核心特点的详细分析&#xff1a; 1. 冯诺依曼架构&#xff08;Von Neumann Architecture&#xff09; 核心…...

7.学习笔记-Maven进阶(P75-P89)-进度(p75-P80)

1.MAVEN-01-分模块开发的意义 &#xff08;一&#xff09;分模块开发意义 模块可以按功能划分&#xff0c;也可以按团队划分&#xff0c;所以把domain的方法抽取出来&#xff0c;进行共享&#xff0c;从而提高开发 的效率。 &#xff08;1&#xff09;分模块开发的意义&#xf…...

Java——令牌技术

目录 一、何为令牌 JWT令牌 介绍 JWT组成 二、JWT用于验证用户登录 三、JWT令牌生成和校验 简单用法 1.创建生成密钥的方法 2.接着添加过期时间&#xff0c;密钥&#xff0c;BASE64解码密钥的属性以及生成token的方法&#xff0c;合并上面生成密钥的方法&#xff0c;下面…...

【含文档+PPT+源码】基于Python校园跑腿管理系统设计与实现

项目介绍 本课程演示的是一款基于Python校园跑腿管理系统设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Python学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.…...

Spring AI Alibaba - Milvus 初体验,实现知识库效果

先看效果 数据被存储在 milvus 中&#xff0c;包括原始数据和向量数据。 大模型使用向量化数据的回答&#xff1a; 环境准备 安装 milvus Milvus 是一款专为向量相似性搜索设计的高性能开源数据库。 本地测试环境可以直接 Standalone 模式安装&#xff0c;需要用到 docke…...

arcpy列表函数的应用

arcpy.ListDatasets() 该函数用于列出指定工作空间中的所有数据集&#xff08;如要素数据集、栅格数据集等&#xff09;。 语法&#xff1a; python arcpy.ListDatasets(wild_cardNone, feature_typeNone) • wild_card&#xff1a;用于筛选数据集名称的通配符。 • feat…...

上位机知识篇---时钟分频

文章目录 前言 前言 本文简单介绍了一下时钟分频。时钟分频&#xff08;Clock Division&#xff09;是数字电路设计中常见的技术&#xff0c;用于将高频时钟信号转换为较低频率的时钟信号&#xff0c;以满足不同模块的时序需求。它在处理器、FPGA、SoC&#xff08;片上系统&am…...

Redis的两种持久化方式:RDB和AOF

Redis持久化概述 Redis作为内存数据库&#xff0c;数据存储在内存中。为了保证数据在服务器重启或宕机时不丢失&#xff0c;Redis提供了两种持久化方案&#xff1a; RDB&#xff08;Redis Database&#xff09;&#xff1a;定时生成内存快照 AOF&#xff08;Append Only File&…...

1位的推理框架bitnet.cpp

源码&#xff1a;https://github.com/microsoft/BitNet bitnet.cpp 技术解析 ‌bitnet.cpp‌ 是专为 ‌低精度大语言模型&#xff08;如 BitNet b1.58&#xff09;‌ 设计的官方推理框架&#xff0c;其核心特性如下&#xff1a; 一、架构优势 ‌全栈优化引擎‌ 提供高度优化…...

教育领域的AIGC革命:构建多模态智能教学系统

一、智能教育系统技术架构 1.1 教育场景技术需求 教学环节 传统痛点 AIGC解决方案 课程设计 耗时耗力&#xff0c;创新不足 跨学科教案自动生成 课堂互动 单向传授&#xff0c;参与度低 多模态交互式虚拟教师 作业批改 重复劳动&#xff0c;反馈延迟 全自动批改与个性化评语 学…...

Simulink 数据存储机制:Base Workspace、Model Workspace 与 Data Dictionary 的核心区别

1. 核心定位与设计目标 存储方式本质核心设计目标Base WorkspaceMATLAB全局内存空间临时数据交互&#xff0c;快速原型开发Model Workspace模型私有数据容器模型数据隔离&#xff0c;防止命名冲突Data Dictionary专业数据管理文件(.sldd)复杂系统数据治理&#xff0c;支持团队…...

TI---UART通信

一、SysConfig 中 UART 配置的核心参数与生成逻辑 1. 基础参数配置&#xff08;图形化界面&#xff09; 配置项功能说明生成代码影响模式选择主机模式&#xff08;Master&#xff09;/ 从机模式&#xff08;仅部分芯片支持&#xff0c;如 UART 作为 I2C 桥接&#xff09;生成…...

spark总结

文章目录 一 spark简介1.1 什么是spark1.2 spark运行过程1.2.1 组成1.2.2 过程1.2.3 事例&#xff08;词频统计WordCount程序&#xff09; 1.3 spark运行模式1.4 pyspark 二 SparkCore2.1 RDD介绍2.2 RDD编写2.3 RDD算子2.4 RDD的持久化2.4.1 为什么需要缓存和检查点机制&#…...

【随笔】地理探测器原理与运用

文章目录 一、作者与下载1.1 软件作者1.2 软件下载 二、原理简述2.1 空间分异性与地理探测器的提出2.2 地理探测器的数学模型2.21 分异及因子探测2.22 交互作用探测2.23 风险区与生态探测 三、使用&#xff1a;excel 一、作者与下载 1.1 软件作者 作者&#xff1a; DOI: 10.…...

补码底层逻辑探讨

在计算机里面以二进制进行存储&#xff0c;二进制并不能区分正负数 为了处理负数&#xff0c;人们想了很多办法 1.原码 首先&#xff0c;很直观的区分方法就是设置一个flag 在二进制前面加一个符号位&#xff0c;0是正、1是负 但是在电路里面处理这样的信号却很复杂&#…...

第二大脑-个人知识库

原文链接:https://i68.ltd/notes/posts/20250407-llm-person-kb/ Quivr-第二大脑一样的个人助手&#xff0c;利用AI技术增强个人生产力 将 GenAI 集成到您的应用程序中的个性化 RAG,专注于您的产品而非 RAG项目仓库:https://github.com/QuivrHQ/quivr Star:37.7k官网:https:/…...

泰勒展开概念解释(图优化SLAM中非线性系统的线性处理)

1. 泰勒展开 泰勒展开是一种用多项式近似复杂函数的数学方法,其核心思想是通过函数在某一点的各阶导数信息,构建一个多项式来逼近原函数,即通过函数在某一点x0的各阶导数值,构造一个多项式 P(x),使得该多项式在 x0 附近与原函数 f(x) 的值及其导数尽可能匹配,数学形式为…...

CANape与MATLAB数据接口技术详解

目录 CANape与MATLAB数据接口技术详解 一、数据互操作背景与意义 1.1 汽车电子开发中的测量需求 1.2 技术标准演进分析 二、CANape数据导出深度解析 2.1 MDF文件结构说明 2.2 转换流程优化建议 三、MATLAB数据处理进阶技术 3.1 数据质量评估脚本 3.2 数据可视化增强方…...

per-task affinity 是什么?

Per-Task Affinity&#xff08;任务级CPU亲和性&#xff09;详解 Per-Task Affinity 是 Linux 调度器提供的一种机制&#xff0c;允许将单个任务&#xff08;进程/线程&#xff09;绑定到特定的 CPU 核心&#xff08;或核心集合&#xff09;上运行&#xff0c;从而优化性能、减…...