初识Redis

目录

  • 认识Redis
  • 分布式系统
  • Redis的特性
  • Redis的应用场景
  • Redis客户端
  • Redis命令

认识Redis

The open source, in-memory data store used by millions of developers as a database, cache, streaming engine, and message broker.

上面一段话是官网给出的对Redis的介绍,in-memory data store表明Redis是在内存中存储数据的,这和我们接触的其他数据库就有很大的不同,比如MySQL,它是将数据存储在磁盘中的,但由于MySQL需要与磁盘交互,访问速度就比较慢,而很多互联网产品,又对性能要求比较高,这时,Redis就可以发挥出它的作用了,因为是在内存中存储数据,就意味着访问速度远比在磁盘中快,极大地提高了程序的性能。

Redis也不是各方面领先于MySQL,比如在存储空间上,是远小于MySQL的,毕竟磁盘的空间要远大于内存!

要想存储的数据多,访问速度也快,就可以考虑将MySQL和Redis结合起来使用,因为20%的热点数据能满足80%的访问需求,但带来的问题是:系统的复杂程度大大提升了,而且数据发生修改时,还涉及到Redis和MySQL之间的数据同步问题,此时,Redis被作为cache

Redis的初心,就是用来作为一个"消息中间件"的(消息队列),然而,当前很少会直接使用Redis作为消息中间件,因为业界有更多更专业的消息中间件使用

为什么要有Redis,直接用变量存储不行?

在单机程序,Redis相对于变量存储数据,没有优势可言,但在分布式系统中,才能发挥威力,基于网络,可以把自己内存中的变量给别的进程,甚至别的主机的进程进行使用

分布式系统

单机架构

如下图,是一个单机架构,只有一台服务器,它负责所有的工作,虽然只有一台服务器,但现在的硬件非常nice,也就意味着一台服务器的性能也很高,可以支持非常高的并发和非常大的数据存储,所以,绝大部分的公司的产品,就是这种单机架构!

在这里插入图片描述
分布式系统的引入

业务进一步增长,用户量和数据量都水涨船高,一台服务器难以应付,如果同一时刻处理的请求多了,可能会导致某个硬件资源不够用了,即导致服务器处理请求的时间变长,甚至于处理出错!

而要想解决这个问题,无非两种方式,第一个是节流,在软件上优化,但对程序员的水平要求就比较高;另一种方式就是引入更多的主机、更多的硬件资源,但一台主机的硬件资源是有限的,比如就4个内存插槽,你也就只能插4条内存条,所以就需要引入多台主机,此时的系统就可以称为是"分布式系统"

分布式系统的引入,会使得系统的复杂程度会大大提高,出现bug的概率也越高,则使用的人力成本上也就会越高,所以,引入分布式,是一种无奈之举!

应用服务和数据库服务分离

如下图, 将应用服务和数据库服务部署在不同的服务器,就可以给他们搭配不同的服务器,比如应用服务器,里面可能会包含很多的业务逻辑,可能会吃CPU和内存,就采用CPU和内存好的主机;而数据服务器,需要更大的硬盘空间,更快的访问速度,就可以配置更大硬盘的主机,甚至是SSD硬盘,这样就能达到更高的性价比!!!
在这里插入图片描述
引入更多的应用服务器节点

如下图,应用服务器可能会比较吃CPU和内存,如果把CPU和内存吃没了,此时应用服务器就顶不住了,就需要引入更多的应用服务器,来解决上述问题,同时也需要引入负载均衡器,用户的请求会先到达负载均衡器/网关服务器,然后根据负载情况,将请求分配给负载相对小的应用服务器,尽可能保证每台应用服务器处理的用户请求是均衡的,当然,这里就会用到负载均衡的相关算法

在这里插入图片描述
负载均衡器,对于请求量的承担能力,是远超过应用服务器的,因为负载均衡器就相当于领导,负责派发任务,而应用服务器则相当于职员,负责执行任务。如果出现请求量大到负载均衡器也扛不住了的时候,就可以引入更多的负载均衡器,即引入多个机房

引入更多的数据库服务器(读写分离)

如下图,当数据量太多,一台数据库服务器难以支撑时,就需要引入更多的服务器来存储数据,而实际的应用场景中,读的频率是比写要高的,所以一般是一台主服务器,多台从服务器,主服务器负责写,读服务器负责读,同时从服务器通过负载均衡的方式,让应用服务器进行访问

在这里插入图片描述

引入缓存

数据库天然有个问题,那就是响应速度是更慢的!所以就需要把数据区分“冷热”,热点数据存放到缓存中,而缓存的访问速度往往比数据要快很多!如下图所示
在这里插入图片描述

