【Redis】从计算机组成原理开始讲解为什么会出现Redis

news2025/7/19 2:48:27

文章目录

  • 前置知识
  • 数据库的出现
  • Redis
    • memcache与redis的区别

前置知识

首先需要知道的一个常识就是:数据是存放在磁盘里面的。
而磁盘有两个指标:

  • 寻址:表示找到对应的数据所需要的时间,ms
  • 带宽:表示单位时间可以有多少个字节流入流出,G/M

相对于内存,内存寻址的速度一般为ns级别。
也就是如果数据在内存中,那么找到它的速度比在磁盘中快了十万倍。
而内存的带宽,以DDR3 1600的速度为12.8G/s,如果构成的是双通道,那么就是25.6G/s。所以内存的带宽是非常大的。

还有一个就是I/O buffer:他考虑的是一个成本问题,我们知道磁盘是有磁道和扇区的,而一个扇区有512Byte,目前大部分电脑的磁盘大小512G,那么就会有特别多的扇区(大约是10^6个),而如果扇区特别多,想要找到一个数据所需要的索引就得跟着变大,因为如果操作系统的查找文件的索引还没有扇区多,那么就会出现找不到某些索引的数据,因此操作系统的索引所占的字节数也要跟着变大。那么就会造成一部分的空间被浪费在索引上。
因此为了解决这个问题,操作系统在查找文件的时候都是以4k为一个标准的,因此无论我们读多大的数据,都是以4k大小去读取的。这样子所需要的索引大小就少了。
这也就是为什么我们再写程序的时候如果设定一个缓冲区大小不是1k的倍数就是4k的倍数。

数据库的出现

上面已经知道操作系统读取数据的时候都是以4k为基础大小去读取的。
而我们的数据一般都存放在文件中,如果我们要读取一个非常大的文件,那么打开这个文件其实就会需要非常多的时间,因为此时磁盘的速度就已经成为了不可逾越的瓶颈了。

而为了解决这种问题,数据库就出现了。
数据库中有一个东西叫做data page(数据页),它的大小是4k,和我们操作系统缓冲区大小一样。
而数据库中是可以有很多的data page的,因此数据库中存储数据只要把数据放在不同的data page中,那么刚刚好每次OS读取的大小都是4k,那么就能很快的就读取到数据了。
而读取文件就不行,因为读取文件,一个文件可能就几十几百M,那么OS就得一次性都把这些数据读出来之后才能展示给你,因此这就是为什么如果你有一个非常大的文本文件,你要打开它会导致系统卡顿一段时间。

但是此时这些数据只是散布在了这些data page中,如果你想要查询对应的数据,还是需要把这些所有的数据都先读取到内存中,也就是把这些data page一页一页的读取到内存中,那么其实和读取文本文件一样,都是全量IO,都是要全部读取完毕,那么就没有速度优势了不是吗?
所以,数据库中有一个很特殊的东西就派上用场了-----索引
索引本身也是数据,他们类似于data page中数据的身份证一样。

我们在创建关系型数据库的时候,要求必须给出schema,也就是必须给出表的每一个列以及每一个列的约束,类型。那么当你设计完毕一张表之后,其中每一个列的字节宽度就已经确定了。
这样做的好处是,即使我们向数据库表插入数据的时候有些字段没有给他数据,那么他也会用默认数据去占位,这么做的好处就在于,下次进行数据修改等操作的时候,不需要去移动磁盘中的空间,而是直接把那个占位的数据给他覆盖掉,这样子就减少了移动空间的开销。

这也就是为什么数据库中存储数据的时候倾向于行级存储。

而我们的内存中,其实存放了一个指向了所有所有的B+树,这个B+树的树干存放在我们的内存中,当我们的SQL语句要进行查询的时候,如果SQL语句中的where条件中能命中某一个索引,那么此时B+树去查找的时候就会去查找我们之前所说的身份证(索引),然后根据这个索引我们就能找到对应的数据了。
前面说过索引本身也是数据,而内存又不够大,因此我们只会把B+树存放在内存中,而不会把索引也放入内存中。

