Redis知识点

        Redis是一个数据库,不过与传统数据库不同的是Redis的数据库是存在内存中,所以读写速度非常快,因此 Redis被广泛应用于缓存方向。

        除此之外,Redis也经常用来做分布式锁,Redis提供了多种数据类型来支持不同的业务场景。除此之外,Redis 支持事务持久化、LUA脚本、LRU驱动事件、多种集群方案。

Redis的5种常见数据结构以及使用场景

(1)、String

        String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。 常规key-value缓存应用; 常规计数:微博数,粉丝数等。

(2)、Hash

        Hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,后续操作的时候,你可以直接仅 仅修改这个对象中的某个字段的值。 比如我们可以Hash数据结构来存储用户信息,商品信息等。

(3)、List

        list 就是链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表, 消息列表等功能都可以用Redis的 list 结构来实现。

        Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。

        另外可以通过 lrange 命令,就是从某个元素开始读取多少个元素,可以基于 list 实现分页查询,这个很棒的一个功 能,基于 Redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西(一页一页的往下走),性能高。

(4)、Set

        set 对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。

        当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在 一个set集合内的重要接口,这个也是list所不能提供的。可以基于 set 轻易实现交集、并集、差集的操作。

        比如:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis可以非常 方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程,具体命令如下:sinterstore key1 key2 key3将交集存在key1内。

(5)、Sorted Set

        和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。

        举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维 度的消息排行榜)等信息,适合使用 Redis 中的 SortedSet 结构进行存储。

Redis的特性

 Redis 具备高性能和高并发两种特性。

  • 高性能:假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!
  • 高并发:直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

C++中的Map也是一种缓存型数据结构,为什么不用Map,而选择Redis做缓存?

严格意义上来说缓存分为本地缓存分布式缓存

        那以 C++ 语言为例,我们可以使用 STL 下自带的容器 map 来实现缓存,但只能实现本地缓存,它最主要的特点是轻量以及快速,但是其生命周期随着程序的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。

        使用 Redis 或 Memcached 之类的称为分布式缓存,在多实例的情况下,各实例共享一份缓存数据,缓存具有一致性。这是Redis或者Memcached的优点所在,但它也有缺点,那就是需要保持 Redis 或 Memcached服务的高可用,整个程序架构上较为复杂。

单线程的Redis为什么这么快

主要是有三个原因:

(1)、Redis的全部操作都是纯内存的操作;

(2)、Redis采用单线程,有效避免了频繁的上下文切换;

(3),采用了非阻塞I/O多路复用机制。

非阻塞I/O多路复用机制

它允许一个线程同时监控多个I/O通道的状态,并在有数据可读或可写时进行相应的操作,而无需阻塞等待。

