Java技术栈总结:Redis篇

一、数据类型

Redis 自身是一个 Map,其中的所有数据均采用“key:value”的形式存储。

数据类型指的是存储的数据的类型,即 value 部分的类型,key 的部分只能是字符串。

value 部分的数据类型:<String、List、Hash、Set、Zset、HyperLogLog>

  • List 是双向链表实现,存储的数据都是 String 类型;
  • Hash 底层为数组加链表,出现哈希冲突使用的是头插法向链表添加数据;Rehash 的过程为渐进式 Rehash,内部维护了两个哈希表 Ht[0]、Ht[1],其中 Ht[0]是一般用到的哈希表,Ht[1]只在 Rehash 的过程中才会用到;
  • Set
  • Zset 如何实现排行榜?
  • HyperLogLong

二、I/O模型

<socket请求--I/O多路复用程序--文件事件分派器--事件处理器>

I/O多路复用机制:通过监视多个描述符,一旦某个描述符就绪,就能够通知程序进行响应;包括select、poll、epoll等;

Redis的I/O模型默认采用的机制为epoll

【采用单线程较快的原因】

  • Redis大部分操作都是在内存中直接完成的,采用的数据结构如哈希表、跳表;
  • 采用了多路复用机制,使得网络I/O操作能并发处理大量的客户端请求。

三、持久化 AOF|RDB

  • AOF(append only file),将操作写入到日志文件,命令执行成功才进行写入,有三种模式:
    • always,同步写回--有命令执行成功,立即将日志写入磁盘;(满足持久性)
    • everysec,命令执行完,先把日志写入到AOF缓冲区,每隔一秒写一次磁盘;
    • no,只写入到AOF缓存区,由操作系统决定何时写磁盘。
  • RDB(Redis DataBase),把内存数据以快照的形式保存的磁盘上,与AOF相比,它记录的是某一时刻的数据,不是操作。

四、主从复制

1、主从复制设置:

  • 通过1)在从节点执行“SLAVE OF 主节点ip 端口号”;
  • 或者2)设置“slaveof选项”;

2、旧版主从同步

分为两个步骤:同步、命令传播。

  • 同步:
    • 从向主发送“SYNC命令”;
    • 主服务器收到后执行“BGSAVE”命令,生成一个“RDB”文件,并使用缓冲区记录从现在开始执行的所有命令;
    • BGSAVE命令执行完成后,主向从发送RDB文件,从服务器接收并载入,将自己更新成主服务器执行BGSAVE命令时刻的数据库状态;
    • 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行,更新状态到主服务器当前状态。
  • 命令传播:
    • 主服务器将自身执行的写命令,发送给从服务器执行。

   问题:一旦断开连接,需要从头开始执行,而不是只同步断开期间的命令,效率低。

3、新版主从同步(版本2.8开始)

  • 使用“PSYNC命令”代替了旧版的“SYNC命令”;包括完整重同步和部分重同步两种模式,其中完整重同步同旧版的同步过程,用于初次同步;部分重同步用于处理断线后的重连接情况。
  • 断线后重连接,如果条件允许,主服务器可将断线期间执行的写命令发送给从服务器,从服务器接收并执行,从而将状态更新为主服务器当前状态。
  • 断线重连接后的“如果条件允许”,条件是判断从服务器断开时刻的复制偏移量和主服务器的“复制积压缓冲区”数据的关系。如果偏移量之后的数据存在于缓冲区则执行部分重同步,否则全量。

4、高可用性

哨兵 + 主从架构。

主节点负责进行写数据操作,从节点进行读数据操作。主节点写数据成功会直接返回成功的消息通知,但是如果还没有将数据同步给从节点,主节点就宕机的话,从节点成为新的主节点,刚新写入的数据就丢失了。

哨兵的数量为奇数个。


五、过期淘汰策略

Redis 的过期策略以及内存淘汰机制?

1、过期策略:

定时删除、定期删除、惰性删除。实际使用:<定期 + 惰性>