而常见的面试题就是,对于一个非常大的数据库,其速度是否变慢,为什么?
答:
在有索引的情况下,增删改操作变慢,因为这些操作对数据进行改变之后,索引也是需要跟着改变的,而修改索引是需要时间开销的。
而对于查询,则不一定,分为两种情况:

  • 如果是一个或者少量的查询,那么查询在命中索引之后将数据读入到内存中依旧很快。

  • 在高并发情况或者SQL语句十分复杂的情况下,由于在同一时间到达了许多的SQL语句,那么就会导致不止一个data page需要写入到内存中,并且如果这些语句查询的都是不同的data page,那么就会导致每一个data page都需要挨个写入到内存中,因此就会导致后面的data page需要等待前面的data page,此时影响速度的就是磁盘的带宽了。这就会导致后来的SQL语句就需要进行等待。

    也就是答题的时候不仅仅是寻址速度的问题,还有带宽大小的问题。

而对于数据越来越大的数据库,除了分库分表操作,也就只有一种方式了,就是将尽可能多的数据放入到内存中,但是这个价格非常昂贵。
因此出现了一个内存与磁盘的中间人,那就是缓存,将少量的数据放入到缓存中,缓存的速度非常的快,尽可能的接近了内存,因为他们的材质是一样的。
所以提到了缓存,那么就引入了今天的主角,Redis。

Redis

Redis在数据库世界中的含金量

memcache与redis的区别

​ Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

​ 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。
在这里插入图片描述

​ Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

在redis之前已经有一个技术,这个技术叫做memcache,它也是键值对,key-value的,那么redis是kv的,然后memcach是kv的,那么redis的出来之后,反而要取代memcach生存的地位。那么为什么它会取代memcach的?
如果稍微一查资料就会知道,memcache当中它的value没有类型的概念,但是redis value具有类型的概念了,这是两个的一个最本质的区别。

redis说他有value,有类型,然后我们开始没有类型,然后当时我大脑条件反射第一个东西是啥?json(因为你的所有数据都能用json表示出来),为什么要条件反射json那个东西,因为肯定开始没有redis。那么如果假设世界上只有这种键值对,然后value没有类型,那么我们使用这个技术的时候可不可以存一些复杂的东西?那么这时候你的条件反射是json对不对?json它可以表示很复杂的的数据结构。首先如果你条件反射想起这个知识,那么你会得出一个间接结论,也就是说你value有没有类型?好像是无所谓的,因为我memcache只要有键值对了,我的value里是不是也可以放一个json,然后来代表有数组,这边你有list,我这边是不是也可以用json表示一个list?你这边有hashes这种键值对的,我这边是不是也可以放?

当这个理论你明白之后,也就是说其实我可以不用redis,我用memcache的它的value也可以存很复杂的东西,但是注意了,你要再逆推一件事情,那么他们的成本,value的类型的意义是什么?

如果注意听下面一个很重要的一句话描述,你就知道为什么你要学redis。

如果我的客户端想通过一个缓存系统,而且是kv的缓存器系统当中取回value当中的某一个元素,也就是memcach当中value里面存了一个数组,然后你用redis中的value当中存了一个list。

那么这时候如果想取回其中的数据,使用memcache的话就是获取它在json里面的某一个元素,而使用redis则是直接取回有类型的这个list中的某一个元素的话。

很明显他们的成本就不一样了。相对memcache来说的话,memcache怎么去做的?你需要返回value所有的数据到 client段。那么memcach这台服务器如果很多人都这么获取的话,网卡I/O就是最大的瓶颈,这是第一个,第二个就是client端要有你实现的代码去解码,解码你的json,把json当中数据解码出来,也就是说有两个复杂度,但是如果换成redis的话,因为它有类型了,类型是什么意思?类型其实并不是太重要的,重要的是redis Server中对每种类型都有自己的方法,也就是说其实他可能给你提供了一个什么?基于index(),让你给出一个索引下标,或者lpop怎么怎么样,也就是你的客户端只需要向对方调一个我取value的某一个元素,或者左边或右边弹出一个元素,那么这个时候其实他就规避了上面的问题,你客户端不需要写很多的,因为他不需要把全量数据取走,你的redis Serve网卡就ok,然后你客户端的代码也比较轻盈。

