Java 面试 - Redis

Redis

Redis 是基于键值对的非关系型数据库。Redis 拥有string、hash、list、set、zset等多种数据结构, redis具有惊人的读写性能, 其优秀的持久化机制是的它在断电和机械故障时也不会发生数据丢失, 可以用于热点数据存放, 还提供了键过期、发布订阅、食物、流水线、LUA脚本等多个高级功能。

1 Redis 数据结构

  • string: 最基本数据类型, 可以存放入二进制、序列化数据、JSON对象、图片等数据

    • 底层实现: SDS(Simple Dynamic String) - 动态字符串

      可修改字符串, 采用预分配冗余空间的方式减少内存的频繁分配。与Java中的ArrayList比较类似, 实质上也是在空间不足时触发扩容机制, 如果 SDS 值大小< 1M , 则增加一倍;反之如果>1M , 则当前空间加1M作为新的空间。
      在这里插入图片描述

      struct sdshdr{//记录buf数组中已使用字节的数量//等于SDS保存字符串的长度4byteint len;//记录 buf数组中未使用字节的数量 4 byteint free;//字节数组,用于保存字符串字节\0结尾的字符串占用了1bytechar buf[];
      }
      
  • list: 字符串列表, 按照插入的顺序排序, 元素可以重复, 底层由 链表 实现。

    • 底层实现: ZIPList| LinkedList(双向链表)

      当元素字符串的长度小于64字节而且元素个数小于512时,采用 zipList;否则采用likedList;

      • ZIPList - 压缩列表: 由连续内存块组成且用于存储小型有序集合或哈希集合的数据结构。主要参数包括: 整个列表占用字节数、偏移量、元素个数、内容列表、结束标志。 优点: 节省空间
        在这里插入图片描述

        struct ziplist<T> {int32 zlbytes; // 整个压缩列表占用字节数int32 zltail_offset; // 最后一个元素距离压缩列表起始位置的偏移量,用于快速定位到最后一个节点int16 zllength; // 元素个数T[] entries; // 元素内容列表,挨个挨个紧凑存储int8 zlend; // 标志压缩列表的结束,值恒为 0xFF
        }
        
  • hash: string 类型 field 和 value 的集合, 适合存放对象

    • 底层实现: ZIPList | HashTable

      当hash对象的键与值的长度都小于64字节时而且键值对的个数小于512个,采用zipList,其它情况,采用hashTable

      • ZIPLIST: 参考上述

      • HashTable - 哈希表

        ① 数组 + 链表 ②数组+红黑树(树化方便查找)

        根据Key value而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录(类似索引),以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

  • set: 无序不重复的集合

    • 底层实现: INTSet | HashTable

      当保存的元素都是整形数字,而且元素个数小于配置范围的时候,则使用intset,否则使用hash表。

      • INTSet - 整数集合

        可变长度的整型数组 - 基于整数数组来实现,并且具备长度可变、有序等特征, 包含: 编码方式、长度、内容等主要属性(可以选择不同位数的整数存储)。

        typedef struct intset {uint32_t encoding; /* 编码方式,支持存放16位、32位、64位整数 */uint32_t length;  /* 元素个数 */int8_t contents[];  /* 整数数组,保存集合数据 */
        } intset;
        
  • zset: 与 set 一样都是 String 类型元素的集合, 且不允许重复, 但 zset 每个元素都会关联一个分数, Redis通过分数来为集合汇总的成员进行从小到大的排序。

    • 底层实现: ZIPList| SKIPList

      • ZIPList: 参考上述

      • SKIPList:

        一种有序的数据结构,通过在每个节点维护多个指针,从而达到快速访问的目的。 优点: 实现简单、内存消耗少 缺点: 不适合范围查询

        跳跃表 - 跳跃表节点结构定义

        typedef struct zskiplist{// 表头节点和表尾节点struct zskiplist *header,*tail;// 表节点个数unsigned long length;// 表节点最大层数int level;
        }zskiplist;
        
        typedef struct zskiplistNode{// 层struct zskiplistLevel{// 前进指针struct zskiplistNode *forward;// 跨度unsigned int span;}level[];// 后退指针struct zskiplistNode *backward;// 分值double score;// 成员对象robj *robj;
        }zskiplistNode;
        
  • 四种特殊数据类型: 1)bitmap 2)hyperloglog 3)geo 4)stream

1) zset 与 set 的区别

  • set 无序, zset 有序

  • zset 底层使用压缩列表和跳跃列表( ziplist & skiplist )

    set 使用 INTSet 和 HashTable