2、内存淘汰机制:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(默认选项,一般不会选用)
  • allkeys-lru:……,在整个键空间中,移除最近最少使用的key。(这个是最常用的)(间隔时间长)
  • allkeys-lfu:……,在整个键空间中,移除最不经常(最少)使用的key(使用频率低)。
  • allkeys-random:……,在整个键空间中,随机移除某个key。
  • volatile-lru:……,在设置了过期时间的键空间中,移除最近最少使用的key。
  • volatile-lfu:……,在设置了过期时间的键空间中,移除最不经常(最少)使用的key。
  • volatile-random:……,在设置了过期时间的键空间中,随机移除某个key。
  • volatile-ttl:……,在设置了过期时间的键空间中,过期时间早的key优先移除。

3、内存淘汰算法:

  • 先进先出(FIFO)算法;
  • 最近最少使用算法(LRU)算法;
  • 最不常用(LFU)算法;

六、Redis事务

1、相关命令

涉及命令:MULTI、EXEC、WATCH等;

开启事务:MULTI;

提交事务:EXEC;

2、实现

(1)事务队列

开启事务到提交事务之间的命令都会被放入“事务队列”中,事务队列是一个 multiCmd 类型的数组。以先进先出的方式保存入队的命令。

客户端执行事务提交命令EXEC时,该命令会立即被服务器执行。

服务器会遍历对应客户端的事务队列,执行队列中保存的命令,然后将执行的结果全部返回给客户端。

(2)WATCH命令

一个乐观锁,在EXEC命令执行前,监视任意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否有被修改的情况。如果有,服务器拒绝执行该事务,并向客户端返回执行失败的空回复。

每个Redis数据库都保存着一个watched_keys”字典,该字典的键为被WATCH命令监视的数据库键,字典的值为一个链表,链表的内容为所有监视该数据库键的客户端

所有对数据库修改的命令,都会触发对 watched_keys 字典的检查,如果有对应的key的话,会把监视该键的所有客户端的 REDIS_DIRTY_CAS 标志打开,表示该客户端事务的安全性已经被破坏。

3、与关系型数据库事务的区别

不支持回滚。

即使在执行过程中出现了错误,出现错误前后的命令也不会受到影响,会全部执行完。


七、分布式寻址算法

分布式寻址算法:1)hash算法;2)一致性哈希 + 虚拟节点;3)hash slot(hash槽)算法

  • hash算法:将不同的请求hash碰撞后放到固定的hash桶中;扩缩容可用性低;
  • 一致性hash:将hash值空间组织成一个虚拟的圆环;顺时针查找;使用虚拟节点解决分布不均的问题;
  • hash槽(默认):记录和物理机之间引入了虚拟桶层,记录通过hash函数映射到虚拟桶,记录和虚拟桶是多对一的关系;第二层是虚拟桶和物理机之间的映射,同样也是多对一的关系,即一个物理机对应多个虚拟桶,这个层关系是通过内存表实现的。

八、布隆过滤器

注:误判断的情况,可以考虑使用两套布隆过滤器。本身是进行的哈希运算,很难出现两套都冲突的情况。


九、分布式锁

1、特性

互斥性、超时释放、可重入性、高性能及高可用、安全性

2、基本实现

setnx + expire

先用setnx进行锁抢占,再用expire给锁设置一个过期时间

3、Redission

(1)定义

  • Redisson是Redis官方推荐的Java版的Redis客户端。
  • 基于Java实用工具包中常用接口,为使用者提供了一系列具有分布式特性的常用工具类。
  • 在网络通信上是基于NIO的Netty框架,保证网络通信的高性能。
  • 在分布式锁的功能上,它提供了一系列的分布式锁;如:
    • 可重入锁(Reentrant Lock)
    • 公平锁(Fair Lock)
    • 非公平锁(unFair Lock)
    • 读写锁(ReadWriteLock)
    • 联锁(MultiLock)
    • 红锁(RedLock)

(2)实现分布式锁

  • Redisson配置;
  • 代码:
    • @Autowired
      RedissonClient redissonClient;
      RLock lock = redissonClient.getLock(key);