分库分表

当数据量更大时,一台服务器已经存不下了,就需要多台主机存储,同时能对数据库进行进一步的拆分,即分库分表。本来一台数据库服务器上有多个数据库(create database),现在引入多台数据库服务器,就能每个数据库服务器存储一个或者一部分数据库,甚至如果某个表特别大,一台主机存不下,也可以针对表进行拆分!具体分库分表如何实现,还要结合实际的业务场景来展开,因为业务决定技术。如下图所示

在这里插入图片描述
微服务架构

前面的应用服务器,里面可能做了很多的业务,这就可能导致这个服务器的代码变得非常复杂,而为了更方便代码的维护,就可以把这样的复杂的服务器,拆分成更多的,功能更单一的,但是更小的服务器,同时服务器的种类和数量就增加了!如下图所示
在这里插入图片描述
注意:微服务本质上是在解决"人"的问题

当应用服务器复杂了,就势必需要更多的人来维护,当人多了,就需要配套的管理,把这些人组织好,可以划分组织结构,分成多个组,每个组分别配备领导进行管理,分成多个组,就需要进行分工,而拆分成多组微服务,就利于人员的组织结构的分配了

微服务的优势

解决了人的问题;
使用微服务,可以更方便于功能的复用;
可以给不同的服务进行不同的部署

引入微服务,付出的代价?

系统性能的下降,而要想保证性能不下降太多,就需要引入更多、更好的硬件资源,而拆分出来更多的服务,多个功能之间要更依赖网络里通信,而如果用的网卡不是很好的那种,那网络通信的速度比硬盘还慢!
系统复杂程度提高,可用性受到影响,服务器更多了,出现问题的概念就更大了,这就需要一系列的手段,来保证系统的可用性,比如更丰富的监控报警,以及配套的运维人员

分布式系统的概念

应用/系统
一个应用,就是一个/组服务器程序

模块/组件
一个应用,里面有很多个功能,每个独立的功能,就可以称为是一个模块/组件

分布式
引入多个主机/服务器,协调配合完成一系列的工作(物理上的多台主机)

集群
引入多个主机/服务器,协调配合完成一系列的工作(逻辑上的多台主机)

主/从
分布式系统中一种比较典型的结构,多个服务器节点,其中一个是主,另外的则是从,从节点的数据要从主节点这里同步过来

中间件
和业务无关的服务(功能更通用的服务),比如数据库,缓存,消息队列

可用性
系统整体可用的时间/总的时间,也是一个系统的第一要务

响应时长
衡量服务器的性能,越小越好

吞吐 vs 并发
衡量系统的处理请求的能力,衡量性能的一种方式

Redis的特性

在这里插入图片描述

如上图,可以看出Redis是在内存中存储数据的,Redis主要是通过"键值对"的方式来存储组织数据,是一种"非关系型数据库",key都是string,value则可以是字符串、哈希表、列表、集合等等

在这里插入图片描述

如上图,针对Redis的操作,可用通过简单的交互式命令进行操作,也可以通过一些脚本的方式,批量执行一些操作(可以带有一些逻辑)

在这里插入图片描述
如上图,Redis提供了一组API,可以用C、C++和Rust语言在Redis原有的功能基础上再进行扩展,即编写动态链接库

在这里插入图片描述
如上图,为了使Redis存储的数据持久化,Redis会把数据存储再硬盘上,即内存为主,硬盘为辅

在这里插入图片描述
如上图,Redis作为一个分布式系统的中间件,能够支持集群是很关键的,这个水平扩展,类似于"分库分表"。
一个Redis能存储的数据是有限的,因为内存空间有限,就可以引入多台主机,部署多个Redis节点,每个Redis节点存储数据的一部分

在这里插入图片描述
如上图,Redis具有高可用特性,数据存在冗余/备份,Redis自身也是支持"主从"结构的,从节点就相当于主节点的备份了

为什么Redis快?

1、Redis数据存在内存中,就比访问硬盘的数据库,要快很多
2、Redis核心功能都是比较简单的逻辑,如比较简单的操作内存的数据结构
3、从网络角度,Redis使用了IO多路复用的方式
4、Redis使用的是单线程模型,减少了不必要的线程之间的竞争开销,因为Redis的核心任务主要是操作内存的数据结构,不会吃很多CPU

Redis的应用场景

在这里插入图片描述
如上图,Redis可以被当作数据库使用,虽然在大多数情况下,考虑到数据存储,优先考虑的是"大",但是仍然有一些场景,考虑的是"快",比如搜索引擎