基本原理如下:

  1. 非阻塞I/O(Non-blocking I/O:通过设置文件描述符为非阻塞模式,使得在进行I/O操作时不会阻塞线程的执行。当进行读取或写入操作时,如果没有数据可读或无法立即写入,系统会立即返回,而不是等待操作完成。
  2. 多路复用(Multiplexing:操作系统提供的多路复用机制允许一个线程同时监控多个I/O通道的状态。常用的多路复用函数有select、poll和epoll等。通过将多个文件描述符注册到多路复用机制中,线程可以等待任一文件描述符就绪,并进行相应的操作。

Redis的线程模型

        Redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,所以 Redis 才叫做单线程的模型。它采用 IO 多路复用机制同时监听多个 socket,根据 socket 上的事件来选择对应的事件处理器进行处理。

文件事件处理器的结构包含 4 个部分:

  • 多个 socket
  • IO多路复用程序
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

        使用 I/O 多路复用程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时, 与操作相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

        多个 socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是 IO 多路复用程序会监听多个 socket,会将 socket 产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。

        一句话总结就是:“I/O 多路复用程序负责监听多个套接字, 并向文件事件分派器传送那些产生了事件的套接字。”

Redis如何处理大量的请求

(1)、Redis是一个单线程程序,也就说同一时刻它只能处理一个客户端请求;

(2)、(select,epoll,kqueue,依据不同的平台,采取不同的实现)来处理多个客户端请求。

select是一个传统的IO多路复用系统调用,它在早期被广泛使用。它可以同时监视多个文件描述符(套接字)的状态,并在其中至少一个文件描述符就绪时返回。但是,在大规模连接的情况下性能较低,因为它使用了线性扫描的方式。

         Redis在Linux系统上使用epoll系统调用作为IO多路复用机制来实现高性能的事件驱动模型

   epoll通过使用事件通知的方式,避免了线性扫描,可以有效地处理大量的并发连接。

        在Redis中,当服务器启动时,会创建一个epoll实例,并将监听套接字(socket)添加到epoll实例中进行监听。当有新的连接到来时,Redis将新的套接字也添加到epoll实例中。然后,Redis会进入事件循环(event loop)中,不断地调用epoll_wait系统调用等待事件的发生。

  epoll_wait会阻塞,直到有事件发生或超时。当有事件发生时,epoll_wait会返回已就绪的文件描述符(套接字),然后Redis会根据就绪的套接字调用相应的回调函数来处理事件。这可以包括读取数据、写入数据或关闭连接等操作。

        使用epoll作为IO多路复用机制,Redis能够高效地处理大规模的并发连接和高吞吐量,提供优异的性能。

        epoll是Linux特有的系统调用,因此在其他操作系统上,如BSD和macOS,Redis会使用不同的IO多路复用机制,如kqueue。这是因为不同操作系统提供了不同的底层机制来支持高性能的事件驱动模型。

Redis设置过期时间的两种方案

Redis中有个设置时间过期的功能,即对存储在 Redis 数据库中的值可以设置一个过期时间。

        作为一个缓存数据库, 这是非常实用的,比如一些 token 或者登录信息,尤其是短信验证码都是有时间限制的,按照传统的数据库处理方式,一般都是自己判断过期,这样无疑会严重影响项目性能。

我们 set key 的时候,都可以给一个 expire time,就是过期时间,通过过期时间我们可以指定这个 key 可以存活的时间,主要可采用定期删除和惰性删除两种方案。

  • 定期删除:Redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删 除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 Redis 存了几十万个 key ,每隔100ms就遍历所 有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载!
  • 惰性删除 :定期删除可能会导致很多过期 key 到了时间并没有被删除掉。所以就有了惰性删除。它是指某个键值过期后,此键值不会马上被删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除,惰性删除的缺点很明显是浪费内存。 除非你的系统去查一下那个 key,才会被Redis给删除掉。这就是所谓的惰性删除!

假如MySQL有1000万数据,采用Redis作为中间缓存,取其中的10万,如何保证Redis中的数据都是热点数据。

可以使用Redis的数据淘汰策略,Redis 内存数据集大小上升到一定大小的时候,就会施行这种策略。具体说来,主要有 6种内存淘汰策略:

  • voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  • no-enviction(驱逐):禁止驱逐数据

Redis集群?集群的原理是什么?

        Redis Sentinel(哨兵)着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。

        Sentinel(哨兵)可以监听集群中的服务器,并在主服务器进入下线状态时,自动从服务器中选举出新的主服务器。

        Redis Cluster(集群)着眼于扩展性,在单个Redis内存不足时,使用Cluster进行分片存储。

缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存击穿、缓存降级

  • 缓存雪崩

        缓存雪崩指的是缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

        我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃。

解决办法

  • 事前:尽量保证整个 Redis 集群的高可用性,发现机器宕机尽快补上,选择合适的内存淘汰策略。
  • 事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉, 通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
  • 事后:利用 Redis 持久化机制保存的数据尽快恢复缓存

缓存穿透

        一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量 请求而崩掉。

        缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,接着查询数据库也无法查询出结果,因此也不会写入到缓存中,这将会导致每个查询都会去请求数据库,造成缓存穿透。

解决办法

1、布隆过滤器

这是最常见的一种解决方法了,它是将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压 力。

对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力;

2、缓存空对象

当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;如果一个查询返回的数据为空(不管是数据不存 在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

但是这种方法会存在两个问题:

1、如果空值能够被缓存起来,这就意味着缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键;

2、即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。

我们可以从适用场景和维护成本两方面对这两汇总方法进行一个简单比较

适用场景:缓存空对象适用于1、数据命中不高 2、数据频繁变化且实时性较高 ;而布隆过滤器适用1、数据命中不高 2、数据相对固定即实时性较低

维护成本:缓存空对象的方法适合1、代码维护简单 2、需要较多的缓存空间 3、数据会出现不一致的现象;布隆过滤器适合 1、代码维护较复杂 2、缓存空间要少一些

缓存预热

缓存预热是指系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。用户会直接查询事先被预热的缓存数据!

解决思路 1、直接写个缓存刷新页面,上线时手工操作下; 2、数据量不大,可以在项目启动的时候自动进行加载; 3、定时刷新缓存;

缓存更新

除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:定时删除和惰性删除,其中: (1)定时删除:定时去清理过期的缓存; (2)惰性删除:当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。 两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡。

缓存击穿

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

比如常见的电商项目中,某些货物成为“爆款”了,可以对一些主打商品的缓存直接设置为永不过期。即便某些商品自己发酵成了爆款,也是直接设为永不过期就好了。mutex key互斥锁基本上是用不上的,有个词叫做大道至简。

缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。 降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。 以参考日志级别设置预案: (1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级; (2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警; (3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级; (4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。

服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

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

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

相关文章

Ansible剧本(playbook)

一、playbooks 概述以及实例操作 1、playbooks 的组成 playbooks 本身由以下各部分组成 (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 (2)Variables&#xff1…

Ubuntu 22 服务器端安装图形化界面

文章目录 前言一、什么是图形化界面二、操作步骤1、更新安装工具2、开始安装3、重启 总结 前言 Ubuntu 系统做得是越来越好了,从CentOS 不再提供维护后,越来越多的企业和公司从CentOS转到Ubuntu服务器系统,转了之后才发现,它比Ce…

MySQL数据库日志管理、备份与恢复

目录 一、MySQL 日志管理 二、数据备份的重要性 造成数据丢失的原因 三、数据库备份的分类 1 、从物理与逻辑的角度 (1)备份划分 (2) 物理备份方法 2、 从数据库的备份策略角度 四、常见的备份方法 1、物理冷备 2、专用备…

解决安卓12限制32个线程

Android 12及以上用户在使用Termux时,有时会显示[Process completed (signal 9) - press Enter],这是因为Android 12的PhantomProcesskiller限制了应用的子进程,最大允许应用有32个子进程。 这里以ColorOS 12.1为例(其他系统操作略…

前端vue入门(纯代码)14

内容创作不易,各位帅哥美女,求个小小的赞!!! 【15.给todoList案例添加编辑按钮】 本篇内容在TodoList案例的基础上添加个编辑按钮,要求: (1)点击编辑按钮后&#xff0c…

数据挖掘——宁县(区、市)农村居民人均可支配收入影响因子分析(论文)

《数据挖掘与分析》课程论文 题目:宁县(区、市)农村居民人均可支配收入影响因子分析 xx学院xx班:xxx 2022年6月 摘要:农村居民人均可支配收入可能被农作物产量、牲畜存栏、农作物播种数量等诸多因素影响。为此&#…

我的内网渗透-代理转发(1)

概念 网关 必须经过 用来进行路由转发的设备,网关的作用是让不同网段之间能够通信 代理 委托访问 无论代理后面挂了几台设备,都认为是从代理进行访问,对外只表现为代理一台。外部认为是与代理进行…

css小兔鲜项目搭建

目录 精灵图 精灵图的使用步骤 背景图片大小 background连写 文字阴影 盒子阴影 过渡 骨架标签 SEO三大标签 版心的介绍 css书写顺序 项目结构搭建 精灵图 场景:项目中将多张小图片,合并成一张大图片,这张大图片称之为精灵图 优点…

机器人项目创新课题汇总提示

创新课题推荐自己思考并给出,如下案例仅供参考: 不想看,不愿意做,就遵循自己内心想法,做自己喜欢的事情吧。 题目和描述: 自动导航机器人:设计一种能够自主导航的机器人,可以在不需…

pgsql序列的使用

大家都知道pgsql和mysql不同,mysql字段有有自增属性,pgsql并没有,但是pgsql和oracle一样有序列,很多人刚接触pgsql的时候,并不知道序列是什么,怎么用,下面这篇文章就介绍序列,并且怎…

idea如何集成Tomcat

(1)、这里应该找Add Configuration点击这里:如果没有标志,点击Exit (2)、这里可以配置一个配置项: (3)、loacl是本地,那个是远程:这里我选择本地 (4&#xff…

DJ4-4 NAT、ICMP、IPv6

目录 一、NAT:网络地址转换 1、工作原理 2、NAT 的限制 二、ICMP 1、ICMP 协议 2、ICMP 类型和代码 3、Traceroute 命令 三、IPv6 地址 1、IPv6 的引入 2、IPv6 的表示 一、NAT:网络地址转换 动机:对外部网络来讲,本地…

11-高性能JSON库——fastjson2

目录 1.具体使用 1.1.添加fastjson2依赖 1.2.常用类和方法 1.3.将JSON字符串转换成对象 1.3.1.JSON字符串转换成对象 1.3.2.JSON字符串转换成数组 1.4.将对象转换成JSON字符串 1.4.1.将对象转换成JSON字符串 1.4.2.将数组转换成 JSON 字符串 2.性能测试报告 3.总结 …

Prompt Engineering 面面观

作者:紫气东来 项目地址:https://zhuanlan.zhihu.com/p/632369186 一、概述 提示工程(Prompt Engineering),也称为 In-Context Prompting,是指在不更新模型权重的情况下如何与 LLM 交互以引导其行为以获得…

总结905

今日已做: 1.核聚课程 2.进步本回顾,重做8道题,有两道还没掌握,记录3页。 3.线性代数第5讲 4.三大计算,刷题15道,纠错。 5.每日长难句。 6.考研常识课 明日必做 1.熟练背诵《the king’s speech》并默写 2…

字符设备驱动内部实现原理解析

字符设备驱动内部实现原理解析 一. 字符设备驱动对象内部实现原理解析二. 字符设备驱动的注册流程三. 代码示例 一. 字符设备驱动对象内部实现原理解析 用户层: ​ 当用户打开(open)一个文件时,会生成一个文件描述符表 内核层: 内…

spark 和 flink 的对比

一、设计理念 Spark 的数据模型是 弹性分布式数据集 RDD(Resilient Distributed Dattsets),这个内存数据结构使得spark可以通过固定内存做大批量计算。初期的 Spark Streaming 是通过将数据流转成批 (micro-batches),即收集一段时间(time-window)内到达的…

SD/StableDiffusion模型,ai绘画部署教程,谷歌云端零成本部署,支持中文

目录 前言 准备前提 说明 开始搭建 1、第一步,下载ipynb脚本文件 2、第二步,上传一键脚本文件到谷歌云盘 3、选择该.ipynb文件--右键--打开方式--关联更多应用 4、输入框搜索Colaboratory找到该应用,安装 5、安装过程中,…

Linux网络基础

网络基础 认识 "协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型 网络传输基本流程网络传输流程图数据包封装和分用 网络中的地址管理认识IP地址认识MAC地址 认识 “协议” “协议” 是一种约定。 举个栗子,你和好友之间提前约好在某个地方…

第九章 形态学图像处理

文章目录 9形态学图像处理9.1预备知识9.2腐蚀与膨胀9.2.1腐蚀9.2.2膨胀9.2.3对偶性 9.3开操作和闭操作9.4击中或击不中变换9.5一些基本形态学方法9.5.1边界提取9.5.2空洞填充9.5.3连通分量的提取9.5.4凸壳9.5.5细化9.5.6粗化 9.6灰度级形态学9.6.3一些基本的形态学算法 9形态学…
最新文章