一、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.mfbz.cn/a/784134.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql在linux系统下重置root密码

mysql在linux系统下重置root密码 登录服务器时候mysql密码忘记了,没办法只能重置,找了一圈,把行之有效的方法介绍在这里。 错误展示: 我还以为yes就可以了呢,这是不行的意思。 关掉mysql服务 sudo systemctl stop …

百度、谷歌、必应收录个人博客网站

主要是给各个搜索引擎提交你的sitemap文件,让别人能搜到你博客的内容。 主题使用的Butterfly。 生成sitemap 安装自动生成sitemap插件。 npm install hexo-generator-sitemap --save npm install hexo-generator-baidu-sitemap --save在站点配置文件_config.yml…

Redhat 安装 docker 网络连接超时问题

目录 添加阿里云的Docker CE仓库 更新YUM缓存 安装 Docker Engine 启动并设置Docker自启动 验证 Docker 安装 [userlocalhost ~]$ sudo yum-config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo 正在更新 Subscription Management 软件仓库…

PHP中的运算符与表达式:深入解析与实战应用

目录 一、基础概念 1.1 运算符的定义 1.2 表达式的定义 二、PHP运算符的分类 2.1 算术运算符 2.2 赋值运算符 2.3 比较运算符 2.4 逻辑运算符 2.5 位运算符 2.6 字符串运算符 2.7 错误控制运算符 三、表达式的优先级与结合性 3.1 优先级 3.2 结合性 四、实战应…

挑战全网最清晰解决文本文件乱码方案

标题 文本文件出现乱码之全网最清晰解决方案乱码出现的原因解决方案第一步:获取文件的原始编码格式。第二步,获取当前系统的格式第三步,将文件的内容以当前系统编码格式进行译码并且输出到新的文件中第四步,删除原文件&#xff0c…

【SOLID原则前端中的应用】接口隔离原则(Interface Segregation Principle,ISP)- vue3示例

接口隔离原则(Interface Segregation Principle,ISP)在Vue 3中的应用 接口隔离原则(Interface Segregation Principle,ISP)规定,客户端不应该被迫依赖于它不使用的方法。 换句话说,…

【Python_GUI】tkinter常用组件——文本类组件

文本时窗口中必不可少的一部分,tkinter模块中,有3种常用的文本类组件,通过这3种组件,可以在窗口中显示以及输入单行文本、多行文本、图片等。 Label标签组件 Label组件的基本使用 Label组件是窗口中比较常用的组件,…

JavaEE初阶-网络原理1

文章目录 前言一、UDP报头二、UDP校验和2.1 CRC2.2 md5 前言 学习一个网络协议,最主要就是学习的报文格式,对于UDP来说,应用层数据到达UDP之后,会给应用层数据报前面加上UDP报头。 UDP数据报UDP包头载荷 一、UDP报头 如上图UDP的…

使用ifconfig命令获取当前服务器的内网IP地址

如何使用ifconfig命令获取当前服务器的内网IP地址呢? ifconfig eth0 | grep inet | awk {print $2}

redis运维:sentinel模式如何查看所有从节点

1. 连接到sentinel redis-cli -h sentinel_host -p sentinel_port如: redis-cli -h {域名} -p 200182. 发现Redis主服务器 连接到哨兵后,我们可以使用SENTINEL get-master-addr-by-name命令来获取当前的Redis主服务器的地址。 SENTINEL get-master-a…

最小爬楼梯(dp)

import java.util.Scanner;public class ClimbingStairsCost {public static int minCostClimbingStairs(int[] cost) {int n cost.length; // 获取输入的 cost 数组的长度int[] dp new int[n 1]; // 创建一个用于存储每个台阶最小花费的 dp 数组dp[0] 0; dp[1] 0; // 初始…

解析java128陷阱

一、提要 在java开发时,由于基本类型不能调用方法,在某些方面很不方便,因此产生了包装类。我们把基本类型和对应的包装类的转换叫装箱、拆箱。 1.装箱 基本类型转成包装类对象 关键字valueOf->装箱,可以指定进制: Integer…

C# modbus验证

窗体 还有添加的serialPort控件串口通信 设置程序配置 namespace CRC {public static class CRC16{/// <summary>/// CRC校验&#xff0c;参数data为byte数组/// </summary>/// <param name"data">校验数据&#xff0c;字节数组</param>///…

NLP 面试八股:“Transformers / LLM 的词表应该选多大?“ 学姐这么告诉我答案

NLP 面试八股&#xff1a;“Transformers / LLM 的词表应该选多大?" 学姐这么告诉我答案 原创 看图学 看图学 2024年07月03日 07:55 北京 题目&#xff1a; Transformers/大模型的 token vocabulary 应该选多大&#xff1f; 答案 先说一下结论&#xff1a; 数据量够大…

docker 重要且常用命令大全

本文将总结一些常见的重要的docker命令&#xff0c;以作备忘。后续如果有新的比较常用重要的也会更新进来。欢迎补充。 docker服务管理 首先我们要解释一下&#xff1a;systemctl和docker命令的不同 systemctl&#xff1a;是许多 Linux 发行版中默认的初始化系统和服务管理器。…

提高LabVIEW软件通用性的方法

提高LabVIEW软件通用性的方法 在使用LabVIEW开发软件时&#xff0c;提高软件的通用性非常重要。通用性意味着软件可以在不同的应用场景中使用&#xff0c;具备高度的适应性和灵活性&#xff0c;从而提高软件的价值和用户满意度。以下从多个角度详细探讨如何提高LabVIEW软件的通…

媒体查询:根据设备特征动态调整样式和布局

不知道你会不会有一个疑问&#xff0c;同一个网站&#xff0c;用手机看和用电脑看在首选项和排版会发生一些变化&#xff0c;但我们使用起来仍然非常顺手&#xff0c;这就是响应式设计。响应式设计原理是指网页可以根据不同使用设备的屏幕尺寸&#xff0c;做出相应的调整和变化…

Linux走进网络

走进网络之网络解析 目录 走进网络之网络解析 一、认识计算机 1.计算机的发展 2.传输介质 3.客户端与服务器端的概念 交换机 路由器 二、计算机通信与协议 1. 协议的标准化 2. 数据包的传输过程 OSI 协议 ARP协议 3. TCP/IP:四层模型 4. TCP三次握手和四次挥手…

OceanBase 配置项系统变量实现及应用详解(1):配置项的定义及使用方法

《OceanBase 配置项&系统变量实现及应用详解》专题导读 在使用OceanBase的过程中&#xff0c;看到大家经常会遇到“参数”、“配置项”、“系统变量”等概念&#xff0c;却不太清楚它们是不是同一个东西&#xff0c;以及应该如何使用。一些对数据库开发感兴趣的朋友&#…

LabVIEW开发商业软件的多角度分析与注意事项

在使用LabVIEW开发商业软件时&#xff0c;有许多方面需要考虑和注意&#xff0c;包括项目管理、架构设计、性能优化、用户体验、安全性、维护与支持等。以下是从多个角度详细分析在LabVIEW中开发商业软件需要注意的事项。 项目管理 需求分析&#xff1a;确保深入了解客户需求&a…