在这里插入图片描述
如上图,Redis存的是部分数据,比如热点数据,全量数据都是以MySQL为主的,哪怕Redis的数据没了,还可以从MySQL那里加载回来

在这里插入图片描述
如上图,Redis可以作为消息队列,基于这个可以实现一个网络版本的生产者-消费者模型

如下图,在用户浏览某个网站时,访问不同的网页,负载均衡器有很大的可能将请求打到不同的应用服务器,而保存的session的只有一台服务器上有,这就会给用户带来不好的体验,毕竟要多次重新登录,此时有两种方式解决这个问题

1、想办法让负载均衡器,把同一个用户的请求始终打到同一台机器上,但就不能通过轮询的方式来选择应用服务器,而要用userld之类的方式来分配机器
2、把会话单独拎出来,放到一台独立的机器上存储(Redis)

在这里插入图片描述

Redis客户端

和MySQL一样,Redis也是一个客户端-服务器结构的程序,它的客户端和服务器可以在同一台主机上,也可以在不同主机上

Redis客户端的形态

命令行客户端redis-cli
图形化界面的客户端(桌面程序、web程序)
基于redis的API自行开发客户端(工作中最主要的形态),非常类似于MySQL的C语言API和JDBC

Redis命令

get和set命令

set:把key和value存储进去
get:根据key来获取value
set和get也是Redis最核心的两个命令
如下图,key和value都是字符串,即使没有加"“,当然,加”"或’'都是可以的
注意:Redis中的命令是不区分大小写的!!!

在这里插入图片描述
key不存在时,会直接返回空

在这里插入图片描述
Redis全局命令:能够搭配任意一个数据结构来使用的命令

keys命令

keys:用来查询当前服务器上匹配的key,后面接pattern,pattern方便查找我们想要的,keys类似于Linux中的grep命令
如下图,设置下面键值对,方便下面的演示

在这里插入图片描述

?:匹配任意一个字符

在这里插入图片描述

*:匹配0个或多个任意字符

在这里插入图片描述

[abcde]:只能匹配到a b c d e,别的不行,相当于给出固定的选项了

在这里插入图片描述

[^a]:排除a,只有a匹配不了,其他的都能匹配

在这里插入图片描述

[a-b]:匹配a-b这个范围内的字符,包含两侧边界

在这里插入图片描述
注意:keys命令的时间复杂度是O(N),所以在生产环境上,一般都会禁止使用keys命令,尤其是大杀器keys *,它会查询出Redis中所有的key。生产环境上的key可能会非常多,而Redis是一个单线程的服务器,执行keys *的可能性非常长,使得Redis服务器被阻塞了,就无法给其他客户端提供服务了,这样的后果是灾难性的!

工作中会涉及到的几种环境

办公环境、开发环境、测试环境、线上环境/生产环境,操作线上环境的任何一个设备/程序都要怀着12分的谨慎!

exists命令

判断一个或多个key是否存在,时间复杂度O(1),返回值:key存在的个数,redis是按照哈希表的方式来组织的

在这里插入图片描述
如上图,一次判断多个key,比起一次判断一个,效率会更高,因为redis是一个客户端—服务器结构的程序,而客户端与服务端是通过网络进行通信的,相对内存而言,网络通信很慢,所以走一次网络和走多次网络区别很大

del命令

删除指定的key,一次可以删除多个,时间复杂度O(1),返回值:删除掉的key的个数

在这里插入图片描述
redis作为缓存时,误删了几个数据,相对于MySQL而言,影响不是很大,但如果把所有的数据或者一大半数据一下子干没了,影响就大了去了,本来redis是帮MySQL负重前行的,而redis数据被删了,就只能去MySQL中获取数据了,很容易把MySQL搞崩
redis作为数据库时,哪怕误删一个数据,影响都会很大
redis作为消息队列时,误删数据影响大不大,就需要具体问题具体分析了

expire命令

给指定的key设置过期时间,单位是秒,时间复杂度O(1),返回值:1表示设置成功,0表示设置失败

在这里插入图片描述
应用场景:手机验证码、外卖优惠券
注意:必须针对已经存在的key设置过期时间

ttl命令(time to live)

查看当前key的过期时间还剩多少,时间复杂度O(1),-1表示没有关联过期时间,-2表示key不存在

在这里插入图片描述

redis中key的过期策略

