一、redis-万字长文读懂redis
高性能分布式缓存Redis
- `第一篇章`
- 1.1缓存发展史&缓存分类
- 1.1.1 大型网站中缓存的使用
- 带来的问题
- 1.1.2 常见缓存的分类及对比
- 与memcache对比
- 1.2 数据类型选择&应用场景
- 1.2.1 string
- 1.2.2 hash
- 1.2.3 链表
- 1.2.4 set
- 1.2.5 sortedset有序集合类型
- 1.2.6 总结
- 1.3 Redis高级应用&拓展功能
- 1.3.1 发布订阅
- redis提供发布订阅功能,可用于消息的传输
- 指令详情
- 使用场景
- 1.3.2 事务
- redis事务支持回滚吗
- redis 事务
- 1.3.2 lua脚本
- 1.3.3 慢查询日志
- `第二篇章`
- 2.1 持久化原理
- 2.1.1 原理
- 2.1.2 持久化流程
- 2.1.3 RDB
- 概念
- 特点
- 触发方式:指令手动触发和redis.conf自动触发
- RDB优势
- RDB劣势
- 2.1.4 AOF
- 概念
- 特点
- AOF持久化实现
- AOF重写原理
- 持久化优先级
- 2.1.5 降低fork阻塞
- 2.1.6 实践中的其它策略
- 2.2 过期删除策略
- 2.2.1 问题分析
- 1. 如何设置过期时间
- 2. 如何盘判定key已过期
- 3. 过期删除策略有哪些
- 4. Redis过期删除策略是什么
- 2.3 内存淘汰策略
- 2.3.1 概念
- 2.3.2 如何设置Redis的最大运行内存
- 2.3.3 Redis的八种内存淘汰策略
- 2.3.4 LRU算法和LFU算法有什么区别
- LRU传统算法
- Redis中的LRU算法
- LFU算法
- redis中LFU算法
- 2.4 Redis高可用
- 2.4.1 主从复制的出现
- 2.4.2 主从复制结构
- 2.4.3 主从复制实现
- 2.4.4 sentinel 哨兵模式
- 哨兵的出现
- 客观下线
- 哨兵挂了怎么办
- 2.4.5 主从+哨兵存在的问题
- `第三篇章`
- 3.1 分布式锁
- 何为分布式锁
- 分布锁的特点
- 如何设计一把良好的锁
- 3.2 布隆过滤器(BloomFilter)
- 3.3 Redis Cluster
- `第四篇章-FAQ`
- 4.1 如何保持缓存和数据库的一致性
- ==总结==
- 1)为什么使用redis来做缓存
- 2)缓存策略带来的问题
- 3)导致数据不一致原因
- 4)并发引起的一致性问题
- 5)删除缓存可以保证一致性吗
- 6)如何保证两步都执行成功
- 7)主从库延迟和延迟双删策略
- 8)保证更新数据库和删除缓存都能成功
- 4.2 redis是单线程架构还是多线程架构
- 4.3 单线程的redis为什么这么快
- 4.4 Redis6.x之后为何引入了多线程?
- 4.5 缓存穿透\缓存击穿\缓存雪崩
- 4.6 为什么用 Redis 作为 MySQL 的缓存?
- 4.7 Redis 如何实现数据不丢失?
第一篇章
1.1缓存发展史&缓存分类
1.1.1 大型网站中缓存的使用

分析:直接从数据库中的数据,是存储在磁盘中的,需要多次的IO,而且请求数据库是基于TCP连接,单机的mysql qps 1W+,而redis的qps达到10w+;所以可以在Tomcat和mysql中加入屏障,将热点数据放入redis,非热点数据放入数据库中,流程如下