十、常见问题

1、缓存穿透、击穿、雪崩

  • 缓存穿透:查找的数据既不在Redis,也不在DB
  • 解决:1)布隆过滤器;2)缓存空对象;
  • 缓存击穿:查找的数据不在Redis,但DB存在
  • 解决:1)预设热门数据,并实时监测变化调整;2)使用分布式锁;
  • 缓存雪崩:大量数据缓存过期失效,导致查DB。
  • 解决:1)设置失效时间随机数;2)对数据库增加过载保护或限流;3)考虑多级缓存。

【缓存清洗】

  • flushdb:清空当前数据库中的所有 key;
  • flushall:清空整个 Redis 服务器的数据(删除所有数据库的所有 key )

【并发竞争Key】

  • 乐观锁--Redis事务,watch指定keys;
  • 分布式锁;
  • 时间戳--类似数据库的乐观锁,判断处理的时间是否对的上;
  • 消息队列。

2、大 Key

大 key 并不是指 key 的值很大,而是 key 对应的 value 很大。

一般而言,下面这两种情况被称为大 key:

  • String 类型的值大于 10 KB;
  • Hash、List、Set、ZSet 类型的元素的个数超过 5000个;

(1)可能造成的问题

  • 客户端超时阻塞。Redis命令单线程处理,操作大key时,会比较好事,从而阻塞Redis。
  • 引发网络阻塞。每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
  • 阻塞工作线程。如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
  • 内存分布不均。集群模型在 slot 分片均匀情况下,会出现数据和查询倾斜情况,部分有大 key 的 Redis 节点占用内存多,QPS 也会比较大。

(2)查找大Key

方法1:“ridis-cli  --bigkeys”

注意事项:

  • 最好选择在从节点上执行该命令。因为主节点上执行时,会阻塞主节点;
  • 如果没有从节点,那么可以选择在 Redis 实例业务压力的低峰阶段进行扫描查询,以免影响到实例的正常运行;或者可以使用 -i 参数控制扫描间隔,避免长时间扫描降低 Redis 实例的性能。

不足:

  • 这个方法只能返回每种类型中最大的那个 bigkey,无法得到大小排在前 N 位的 bigkey;
  • 对于集合类型来说,这个方法只统计集合元素个数的多少,而不是实际占用的内存量。但是,一个集合中的元素个数多,并不一定占用的内存就多。因为,有可能每个元素占用的内存很小,这样的话,即使元素个数有很多,总内存开销也不大。

方法2:使用SCAN命令

使用 SCAN 命令对数据库扫描,然后用 TYPE 命令获取返回的每一个 key 的类型。

对于 String 类型,可以直接使用 STRLEN 命令获取字符串的长度,也就是占用的内存空间字节数。

对于集合类型来说,有两种方法可以获得它占用的内存大小:

  • 如果能够预先从业务层知道集合元素的平均大小,那么,可以使用下面的命令获取集合元素的个数,然后乘以集合元素的平均大小,这样就能获得集合占用的内存大小了。List 类型:LLEN​ 命令;Hash 类型:HLEN​ 命令;Set 类型:SCARD​ 命令;Sorted Set 类型:ZCARD 命令;
  • 如果不能提前知道写入集合的元素大小,可以使用MEMORY USAGE 命令(需要 Redis 4.0 及以上版本),查询一个键值对占用的内存空间。

方法3:使用RdbTools工具

使用 RdbTools 第三方开源工具,可以用来解析 Redis 快照(RDB)文件,找到其中的大 key。

比如,下面这条命令,将大于 10 kb 的  key  输出到一个表格文件。

“rdb dump.rdb -c memory --bytes 10240 -f redis.csv”

(3)删除方法

方式一:分批次删除

对于删除大 Hash,使用 hscan 命令,每次获取 100 个字段,再用 hdel 命令,每次删除 1 个字段。

对于删除大 List,通过 ltrim 命令,每次删除少量元素。

