一、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对比

共同点:

  1. 都是基于内存的数据库,一般都用来当做缓存使用。
  2. 都有过期策略。
  3. 两者的性能都非常高。

区别:

  1. Redis 支持的数据类型更丰富(String、Hash、List、Set、zset),而 Memcached 只支持最简单的 key-value 数据类型;
  2. Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memcached 没有持久化功能,数据全部存在内存之中,Memcached 重启或者挂掉后,数据就没了
  3. Redis 原生支持集群模式,Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;
  4. 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中方的数据以某种形式从内存

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[数仓]三、离线数仓(Hive数仓系统)

第1章 数仓分层 1.1 为什么要分层 DIM:dimensionality 维度 1.2 数据集市与数据仓库概念 1.3 数仓命名规范 1.3.1 表命名 ODS层命名为ods_表名DIM层命名为dim_表名DWD层命名为dwd_表名DWS层命名为dws_表名 DWT层命名为dwt_表名ADS层命名为ads_表名临时表命名为…

昇思25天训练营Day11 - 基于 MindSpore 实现 BERT 对话情绪识别

模型简介 BERT全称是来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Transformers),它是Google于2018年末开发并发布的一种新型语言模型。与BERT模型相似的预训练语言模型例如问答、命名实体识别、自然语言推理、…

56、最近邻向量量化(LVQ) 网络训练对输入向量进行分类

1、LVQ 网络训练对输入向量进行分类简介 1)简介 LVQ(最近邻向量量化)是一种简单而有效的神经网络模型,用于对输入向量进行分类。LVQ网络通过学习一组原型向量(也称为代码矢量或参考向量),来表…

HTML5 WebSocket技术使用详解

HTML5 WebSocket API 提供了一种在单个连接上进行全双工通信的方式。这意味着客户端和服务器可以同时发送和接收数据,而不需要像传统的 HTTP 请求那样进行多次请求和响应的轮询。WebSocket 允许更实时的交互,非常适合需要快速、连续数据交换的应用场景&a…

SAP Build4-office 操作

1. 邮件操作 1.1 前期准备 商店中找到outlook的sdk,添加到build中 在process中添加outlook的SDK 电脑上装了outlook的邮箱并且已经登录 我用个人foxmail邮箱向outlook发了一封带附件的销售订单邮件,就以此作为例子 1.2 搜索邮件 搜索有两层&…

计算机视觉、目标检测、视频分析的过去和未来:目标检测从入门到精通 ------ YOLOv8 到 多模态大模型处理视觉基础任务

文章大纲 计算机视觉项目的关键步骤计算机视觉项目核心内容概述步骤1: 确定项目目标步骤2:数据收集和数据标注步骤3:数据增强和拆分数据集步骤4:模型训练步骤5:模型评估和模型微调步骤6:模型测试步骤7:模型部署常见问题目标检测入门什么是目标检测目标检测算法的分类一阶…

CSS实现图片裁剪居中(只截取剪裁图片中间部分,图片不变形)

1.第一种方式:(直接给图片设置:object-fit:cover;) .imgbox{width: 100%;height:200px;overflow: hidden;position: relative;img{width: 100%;height: 100%; //图片要设置高度display: block;position: absolute;left: 0;right…

OpenCV:解锁计算机视觉的魔法钥匙

OpenCV:解锁计算机视觉的魔法钥匙 在人工智能与图像处理的世界里,OpenCV是一个响当当的名字。作为计算机视觉领域的瑞士军刀,OpenCV以其丰富的功能库、跨平台的特性以及开源的便利性,成为了开发者手中不可或缺的工具。本文将深入…

基于Java+SpringMvc+Vue技术的在线学习交流平台的设计与实现---60页论文参考

博主介绍:硕士研究生,专注于Java技术领域开发与管理,以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经…

AI+若依框架(低代码开发)

提前说明: 文章是实时更新,写了就会更。 文章是黑马视频的笔记,如果要自己学可以点及下面的链接: https://www.bilibili.com/video/BV1pf421B71v/一、若依介绍 1.版本介绍 若依为满足多样化的开发需求,提供了多个版本…

基于jeecgboot-vue3的Flowable流程-集成仿钉钉流程(一)图标svgicon的使用

因为这个项目license问题无法开源,更多技术支持与服务请加入我的知识星球。 1、lowflow这里使用了tsx的动态图标,如下: import ./index.scss import type { CSSProperties, PropType } from vue import { computed, defineComponent, resolv…

MATLAB基础应用精讲-【数模应用】 岭回归(Ridge)(附MATLAB、python和R语言代码实现)

目录 前言 算法原理 数学模型 Ridge 回归的估计量 Ridge 回归与标准多元线性回归的比较 3. Ridge 参数的选择 算法步骤 SPSSPRO 1、作用 2、输入输出描述 3、案例示例 4、案例数据 5、案例操作 6、输出结果分析 7、注意事项 8、模型理论 SPSSAU 岭回归分析案…

Java [ 进阶 ] 深入理解 JVM

✨探索Java基础 深入理解 JVM✨ 深入理解 JVM:结构与垃圾回收机制 Java 虚拟机(JVM)是 Java 程序运行的核心,了解 JVM 的内部结构和垃圾回收机制对优化 Java 应用性能至关重要。本文将深入探讨 JVM 的结构和垃圾回收机制&#…

支付宝沙箱对接(GO语言)

支付宝沙箱对接 1.1 官网1.2 秘钥生成(系统默认)1.3 秘钥生成(软件生成)1.4 golan 安装 SDK1.5 GoLand 代码1.6 前端代码 1.1 官网 沙箱官网: https://open.alipay.com/develop/sandbox/app 秘钥用具下载: https://ope…

序列化、反序列化

java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。 将序列化对象写入文件之后,可以从文件中读取出来,并且对…

Java并发编程-ThreadLocal深入解读及案例实战

文章目录 概述原理使用场景示例最佳实践内存泄漏风险阿里开源组件TransmittableThreadLocal原理和机制使用场景如何使用注意事项ThreadLocal在分布式存储系统edits_log案例中的实践1. 为什么使用`ThreadLocal`?2. 实践案例2.1 缓存日志操作2.2 线程局部的编辑日志状态3. 注意事…

在 Spring 中编写单元测试

单元测试是软件开发过程中不可或缺的一部分,它能有效地提高代码质量,确保代码功能的正确性。在 Spring 应用中,JUnit 和 Mockito 是常用的单元测试工具,而 Spring Test 提供了丰富的测试支持。本文将介绍如何在 Spring 中使用 JUn…

并行处理百万个文件的解析和追加

处理和解析大量文件,尤其是百万级别的文件,是一个复杂且资源密集的任务。为实现高效并行处理,可以使用Python中的多种并行和并发编程工具,比如multiprocessing、concurrent.futures模块以及分布式计算框架如Dask和Apache Spark。这…

物联网时代5G通信技术分析研究一、引言

一、引言 近几年,移动网络技术跟随互联网的不断发展而改革和进步,给平民大众的生活也带来新的尝试与影响。从2G网络的出现,到逐步被社会民众所了解的3G,再到被熟知的且正在服务于大家的4G网络,移动网络技术的发展速度令…

jQuery Mobile 安装指南

jQuery Mobile 安装指南 jQuery Mobile 是一个基于 jQuery 的移动设备友好的网页开发框架,它允许开发者创建响应式网页和应用程序。本指南将详细介绍如何安装 jQuery Mobile,并确保您的开发环境准备好进行移动网页开发。 1. 环境准备 在开始安装 jQuery Mobile 之前,请确…