带来的问题
- 读写缓存策略
- 读写穿透
- 异步缓存写入
- 数据库和缓存如何保证数据一致性
- 写策略
- 先更新缓存,再删除缓存
- 先删除缓存,再更新数据库
- 写策略
1.1.2 常见缓存的分类及对比
与memcache对比
共同点:
- 都是基于内存的数据库,一般都用来当做缓存使用。
- 都有过期策略。
- 两者的性能都非常高。
区别:
- Redis 支持的数据类型更丰富(String、Hash、List、Set、zset),而 Memcached 只支持最简单的 key-value 数据类型;
- Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memcached 没有持久化功能,数据全部存在内存之中,Memcached 重启或者挂掉后,数据就没了
- Redis 原生支持集群模式,Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;
- Redis 支持发布订阅模型、Lua 脚本、事务等功能,而 Memcached 不支持
所以,很少使用memcached了
1.2 数据类型选择&应用场景
- 常见的五种数字类型:string、hash、list、set、zset
1.2.1 string
- redis并不是简单的使用c的string,而是构建了简单动态字符串,不光可以保存文本数据还可以保存二进制,并且获取字符串的长度为0
- 常用命令:set,get,strlen,exists
- 应用场景:缓存对象、常规计数、分布式锁、共享session
- 对象缓存:直接缓存整个对象的json
- 分布式锁:setnx product:10001 true;setnx product:10001 false
1.2.2 hash
- key-value,适合存储
- 适合做对象缓存
电商购物车
用户id为key;商品id为field;商品数量为value;Hest cart:1 1001 1 //向id为1的商品1001添加1间商品
- 适合做对象缓存
1.2.3 链表
- c的链表查询比较难,所以redis使用了双向链表,支持反向查找和遍历,更方便操作,不过带了了额外的内存开销
- 内部实现:quicklist
- 常用命令:rpush、lpop、lpush
- 应用场景:发布与订阅或者说消息队列,慢查询

- 常用数据结构
- Stack(栈)=LPUSH(左边放)+LPOP(左边取)–> FILO
- Queue(队列)=LPUSH(左边放)+RPOP右边取)
- BLocking queue(阻塞队列)=LPUSH(左边放)+ BRPOP(右边阻塞取:没有数据就阻塞!)
- 实现微波朋友圈等的关注列表显示
- 实现后发的消息在列表中最上方展示
- 小明关注了北京本地宝,京城美味君等公众号,这些订阅号发布消息时,通过推或拉的方式把消息LPUSH放入redis中属于小明的list中。其中key为msg:{小明D}。当小明要获取大V们发的消息时,使用LRANGE 命令从队列中获取指定个数的订阅号信息
Lpush msg:1 1001 //1001是北京本地宝,mag:1是小明的id
Lpush msg:1 1002
显示的结果是1002先显示
1.2.4 set
- 是一个无序并唯一的键值集合,它的存储顺序不会按照插入的先后顺序进行存储。一个集合最多可以存储 2^32-1 个元素。概念和数学中个的集合基本类似,可以交集,并集,差集等等,所以 set 类型除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集
- 底层实现:哈希表或整数集合
- 常用命令: sadd,spop,smembers,sismember,scard,sinterstore,sunion 等
- 应用场景: 需要存放的数据不能重复以及需要获取多个数据源交集和并集等场景
1.2.5 sortedset有序集合类型
- 介绍:zset 类型(有序集合类型)相比于 Set 类型多了一个排序属性 score(分值),对于有序集合zSet 来说,每个存储元素相当于有两值组成的,一个是有序集合的元素值,一个是排序值。
- 内部实现:压缩列表或跳表
- 常用命会: zadd,zcard,zscore,zrange,zrevrange,zrem等
- 应用场景: 需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息。
1.2.6 总结

1.3 Redis高级应用&拓展功能
1.3.1 发布订阅
redis提供发布订阅功能,可用于消息的传输
redis的发布订阅包含三个部分,publisher(redis客户端),subscriber(redis客户端)、channel(服务器)

指令详情
- SUBSCRIBE/PSUBSCRIBE:订阅,精确、或者按匹配符UNSUBSCRIBE/PUNSUBSCRIBE:退订,精确、或者按匹配
- PUBLISH:发送;PUBSUB:查看消息列表
使用场景
- 在Redis哨兵模式中,哨兵通过发布与订阅的方式与Redis主服务器和Redis从服务器进行通信Redisson是一个分布式锁框架,在Redisso
- 分布式锁释放的时候,是使用发布与订阅的方式通知的注:重业务的消息,推荐用消息队列
1.3.2 事务
redis事务支持回滚吗
所谓事务,是指作为单个逻辑工作单元执行的一系列操作
mysql在执行事务时,会提供回滚机制,当事务执行发生错误时,事务中的所有操作都会撤销,已修改的数据也会被恢复到事务执行前的状态,但是redis并没有提供回滚机制,redis事务不一定能保证原子性
redis 事务
redis事务的本质是一组命令的集合:单词执行多个命令,一次性、排他性、顺序性
- redis事务是通过multi、exec、discrd、watch这四个命令来完成的
- redis的单个命令都是原子性的,所以这里需要确保事务的对象是命令集合
- redis将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行
- redis不能保障失败回滚
原理刨析:
在exec执行事务的一瞬间,判断监控的key是否变动
变动则取消事务队列,直接不执行
无变动则执行,提交事务