对于删除大 Set,使用 sscan 命令,每次扫描集合中 100 个元素,再用 srem 命令每次删除一个键。

对于删除大 ZSet,使用 zremrangebyrank 命令,每次删除 top 100个元素。

方式二:异步删除(4.0版本以上)

unlink 命令代替 del 来删除。

这样 Redis 会将这个 key 放入到一个异步线程中进行删除,这样不会阻塞主线程。


参考:

Redis过期策略及内存淘汰机制;

什么是可重入锁?详解redis实现分布式重入锁的方法;

Redis大key删除的相关问题;redis随手记-大key删除法;面试官:Redis 大 Key 要如何处理;

Redis删除大key引发的线上事故;

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

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

相关文章

vue高德地图使用

先根据官方方法给vue项目引入高德 高德文档地址 做好准备后使用 初始化地图 AMap.plugin(AMap.MoveAnimation, () >{//地图this.map new AMap.Map("mapContainer", {resizeEnable: true,center: [116.397447,39.909176],//地图中心坐标zoom:12,//缩放值});this.…

《NATURE丨使用 AlphaFold 3 准确预测生物分子相互作用的结构》

NATURE丨使用 AlphaFold 3 准确预测生物分子相互作用的结构 注意&#xff01;&#xff1a;本文创作仅根据个人理解和网络信息&#xff0c;如有错误恳请指正&#xff01;谢谢&#xff01; 大家好&#xff0c;今天分享的文献是2024年5月发表在Nature上的“ Accurate structure …

Qt/C++编写地图应用/离线地图下载/路径规划/轨迹回放/海量点/坐标转换

一、前言说明 这个地图组件写了很多年了&#xff0c;最初设计的比较粗糙&#xff0c;最开始只是为了满足项目需要&#xff0c;并没有考虑太多拓展性&#xff0c;比如最初都是按照百度地图写死在代码中&#xff0c;经过这几年大量的现场实际应用&#xff0c;以及大量的用户提出…

深度学习标注文件格式转换

json转xml 原始数据集文件夹中图片格式为bmp&#xff0c;标注文件为json&#xff0c;图片和标注文件放在同一个文件夹下面&#xff0c;将json转为xml格式&#xff0c;图片和标注文件分别存放在一个文件夹下面。 headstr """\ <annotation><folder>…

C语言 -- 函数

C语言 -- 函数 1. 函数的概念2. 库函数2.1 标准库和头文件2.2 库函数的使用方法2.2.1 功能2.2.2 头文件包含2.2.3 实践2.2.4 库函数文档的一般格式 3. 自定义函数3.1 函数的语法形式3.2 函数的举例 4. 形参和实参4.1 实参4.2 形参4.3 实参和形参的关系 5. return 语句6. 数组做…

页面加载503 Service Temporarily Unavailable异常

最近发现网页刷新经常503&#xff0c;加载卡主&#xff0c;刷新页面就正常了。 研究之后发现是页面需要的js文件等加载失败了。 再研究之后发现是nginx配置的问题。 我之前为了解决一个漏洞检测到目标主机可能存在缓慢的HTTP拒绝服务攻击 把nginx的连接设置了很多限制&#…

通过easyexcel导入数据,添加表格参数的校验,同表格内校验以及和已有数据的校验

引入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.11</version><scope>compile</scope></dependency> 需要导入到某个目录下 如果产品名称相同&#xff0c…

这玩意终于有免费的了———Navicat Premium Lite

免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 去下载吧&…

基于Teager-Kaiser能量算子的肌电信号降噪方法(MATLAB)

Teager-Kaiser能量算子是一种非线性算子&#xff0c;它能有效提取信号的瞬时能量&#xff0c;对信号瞬时变化具有良好的时间分辨率。Teager-Kaiser能量算子只需信号三个采样点&#xff0c;即可快速跟踪信号的幅值和角频率变化&#xff0c;计算实现简单、运算量小。 clc clear a…

【 香橙派 AIpro评测】大语言模型实战教程:香橙派 AIpro部署LLMS大模型实站(保姆级教学)

引言 OrangePi AIpro 这块板子作为业界首款基于昇腾深度研发的AI开发板&#xff0c;一经发布本博主就火速去关注了&#xff0c;其配备的 8/20TOPS澎湃算力是目前开发板市场中所具备的最大算力&#xff0c;可谓是让我非常眼馋啊&#xff01;这么好的板子那必须拿来用用&#xff…

WPF 3D绘图 点云 系列五

基本概念:点云是某个坐标系下的点的数据集。 可能包含丰富的信息,包括三维坐标X,Y,Z、颜色、分类值、强度值、时间等等 点云可以将现实世界原子化,通过高精度的点云数据可以还原现实世界。万物皆点云。 通过三维激光扫描仪进行数据采集获取点云数据,其次通过二维影像进行…

初次使用GitHub教程入门

注册一个github账户 访问地址&#xff1a;https://github.com/&#xff0c;点击右上角sign up&#xff0c;录入以下信息&#xff0c;邮箱&#xff0c;密码&#xff0c;账号&#xff0c;会有邮箱验证&#xff0c;跟着步骤来就好了 配置 本机上设置你的github的邮箱和用户名 …

R语言学习,入门

我是一名6年开发经验的程序员&#xff0c;后端&#xff0c;大数据&#xff0c;前端都会。 现在加入了医疗行业&#xff0c;要做数据分析&#xff0c;前同事的实验室生信专业的&#xff0c;用的是R语言&#xff0c;为了跑通他的程序。就来学一下吧&#xff0c;看了一下好像挺简…

农村生活污水处理监测系统解决方案

一、概述 随着国民经济的发展和农村生活水平的提高&#xff0c;农村生活用水量越来越大&#xff0c;随之而来的污水产量也越来越大&#xff0c;农村生活污染对环境的压力越来越明显。环境保护意识的逐渐增强&#xff0c;使得人们对青山绿水的希望更为迫切&#xff0c;为满足人民…

Nordic 52832作为HID 键盘连接配对电视/投影后控制没反应问题的分析和解决

问题现象&#xff1a;我们的一款HID键盘硬件一直都工作的很好&#xff0c;连接配对后使用起来和原装键盘效果差不多&#xff0c;但是后面陆续有用户反馈家里的电视等蓝牙设备配对连接我们的键盘后&#xff0c;虽然显示已连接&#xff0c;但实际上控制不了。设备涉及到了好些品牌…

【操作与配置】VSCode配置Python及Jupyter

Python环境配置 可以参见&#xff1a;【操作与配置】Python&#xff1a;CondaPycharm_pycharmconda-CSDN博客 官网下载Python&#xff1a;http://www.python.org/download/官网下载Conda&#xff1a;Miniconda — Anaconda documentation VSCode插件安装 插件安装后需重启V…

layui-表格

1.使用方法 加上table标签 加上classlayui-table colgroup是列属性 tr是行td是列 thead是表头&#xff0c;后面一一对应 2.基础属性 加lay-even逐行换色 加lay-skin 设置边框风格

竞赛 深度学习+opencv+python实现昆虫识别 -图像识别 昆虫识别

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数&#xff1a;2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 4 MobileNetV2网络5 损失函数softmax 交叉熵5.1 softmax函数5.2 交叉熵损失函数 6 优化器SGD7 学…

企业多存储方式如何兼顾安全统一管理、便捷流畅访问的双向需求?

数据和文件存储是企业最基础的需求&#xff0c;常见的存储方式有磁盘存储、NAS存储、SAN存储、云存储、分布式存储、闪存存储等&#xff1b;随着企业规模的扩大、业务结构的复杂化&#xff0c;企业内部可能会同时出现多种存储方式、多个存储设备并行使用的情况。 这样的使用场景…

Ubuntu24.04(22.04+版本通用)Miniconda与Isaacgym

1. ubuntu24.04安装minicondda mkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh解释下这段代码 bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3~/miniconda3/miniconda.sh: 指向Mi…