就比如使用过redistemplate的,都知道其返回值是直接对应了某种具体的类型了,就不再需要我们自己手动编写某种方式去解析从memcache那里面取出来的json了。这也就是为什么Redis渐渐取代了memcache的原因。
在这里插入图片描述

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

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

相关文章

Python排序:冒泡排序,选择排序,插入排序,希尔排序

编程中的交换元素逻辑: # python中交换元素 有内置的三方底层逻辑 可以直接交换 a 2 b 3 a, b b, a print(a) # a为3# 其他编程需要有一个中间的变量来转换 变量设为temp a 2 b 3 temp a a b b temp print(a) # a为3 -----冒泡排序----- 相邻…

openfeign原理

openfeign原理 EnableFeignClients注解启用Feign客户端,通过Import注解导入了FeignClientsRegistrar类加载额外的Bean。FeignClientsRegistrar实现了ImportBeanDefinitionRegistrar接口,在Spring启动过程中会调用registerBeanDefinitions方法注册BeanDe…

自动化项目倍加福WCS-PG210E使用GSD文件

1.硬件电气连接 WCS-PG210E WCS3B WCS2B Pin 颜色 Pin 颜色 24V UB 1 BN棕色 2 WH白色 0V GND 3 BU蓝色 3 BU蓝色 RS485- RS485- 4 BK黑色 1 BN棕色 RS485 RS485 2 WH白色 4 BK黑色 保留 5 GY灰色 5 GY灰色 2. 安装W…

Nginx (4):nginx动静分离

