《Redis 核心技术与实战》课程学习笔记(二)

news2024/11/26 7:27:51

数据结构:快速的 Redis 有哪些慢操作

  • 数据库这么多,为啥 Redis 能有这么突出的表现呢?
    • 一方面,因为它是内存数据库,所有操作都在内存上完成,内存的访问速度本身就很快。
    • 另一方面,因为,键值对是按一定的数据结构来组织的,操作键值对最终就是对数据结构进行增删改查操作,所以高效的数据结构是 Redis 快速处理数据的基础。
  • 简单来说,底层数据结构一共有 6 种,分别是简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。
    在这里插入图片描述

键和值用什么结构组织?

  • 为了实现从键到值的快速访问,Redis 使用了一个哈希表来保存所有键值对。
    • 一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。
    • 一个哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据。
    • **哈希桶中的元素保存的并不是值本身,而是指向具体值的指针。**这也就是说,不管值是 String,还是集合类型,哈希桶中的元素都是指向它们的指针。
  • 哈希桶中的 entry 元素中保存了 *key 和 *value 指针,分别指向了实际的键和值,这样一来,即使值是一个集合,也可以通过 *value 指针被查找到。
    在这里插入图片描述
    • 因为这个哈希表保存了所有的键值对,所以,我也把它称为全局哈希表。
    • 哈希表的最大好处很明显,就是让我们可以用 O(1) 的时间复杂度来快速查找到键值对⸺我们只需要计算键的哈希值,就可以知道它所对应的哈希桶位置,然后就可以访问相应的 entry 元素。

为什么哈希表操作变慢了?

  • 当你往哈希表中写入更多数据时,哈希冲突是不可避免的问题。
    • 哈希冲突就是指两个 key 的哈希值和哈希桶计算对应关系时,正好落在了同一个哈希桶中。
    • Redis 解决哈希冲突的方式,就是链式哈希,即同一个哈希桶中的多个元素用一个链表来保存,它们之间依次用指针连接。
      在这里插入图片描述
  • 哈希冲突链上的元素只能通过指针逐一查找再操作。
    • 如果哈希表里写入的数据越来越多,哈希冲突可能也会越来越多,这就会导致某些哈希冲突链过长,进而导致这个链上的元素查找耗时长,效率降低。
    • 对于追求“快”的 Redis 来说,这是不太能接受的。
    • 所以,Redis 会对哈希表做 rehash 操作。
    • rehash 也就是增加现有的哈希桶数量,让逐渐增多的 entry 元素能在更多的桶之间分散保存,减少单个桶中的元素数量,从而减少单个桶中的冲突。
      • 其实,为了使 rehash 操作更高效,Redis 默认使用了两个全局哈希表:哈希表 1 和哈希表 2。
      • 一开始插入数据时,默认使用哈希表 1,此时的哈希表 2 并没有被分配空间。
      • 随着数据逐步增多,Redis开始执行 rehash,这个过程分为三步:、
        • 给哈希表 2 分配更大的空间,例如是当前哈希表 1 大小的两倍;
        • 把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中;
          • Redis 采用了渐进式 rehash。
          • 每处理一个请求时,从哈希表 1 中的第一个索引位置开始,顺带着将这个索引位置上的所有 entries 拷贝到哈希表 2 中;
          • 等处理下一个请求时,再顺带拷贝哈希表 1 中的下一个索引位置的 entries。
        • 释放哈希表 1 的空间。

集合数据操作效率

  • 和 String 类型不同,一个集合类型的值,第一步是通过全局哈希表找到对应的哈希桶位置,第二步是在集合中再增删改查。
  • 集合类型的底层数据结构主要有 5 种:整数数组、双向链表、哈希表、压缩列表和跳表。
    • 压缩列表实际上类似于一个数组,数组中的每一个元素都对应保存一个数据。
      • 和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail 和 zllen,分别表示列表长度、列表尾的偏移量和列表中的 entry 个数;
      • 压缩列表在表尾还有一个 zlend,表示列表结束。
        在这里插入图片描述
      • 在压缩列表中,如果我们要查找定位第一个元素和最后一个元素,可以通过表头三个字段的长度直接定位,复杂度是 O(1)。
      • 查找其他元素时,就只能逐个查找,此时的复杂度就是 O(N)。
    • 跳表在链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位。
      在这里插入图片描述
      • 为了提高查找速度,我们来增加一级索引:从第一个元素开始,每两个元素选一个出来作为索引。这些索引再通过指针指向原始的链表。
      • 如果我们还想再快,可以再增加二级索引:从一级索引中,再抽取部分元素作为二级索引。
      • 可以看到,这个查找过程就是在多级索引上跳来跳去,最后定位到元素。
      • 当数据量很大时,跳表的查找复杂度就是 O(logN)。

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

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

相关文章

SQL入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

导读: SQL语言有40多年的历史,从它被应用至今几乎无处不在。我们消费的每一笔支付记录,收集的每一条用户信息,发出去的每一条消息,都会使用数据库或与其相关的产品来存储,而操纵数据库的语言正是 SQL &…

vue页面中一个小列表中多选框的选中状态的两种设置方法