2 Key 过期策略

  • 定期删除 - 过期 Key 保存在字典, 定期随机抽取20个Key, 删除其中过期的, 如果比例超过1/4, 重复删除步骤。

    redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。

    Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。

    1.从过期字典中随机 20 个 key;

    2.删除这 20 个 key 中已经过期的 key;

    3.如果过期的 key 比率超过 1/4,那就重复步骤 1;

    redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。

  • 惰性删除 - 访问时发现 Key 过期, 直接删除不返回任何值

    在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。

    定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西。

3 内存淘汰策略

数据的淘汰策略: 当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。

  • noeviction: 不淘汰任何key,但是内存满时不允许写入新数据,默认策略。

  • volatile-TTL: 对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰。

  • allkeys -RANDOM: 对全体key,随机进行淘汰。

  • volatile-RANDOM: 对设置了TTL的key,随机进行淘汰。

  • alkeys -LRU: 对全体key,基于LRU算法进行淘汰

  • volatile-LRU: 对设置了TTL的key,基于LRU算法进行淘汰

  • allkeys -LFU: 对全体key,基于LFU算法进行淘汰

  • volatile-LFU: 对设置了TTL的key,基于LFU算法进行淘汰

4 主从同步机制

  • 主从同步

    • 全量同步

      一般发生在第一次连接时, 原理为将当前数据写入到RDB文件后发送给从机读取到丛机的内存中。

    • 增量同步

      一般发生在第一次之后的链接时, 主机同步期间发生的数据变化会以命令的形式写入缓存中, 当校验到正确的从机ID时获取从机的偏移量,然后从偏移量记录的命令开始将未同步的数据操作命令发送给从机执行, 进而完成数据同步。


updating …

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

诗诺克科技引领数字资产智能交易革命

在当今全球金融市场中&#xff0c;数字资产的崛起正引发着一场前所未有的变革。随着区块链技术不断演进和数字资产广泛获得认可&#xff0c;智能交易系统正在迅速成为投资者和交易者的首选工具。这一趋势不仅在全球范围内显著&#xff0c;而且为金融领域的未来带来了令人瞩目的…

1.2 互联网概述

思维导图&#xff1a; 主要内容 &#xff1a; 这段话描述了“互联网”的基本概念和组成。首先&#xff0c;强调了该段文本主要是关于计算机网络的讨论&#xff0c;而不是关于电信网络或有线电视网络。 接下来&#xff0c;描述了计算机网络的基本构成&#xff0c;由结点&…

赞奇科技参与华为云828 B2B企业节,云工作站入选精选产品解决方案

8月27日&#xff0c;由华为云携手上万家伙伴共同发起的第二届 828 B2B 企业节拉开帷幕&#xff0c;围绕五大系列活动&#xff0c;为万千中小企业带来精细化商机对接。 聚焦行业数字化所需最优产品&#xff0c;举办超1000场供需对接会&#xff0c;遍及20多个省100多个城市&…

ACL 访问控制 过滤数据 维护网络安全(第七课)

一 ACL 简介 ACL是Access Control List(访问控制列表)的缩写,是一种用于控制文件、目录、网络设备等资源访问权限的方法。ACL可以对每个用户或用户组设置不同的访问权,即在访问控制清单中为每个用户或用户组指定允许或禁止访问该资源的权限。它通常由一系列规则组成,规则…

使用docker容器内的anaconda虚拟环境启动python web项目

1、环境安装 1.1 基础镜像 这里以ubuntu18.04 cuda 11.8为基础镜像&#xff08;主机支持nvidia-gpu&#xff09; &#xff08;1&#xff09;拉取ubuntu18.4 cuda11.8镜像 docker pull nvidia/cuda:11.8.0-devel-ubuntu18.04 1.2 docker下anaconda安装 &#xff08;1&am…

【STL】模拟实现map和set {map和set的封装;核心结构;插入和查找;红黑树的迭代器;STL中的红黑树结构}

模拟实现map和set map和set是红黑树的两种不同封装形式&#xff0c;底层使用同一颗泛型结构的红黑树&#xff0c;只是存储类型不同。set是红黑树的K模型&#xff0c;存储key&#xff1b;map是红黑树的KV模型&#xff0c;存储pair<key,value>。 下面的代码和讲解着重体现…

Linux 进程基础概念-进程状态、进程构成、进程控制

目录 Linux 进程 进程基础概念 进程状态 进程的构成 进程控制 进程创建和终止 Linux 进程 参考&#xff1a; 「linux操作系统」进程的切换与控制到底有啥关系&#xff1f; - 知乎 (zhihu.com)&#xff0c;Linux进程解析_deep_explore的博客-CSDN博客&#xff0c;腾讯面试…

蓝桥杯打卡Day1

文章目录 全排列八皇后 一、全排列IO链接 本题思路:本题是一道经典的全排列问题&#xff0c;深度优先搜索即可解决。 #include <bits/stdc.h>constexpr int N10;std::string s; std::string ans; int n; bool st[N];void dfs(int u) {if(un){std::cout<<ans<…