如果直接遍历所有的key,显然是行不通的,效率太低了
redis整体的策略是定期删除和惰性删除
定性删除:每次抽取一部分,进行验证过期时间,保证这个抽取检查的过程足够快
为什么要对定性删除的时间,有明确的要求?
因为redis是单线程的程序,主要的任务执行命令,如果扫描过期key消耗的时间太多了,就可能导致正常处理请求命令就被阻塞了,类似于keys *
惰性删除:当某个key已经到过期时间了,但是暂时还没删它,key还存在,后面又一次访问,正好用到了这个key,于是这次访问就会让redis服务器触发删除key的操作,同时再返回一个nil

过期策略也可以通过定时器来实现!!!

定时器

概念:在某个时间达到之后,执行指定的任务

基于优先级队列实现定时器

假定现在又很多key都设置了过期时间,就可以把这些key加入到一个优先级队列中,指定优先级规则:过期时间早的,先出队列,队首元素,就是最早要过期的key,然后只需要给定时器分配一个线程,让这个线程取检查队首元素,看看是否过期即可,此时,扫描线程不需要遍历所有key,只需要盯住队首元素即可
在扫描线程检查队首元素过期时间的时候,也不能检查太频繁,可以根据当前时刻和队首元素的过期时间,设置一个等待,当时间差不多到了,系统再去唤醒这个线程,来新任务时,唤醒线程,重新设置阻塞时间即可!

基于时间轮实现定时器

在这里插入图片描述
如上图,把时间划分成很多小段—划分的粒度,看实际需求
每个小段上都挂着一个链表,每个链表都代表一个要执行的任务(相当于一个函数指针,以及对应的参数啥的)
给定一个指针,指向时间轮中的一个格子,让它绕着这个时间轮旋转,每走到一个格子,就会尝试把这个格子上链表的任务尝试执行一下
注意:每个格子是多少时间,一共多少格子,都是需要根据实际场景,灵活调配的

type命令

查看这个key对应value的类型,有string、list、set、hash等等,时间复杂度O(1)

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

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

相关文章

书写自动智慧:探索Python文本分类器的开发与应用:支持二分类、多分类、多标签分类、多层级分类和Kmeans聚类

书写自动智慧:探索Python文本分类器的开发与应用:支持二分类、多分类、多标签分类、多层级分类和Kmeans聚类 文本分类器,提供多种文本分类和聚类算法,支持句子和文档级的文本分类任务,支持二分类、多分类、多标签分类…

Linux:Firewalld防火墙

目录 绪论 1、firewalld配置模式 2、预定义服务:系统自带 3端口管理 绪论 firewalld 防火墙,包过滤防火墙,工作在网络层,centos7自带的默认的防火墙 作用是为了取代iptables 1、firewalld配置模式 运行时配置 永久配置 i…

HTML详解连载(1)