第一种方法:所有类型都是固定的、后台提供了选中状态的接口(页面进入时默认展示所有类型和类型的选中状态 思路: 1、列出所有类型同时与后台规定好每种类型的id与对应的名称 2、在mounted中执行获取后台给定的选中状态(包含1个或多个的id数组) 3、将得到的结构绑定到el-ch…

单元测试基础

一、什么是单元测试: 单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类;单元测试属于最严格的软件测试手段,是最接近代码底层实现…

剑指 Offer 14- II: 剪绳子 II

这道题不能使用动态规划来解决,因为会越界。用贪心算法找规律可以得到答案(3越多越好,小于等于4取本身的值) 这道题错的原因在于res在存储过程中会越界,最轻微的上溢是 INT_MAX 1 :结果是 INT_MIN。 最严重…

C++学习笔记-第10单元 模板初步

第10单元 模板初步 文章目录 第10单元 模板初步单元导读10.1 模板与泛型编程10.1.1 元编程与泛型编程10.1.2 初识模板 10.2 函数模板10.2.1 函数模板10.2.2 函数模版实例化 10.3 排序示例与泛型化10.3.1 例子:选择排序10.3.2 将一个函数泛型化 10.4 类模板10.4.1 类…

基于matlab使用深度学习从分割图生成图像(附源码)

一、前言 此示例演示如何使用 pix2pixHD 条件生成对抗网络 (CGAN) 从语义分割映射生成场景的合成图像。 Pix2pixHD [1] 由两个同时训练的网络组成,以最大限度地提高两者的性能。 生成器是一种编码器-解码器风格的神经网络,可从语…

设置云服务器和配置docker

一、设置云服务器 刚租完服务器,直接利用公网ip登录此时进入到的是root目录下 ssh root公网ip 但是root的权限太大,一般做项目不会在root路径下直接操作,会创建一个子用户,一台服务器可以创建多个子用户,就像一个大…

通用二进制方式安装Mysql

一、去官网下载MySQL glibc版本 示例环境为CentOS 7.9版本,要安装的Mysql版本为5.7 1.选择版本下载到自己本地 下载地址:https://dev.mysql.com/downloads/mysql/ 2.将下载的tar包上传到自己的CentOS虚拟主机上 传输完成后,查看确认一下 …

Tomcat相关

1. 运行项目 将java项目打包为war或者war所对应的文件夹,放置于tomcat的webapps目录下。其实tomcat运行时会解压war到项目中并运行class文件,延伸开来,为啥不能用jar包,因为jar可能可以表示项目但也能表示依赖,tomcat…

Linux 内核和驱动开发工程师的发展前景怎么样?

或许这样的标题,应该是由像Linus或Greg KH这样的大师级的高手才有资格写的吧。但是作为我来说,也许我更想把这个标题作为一个疑问句来使用,整理一下自己的认识,用来勉励自己,和大家一起努力实现这个目标。认识肤浅的地…

4.51ue4:savegame

1.创建savegame,蓝图搜索savegame创建 2.ue4是类似于计算机磁盘读取和内存响应的方式进行保存数据,又称序列化。 详解: 序列化时类似于:从内存保存数据到磁盘的过程,是将数据进行序列化存入磁盘。 读取数据就是反序…

社区说|浅谈 WorkManager 的设计与实现:系统概述

什么是 社区说 ? 反思 系列博客是一种看似 “内卷” ,但却 效果显著 的学习方式,该系列起源和目录请参考 这里 。 困境 作为一名 Android 开发者,即使你没有用过,也一定对 WorkManager 耳熟能详。 自2018年发布以来&#xff0c…

设计模式第22讲——访问者模式(Visitor)

目录 一、什么是访问者模式 二、角色组成 三、优缺点 四、 应用场景 4.1 生活场景 4.2 Java场景 五、代码实现 5.0 UML类图 5.1 抽象访问者——Visitor 5.2 具体访问者——Tourist 5.3 抽象元素——Spot 5.4 具体元素——View、Relic 5.5 对象结构——SpotCollecti…

大厂面试打起12万分小心?3轮技术面过,你也可能挂在HR手上!

很多朋友在面试大厂时存在一个误区,认为面试你的那个是最初给你打电话的HR,其实不然,更大可能是业务部门相关的 HRBP导致你面试失败。 1、什么是HRBP? 为了解释清楚这个问题,先说 HRBP 是什么。HRBP全称为 Human Resource Busin…

java对象clone

Object提供了colne方法给我们定义的类,用来进行对象克隆,但是这个clone方法是protected的,所以需要在我们需要使用clone的类中重写Object的clone方法,并且需要实现Cloneable接口,Cloneable接口是一个标记接口&#xff…

「JVS低代码开发平台2.1.8版本」-首页功能介绍

JVS是面向软件开发团队可以快速实现应用的基础开发脚手架,主要定位于企业信息化通用底座,采用微服务分布式框架,提供丰富的基础功能,集成众多业务引擎,它灵活性强,界面化配置对开发者友好,底层容…

【Java】Netty中ByteBuf学习笔记

文章目录 1) ByteBuf创建与自动扩容2)直接内存 vs 堆内存3)池化 vs 非池化4)组成5)写入6)扩容7)读取8)retain & release9)slice10)duplicate11)copy12&am…

给LLM装上知识:从LangChain+LLM的本地知识库问答到LLM与知识图谱的结合

第一部分 基于LangChain ChatGLM-6B的本地知识库问答的应用实现 1.1 什么是LangChain:连接本地知识库与LLM的桥梁 作为一个 LLM 应用框架,LangChain 支持调用多种不同模型,提供相对统一、便捷的操作接口,让模型即插即用&#x…

java并发编程 6:java内存模型与volatile(重点)

目录 硬件内存模型Java 内存模型主内存工作内存内存交互的八个原子操作JMM作用 可见性退不出的循环volatile解决同步模式之 Balking 有序性指令重排解决指令重排 volatile 原理volatile如何保证可见性volatile如何保证有序性volatile 不能解决指令交错double-checked locking 问…

2023/7/5总结

JS BOM 是浏览器对象模型 window对象是一个全局对象,也是JavaScript的顶级对象 所以通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法 定时器-延时函数 setTimeout(回调函数,等待的毫秒数) 延时函数只会执行一次 清除延时函…