什么是动静分离不解释了,网上说的很清楚,这里只说配置 目的 02虚拟机运行一个tomcat,处理动态请求,而对静态文件的访问则交给01虚拟机。操作 下面是01虚拟机的配置文件内容: server {listen 82;listen [::]:82;#root /…

六、nacos环境隔离、服务配置拉取和多环境配置共享

文章目录一、环境隔离-namespace1.namespace理解2.创建命名空间二、Nacos-实现配置管理三、nacos-实现服务配置拉取1.非热更新2.热更新:四、实现多环境配置共享1.开发环境:2.测试环境3.结论一、环境隔离-namespace 1.namespace理解 Nacos中服务存储和数…

Element Plus 组件库相关技术:7. 组件实现的基本流程及 Icon 组件的实现

前言 本章节我们将要实现 Icon 组件,Icon 组件应该是所有组件里面最简单的一个组件了,所以我们由简入深,循序渐进进行学习。Icon 组件虽然简单,但它却包含了一个组件的全部基础流程,通过实现 Icon 组件进行理解 Eleme…

疫情失业之下,测试的未来在哪里

前天和测试圈子里一个朋友聊了关于今年求职招聘市场行情和个人认知以及发展副业的话题。 聊起了今年的求职招聘行情,他说他们公司已经裁了一波人了,估计年底还会有一波裁员。 今年的市场冷的有点吓人,在这么下去,他也会担心自己…

nacos实现负载均衡、权重

文章目录一、nacos服务分级存储模型二、Nacos-NacosRule 实现负载均衡三、nacos-服务实例的权重设置一、nacos服务分级存储模型 修改 application.yml 配置文件: spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZ #集群位置&#xff0c…

Linux C/C++ 学习笔记(九):百万并发的服务器实现

本文内容参考自(2条消息) Linux C/C 开发(学习笔记十三):百万并发的服务器实现_菊头蝙蝠的博客-CSDN博客_linux百万并发 一、connection_refuesed ---->文件系统最大的进程fd个数 nat 模式,物理机的VMnet8网卡,连接到了VMnet…

selenium--关闭窗口,指定窗口大小,前进,后退,刷新等等

关闭窗口跳转到指定页面窗口大小设置返回上个页面前进到下一个页面页面刷新关闭窗口 在selenium中执行完关闭窗口一般有两种方法: driver.close() driver.quit()这两个都是常用的方法,但是他们有什么区别呢? 对于driver.close(),他是关闭当…

【FME实战教程】003:FME读取地理空间数据(矢量、栅格、点云、三维模型、数据库、地理服务)大全

FME读取地理空间数据(矢量、栅格、点云、三维模型、空间数据库、地理服务)大全。 文章目录1. FME读取数据1.1 读取矢量1.1.1 读取Shapefile1.1.2 读取dwg1.2 读取栅格数据1.2.1 影像DOM1.3 读取地理数据库1.3.1 读取文件数据库(.gdb&#xff…

机械原理复习试题

​ 编辑切换为居中 添加图片注释,不超过 140 字(可选) ​ 编辑切换为居中 添加图片注释,不超过 140 字(可选) ​ 编辑 添加图片注释,不超过 140 字(可选) ​ 编辑…

聚类分析的基本概念和方法

聚类分析的基本概念和方法 文章目录聚类分析的基本概念和方法前言一、什么是聚类分析1、聚类分析基本流程与步骤2、 什么是好的聚类方法3、聚类的模型评估4、聚类分析的比较5、聚类分析的挑战二、基本聚类方法概述三、划分算法1、基本概念2、k-means 聚类方法1、k-means 方法的…

CMake中configure_file的使用

CMake中的configure_file命令用于将一个文件拷贝到另一个位置并修改其内容&#xff0c;其格式如下&#xff1a; configure_file(<input> <output>[NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |FILE_PERMISSIONS <permissions>...][COPYONLY] [ESCAPE_…

01 一条SQL 语句是如何执行的?

select * from teacher where id 10 1、一条简单的sql语句底层的执行过程是怎么样的&#xff1f; 答&#xff1a;一条sql执行会经过连接器、查询缓存、分析器、优化器和执行器等步骤。 2、连接器的作用是什么&#xff1f; 答&#xff1a;sql查询&#xff0c;首先连接到这个数…

【机器学习项目实战10例】(四):利用XGBoost实现短期电力负荷预测

💥 项目专栏:【机器学习项目实战10例】 文章目录 一、利用XGBoost实现短期电力负荷预测二、数据集介绍三、将数据进行标准化四、形成训练数据五、划分训练集、测试集六、定义模型七、模型训练八、训练集、测试集验证九、网络搜索十、绘制结果一、利用XGBoost实现短期电力负荷…

分布式事务

一、事务 1.1、什么是事务&#xff1f; 事务&#xff08;transaction&#xff09;是访问并操作数据库中数据的一个程序执行单元&#xff0c;由开始事务和提交事务之间的所有的语句组成。事务的结束有两种&#xff0c;一个是事务中间的所有操作执行成功&#xff0c;提交事务。一…

UE5笔记【九】蓝图BluePrint;

新建一个第三视角游戏。然后打开关卡蓝图。 长得跟材料编辑器一样。 这里是我们创建Node和新功能的地方。 首先我们新建一个游戏开始的地方。右键&#xff1a;Begin搜索。 我们需要打印一行字&#xff1a;欢迎来到游戏世界。我们需要添加一个打印文本的结点&#xff1a;PrintT…

APS自动排产 — 排产结果拉动物料需求计划

一、APS系统生产计划前应该注意哪些 建立好基础资料 标准产能&#xff1a;所有产品的标准产能&#xff0c;来自于工程技术部。如果工程技术部无法提供标准产能&#xff0c;则请生产部门根据实际提供相对准确的标准产能。技术资料&#xff1a;产品的物料清单(BOM)、图纸、工程…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java线上学习系统8e88w

做毕业设计一定要选好题目。毕设想简单&#xff0c;其实很简单。这里给几点建议&#xff1a; 1&#xff1a;首先&#xff0c;学会收集整理&#xff0c;年年专业都一样&#xff0c;岁岁毕业人不同。很多人在做毕业设计的时候&#xff0c;都犯了一个错误&#xff0c;那就是不借鉴…