mysql与msql2数据驱动

mysql基本使用 数据库操作&#xff08;DDL&#xff09; -- 数据考操作 -- 1.查询所有数据库 SHOW DATABASES;-- 2.选择数据库 USE learn_mysql;-- 3.当前正在使用的数据库 SELECT DATABASE();-- 4.创建数据库 CREATE DATABASE IF NOT EXISTS learn_mysql;-- 5.删除数据库 DRO…

《TCP/IP网络编程》阅读笔记--基于TCP的服务器端/客户端

目录 1--TCP/IP协议栈 2--TCP服务器端默认函数调用顺序 3--TCP客户端的默认函数调用顺序 4--Linux实现迭代回声服务器端/客户端 5--Windows实现迭代回声服务器端/客户端 6--TCP原理 7--Windows实现计算器服务器端/客户端 1--TCP/IP协议栈 TCP/IP协议栈共分 4 层&#xf…

聊聊如何玩转spring-boot-admin

前言 1、何为spring-boot-admin&#xff1f; Spring Boot Admin 是一个监控工具&#xff0c;旨在以良好且易于访问的方式可视化 Spring Boot Actuators 提供的信息 快速开始 如何搭建spring-boot-admin-server 1、在服务端项目的POM引入相应的GAV <dependency><grou…

kali 安装cpolar内网穿透实现 ssh 远程连接

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过cpolar 内网穿透软件实现ssh 远程连接kali! 1. 启动kali ssh 服务 默认新安装的kali系统会关闭ssh 连接服务,我们通…

接入 NVIDIA A100、吞吐量提高 10 倍!Milvus GPU 版本使用指南

Milvus 2.3 正式支持 NVIDIA A100&#xff01; 作为为数不多的支持 GPU 的向量数据库产品&#xff0c;Milvus 2.3 在吞吐量和低延迟方面都带来了显著的变化&#xff0c;尤其是与此前的 CPU 版本相比&#xff0c;不仅吞吐量提高了 10 倍&#xff0c;还能将延迟控制在极低的水准。…

【sgLazyTree】自定义组件:动态懒加载el-tree树节点数据,实现增删改、懒加载及局部数据刷新。

特性 可以自定义主键、配置选项支持预定义节点图标&#xff1a;folder文件夹|normal普通样式多个提示文本可以自定义支持动态接口增删改节点 sgLazyTree源码 <template><div :class"$options.name" v-loading"rootLoading"><div class&qu…

我使用的Vim插件

2023年9月5日&#xff0c;周二下午 为了方便以后还原自己的Vim插件配置&#xff0c;于是写这篇博客来记录一下 不定期更新 目录 语法检查Syntastic文件树The NERD tree自动补全括号auto-pairs超轻量级自动补全vim-auto-popmenu 我使用的插件管理器是vim-plug 语法检查Syntas…

Java学习笔记之----I/O(输入/输出)二

【今日】 孩儿立志出乡关&#xff0c;学不成名誓不还。 文件输入/输出流 程序运行期间&#xff0c;大部分数据都在内存中进行操作&#xff0c;当程序结束或关闭时&#xff0c;这些数据将消失。如果需要将数据永久保存&#xff0c;可使用文件输入/输出流与指定的文件建立连接&a…

GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图

GPT对于每个科研人员已经成为不可或缺的辅助工具&#xff0c;不同的研究领域和项目具有不同的需求。如在科研编程、绘图领域&#xff1a;1、编程建议和示例代码: 无论你使用的编程语言是Python、R、MATLAB还是其他语言&#xff0c;都可以为你提供相关的代码示例。2、数据可视化…

操作系统强化认识之Shell编程学习与总结

目录 1.Shell的概述 2.Shell脚本入门 3.变量 3.1.系统预定义变量 3.2.自定义变量 3.3.特殊变量 4.运算符 5.条件判断 6.流程控制 6.1.if判断 6.2.case语句 6.3.for循环 6.4.while循环 7.read读取控制台输入 8.函数 8.1.系统函数 8.2.自定义函数 9.正则表示式入…

Python,如何安装lap,pip安装lap出现问题

Linux可以&#xff1a; pip install cpython pip install gitgit://github.com/gatagat/lap.gitwindows可以&#xff1a; 下载https://github.com/gatagat/lap 后解压&#xff0c; 安装pip install cpython 安装VS2019企业版&#xff1a; key BF8Y8-GN2QH-T84XB-QVY3B-RC4D…

Python 之 match 表达式

Python 从 3.10 版本开始增加了 match 语句&#xff0c;和其他语言常见的 switch 语句极其相似&#xff0c;但功能更加强大。 本文通过实例&#xff0c;了解下其用法。 基本的 match 语句 def http_code(status): match status: case 400 | 404 | 418: …