1.3.2 lua脚本
redis+lua脚本保持原子性
- lua是一种轻量小巧的脚本语言用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
- Lua应用场景
- 游戏开发、独立应用脚本、web应用脚本、查询库存扣减库存
- Nginx+lua开发高性能web应用,限流、防止Sql注入
时间复杂度:取决于执行的脚本。
- 使用Lua脚本的好处:
- 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。原子操作。redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无换事务。
- 复用。客户端发送的脚本会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。
1.3.3 慢查询日志
日常使用redis为什么要用慢查询日志
客户端请求的生命周期的完整生命周期,4个阶段
慢查询只统计步骤3的时间

- 在生产环境中,慢查询功能可以有效地帮助我们找到Redis可能存在的瓶颈,但在实际使用过程中要注意以下几点:
- slowog-max-en:线上建议调大慢查询列表,记录慢査询时Redis会对长命令做阶段操作,并不会占用大量内存,增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000以上.
- 2slowlog-log-slower-than:默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值,慢查询只记录命令的执行时间,
并不包括命令排队和网络传输时间,因此客户端执行命令的时间会大于命令的实际执行时间,因为命2令执行排队机制,慢查询会导致其他命令级联阻塞,因此客户端出现请求超时时,需要检査该时间点是否有对应的慢查询,从而分析是否为慢查询导致的命令级联阻塞.
第二篇章
2.1 持久化原理
2.1.1 原理
redis是内存数据,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将redis中方的数据以某种形式从内存
相关文章:
一、redis-万字长文读懂redis
高性能分布式缓存Redis `第一篇章`1.1缓存发展史&缓存分类1.1.1 大型网站中缓存的使用带来的问题1.1.2 常见缓存的分类及对比与memcache对比1.2 数据类型选择&应用场景1.2.1 string1.2.2 hash1.2.3 链表1.2.4 set1.2.5 sortedset有序集合类型1.2.6 总结1.3 Redis高级应…...
搞清楚[继承],易如反掌
穷不失义,达不离道。——孔丘《论语》 继承 1、简单理解2、继承2、1、继承的概念2、2、继承定义2、3、基类和派生类对象赋值转换2、4、继承中的作用域2、5、派生类默认成员函数2、6、继承中的特点2、6、1、友元2、6、2、静态成员2、6、3、菱形继承及菱形虚拟继承 3、…...
Perl 语言入门学习指南:探索高效脚本编程的奥秘
引言 Perl,全称Practical Extraction and Report Language,是一种功能强大的编程语言,特别擅长于文本处理、报告生成以及系统自动化管理任务。自1987年诞生以来,Perl凭借其灵活性、强大的内置功能库和广泛的社区支持,…...
【HTML】-解决页面内容无法选择、复制问题
目录 1、网页内容无法选中 1.1、问题原因 1.2、解决脚本 1.2.1、开启控制台窗口 1.2.2、执行脚本命令 2、内容复制弹出阻止框 2.2、解决脚本 1、网页内容无法选中 1.1、问题原因 今天在访问某一网站平台,需要将内容进行选择、复制时发现不可使用。 在使用…...
C#中委托与事件
一、委托 在面向对象中,我们可以将任何数据类型作为参数传递给方法,能否将一个方法作为参数传递给另一个方法?C#中通过委托可以实现将方法作为参数进行传递。 1.1概念 委托是一种引用类型,它可以用于封装并传递方法作为参数。委…...
通用后台管理(二)——项目搭建
目录 前言 一、安装vue-cli依赖 1、使用yarn下载vue-cli 2、使用npm下载 3、检查一下是否下载成功 二、创建项目 1、创建项目,my-app是项目名称 2、 这里选择vue 2,蓝色表示选中的。 3、启动项目 三、下载项目依赖 四、配置项目 1、修改esli…...
多模态大模型之达摩院通义MPLUG
引言 随着人工智能技术的飞速发展,多模态技术逐渐成为研究的热点。它结合了文本、图像、声音等多种数据类型,为机器理解世界提供了更丰富的视角。本文根据严明老师的达摩院通义MPLUG多模态预训练技术分享,及其在电商等行业的应用实践&#x…...
文章翻译记录
以 PINN 为基础,我们开发了一个框架,用于在不同震源位置和速度模型下进行地震建模。本研究的显著贡献包括: 1. 为了提高网络对不同速度模型的泛化能力,必须将速度变量 vp 作为系统的输入参数。本研究从监督学习中汲取灵感…...
C++ 语法习题(2)
第三讲 循环语句 1.偶数 编写一个程序,输出 1 到 100之间(包括 1 和 100)的全部偶数。 输入格式 无输入。 输出格式 输出全部偶数,每个偶数占一行。 输入样例 No input输出样例 2 4 6 ... 100 参考代码: #include <i…...
使用Gstreamer时遇到WARNING: erroneous pipeline: no element “x264enc“(亲测有效)
WARNING: erroneous pipeline: no element “x264enc” 解决: 我下了gstreamer1.0-plugins-ugly包就解决了 sudo apt install -y gstreamer1.0-plugins-ugly...
SAP 新增移动类型简介
在SAP系统中新增移动类型的过程涉及多个步骤,包括复制现有的移动类型、调整科目设置以及进行必要的测试。以下是新增移动类型的一般步骤和关键点: 复制现有的移动类型: 使用事务代码OMJJ进入移动类型维护界面。 勾选移动类型 这里不填写移动类型,然后直接下…...
SQL性能优化策略
发现问题 通过业务监控发现慢SQL或接口响应延迟。利用性能分析工具定位问题。 定位SQL语句 使用监控工具确定影响性能的SQL语句和表。 SQL查询变慢原因 索引失效:查询未使用索引或索引效率低。多表连接:JOIN操作导致性能下降。查询字段过多…...
代码随想录第四十八天 | 198.打家劫舍, 213.打家劫舍II,337.打家劫舍III
198.打家劫舍 看完想法:这里的偷/不偷,和背包问题中的放/不放感觉是一个道理,所以在dp递推公式中仍旧使用max(dp[i-2] nums[i], dp[i-1]) int rob(vector<int>& nums) {vector<int> dp(nums.size()1,0);if(nums.size()0) …...
C#实用的工具类库
Masuit.Tools Masuit.Tools大都是静态类,加密解密,反射操作,树结构,文件探测,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载…...
首席数据官CDO证书报考指南:方式、流程、适考人群与考试难度
在信息泛滥的今天,数据已转变为企业不可或缺的宝贵资源。 面对海量的信息,如何提炼出价值,为企业带来实质性的收益?首席数据官(CDO)认证的出现正是为了满足这一需求,它不仅是个人专业能力的体现…...
数据库基础复习
数据库简介 关系型数据库:Mysql 、Oracle 、SqlServer.... DB2 达梦 非关系型数据库:Redis 、MongoDB... MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管…...
探索AI大模型(LLM)减少幻觉的三种策略
大型语言模型(LLM)在生成文本方面具有令人瞩目的能力,但在面对陌生概念和查询时,它们有时会输出看似合理却实际错误的信息,这种现象被称为“幻觉”。近期的研究发现,通过策略性微调和情境学习、检索增强等方…...
【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十三章 Linux连接档
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...
鸿蒙语言基础类库:【@ohos.uri (URI字符串解析)】
URI字符串解析 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 导入…...
JavaScript---new Map()用法
new Map 创建 Map 对象设置键值对获取值检查键是否存在键值对数量删除键值对清空所有键值对迭代 Map 在JavaScript中,Map 是一个构造函数,用于创建 Map 对象,它可以存储键值对集合。与普通的对象不同,Map 的键可以是任何类型的值&…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