HTML详解连载(1) HTML定义HTML 超文本标记语言标签语法注意拓展 HTML基本骨架解释VS Code 快速生成骨架:标签的关系父子关系(嵌套关系)兄弟关系(并列关系) 代码格式注释 标题标签标签名:h1-h6(双…

Jenkins 监控dist.zip文件内容发生变化 触发自动部署

为Jenkins添加plugin http://xx:xx/manage 创建一个任务 构建触发器 每3分钟扫描一次,发现指定文件build.zip文件的MD5发生变化后 触发任务

IntelliJ IDEA(简称Idea) 基本常用设置及Maven部署---详细介绍

一,Idea是什么? 前言: 众所周知,现在有许多编译工具,如eclipse,pathon, 今天所要学的Idea编译工具 Idea是JetBrains公司开发的一款强大的集成开发环境(IDE),主要用于Java…

qemu简单使用

参考: 记一次全设备通杀未授权RCE的挖掘经历 claude1 安装使用 附件下载 下载后拖到虚拟机 解压 使用root用户 运行.sh脚本即可 运行脚本解读 #!/bin/bashsudo qemu-system-mipsel \-cpu 74Kf \-M malta \-kernel vmlinux-3.2.0-4-4kc-malta \ -hda debian…

【C语言】每日一题(寻找数组的中心下标)

寻找数组的中心下标,链接奉上 方法 暴力循环前缀和 暴力循环 ​​​​​​​思路: 依旧是我们的老朋友,暴力循环。 1.可以利用外层for循环,循环变量为数组下标,在循环内分别求出下标左边与右边的sum 2.在边界时讨论&…

【华为Datacom 综合拓扑案例—分享篇】

拓扑图 题目要求 实验要求: 1、PC1\PC2\PC3\PC4采用DHCP自动获取IP地址,SW5作为服务器,SW3和SW4作为中继 创建地址池ip pool huawei1和ip pool huawei2,租期都为2天 2、SW3与SW4做链路聚合,采用LACP模式。SW3作为主…

VScode如何设置中文教程

前言:打开VSCode软件,可以看到刚刚安装的VSCode软件默认使用的是英文语言环境,但网上都是vscode中文界面教你怎么设置中文,可能不利于小白阅读,所以重装vscode,手摸手从英文变成中文。 设置为中文 打开VS…

Mirror网络库 | 实战

此篇为下文,上篇:Mirror网络库 | 说明 一、官方实例说明 场景名说明AdditiveLevels场景为“关卡”,附加形式加载AdditiveScenes加载卸载附加场景Basic基础的连接/断开,消息发送Benchmark服务器1000“怪物”生成性能测试Benchmark…

PHP最简单自定义自己的框架控制器自动加载运行(四)

1、实现效果调用控制中方法 2、创建控制器indexCrl.php <?php class indexCrl{public function index(){echo 当前index控制器index方法;} } 3、KJ.php字段加载控制器文件 public static function run(){//定义常量self::_set_const();//创建模块目录self::_mk_module();…

Vue-打印组件页面

场景: 需要将页面的局部信息打印出来&#xff0c;只在前端实现&#xff0c;不要占用后端的资源。经过百度经验&#xff0c;决定使用 print-js和html2canvas组件。 1. 下载包 npm install print-js --save npm install --save html2canvas 2. 组件内引用 <script>impo…

win11右下角图标(网络,音量,电量)点击无反应问题,两分钟解决!

win11系统用的好好的&#xff0c;突然有一天任务栏右下角的常用三件套&#xff08;网络&#xff0c;音量&#xff0c;电量&#xff09;左键单击没反应&#xff0c;无法方便的调节音量和连接wifi&#xff0c;如下图所示&#xff0c;但是右键好用&#xff0c;不过不方便。网上查了…

spring按条件注入@Condition及springboot对其的扩展

概述 spring的ioc极大的方便了日常开发&#xff0c;但随着业务的迭代。配置的一些参数在某些情况下需要按条件注入。 比如原先定义的db公共模块下&#xff0c;相关的配置和工具类只是基于mysql的。但是后续有模块需要使用mongo/es等其他数据库&#xff0c;又想继续使用db公共…

RocketMQ消息轨迹产生的背景以及使用方式

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 背景 最近在维护RocketMQ经常会出现这种问题 消息发送方和接收方出现扯皮&#xff0c;消息发送方说我的消息已经发送成功了&#xff0c;消费方说我没接收到消息。…

AI黑马挑战赛,探索研发新趋势丨IDCF

随着AI的出现&#xff0c;获取知识的成本大幅降低&#xff0c;当DevOps与AI相结合时&#xff0c;必将产生全新的化学反应。不断涌现的AI新工具提醒我们&#xff0c;一个全新的研发工作范式正在逐渐形成。而DevOps的核心理念是敏捷协同&#xff0c;作为工程师&#xff0c;如何通…

【从零学习python 】19. 循环遍历列表和列表嵌套的应用

文章目录 列表的循环遍历1. 使用while循环2. 使用for循环3. 交换2个变量的值1. 列表嵌套2. 应用 进阶案例 列表的循环遍历 1. 使用while循环 为了更有效率的输出列表的每个数据&#xff0c;可以使用循环来完成 namesList [xiaoWang,xiaoZhang,xiaoHua] length len(namesLi…

基于C#的无边框窗体阴影绘制方案 - 开源研究系列文章

今天介绍无边框窗体阴影绘制的内容。 上次有介绍使用双窗体的方法来显示阴影&#xff0c;这次介绍使用API函数来进行绘制。这里使用的是Windows API函数&#xff0c;操作系统的窗体也是用的这个来进行的绘制。 1、 项目目录&#xff1b; 下面是项目目录&#xff1b; 2、 函数介…

浅谈早期基于模板匹配的OCR的原理

基于模板匹配的概念是一种早期的字符识别方法&#xff0c;它基于事先准备好的字符模板库来与待识别字符进行比较和匹配。其原理如下&#xff1a; 1. 字符模板库准备&#xff1a;首先&#xff0c;针对每个可能出现的字符&#xff0c;制作一个对应的字符模板。这些模板可以手工创…

同步_异步请求和Ajax并利用axios框架简化

目录 同步和异步 原生的Ajax 创建XMLHttpRequest对象 常用方法 常用属性 axios框架 同步和异步 同步请求&#xff1a;发送请求后&#xff0c;会做出回应&#xff0c;回应的内容会覆盖浏览器中的内容&#xff0c;这样会打断其他正常的操作&#xff0c;显得不太友好&#…