Java-Redis(javaredis判断key是否存在)
wptr33 2025-02-03 15:29 19 浏览
1.简单介绍一下Redis
Redis是一个使用C语言开发的数据库,不过与传统的数据库不同的是Reids的数据库是存在内存中的,也就是它是内存数据库,所以读写速度非常快,因此Redis被广泛应用于缓存方向。
Redis除了做缓存之外,Redis也经常用来做分布式锁,甚至是消息队列。
Redis提供了多种数据类型来支持不同的业务场景。Redis还支持事务、持久化、Lua脚本、多种集群方案。
优点:
读写性能极高
支持数据持久化
支持事务
数据结构丰富
支持主从复制
丰富的特性
缺点:
数据库容量收到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
2.缓存数据的处理流程
如果用户请求的数据在缓存中就直接返回
缓存中不存在的话就看数据中是否存在
数据库中不存在的话就更新缓存中的数据
数据库中不存在的话就返回空数据。
3.Rsdis常见的数据库
A.字符串类型 String
String数据结构是简单的key-value类型,可以存储任何类型的数据,包括二进制数据,序列化后的数据,JSON化后的数据,甚至是一张图片。最大为512M
常用命令:set、get、strlen、exists、dect、incr、setex
应用场景:计数器:记录播放量,记录访问数(Redis记总数,MySQL记录日志)、登录验证码
B.列表类型 list
是简单的字符串列表,按照插入顺序排序,元素可以重复。可以添加一个元素到列表的头部或者尾部,底层是个链表结构。实现的是双向链表,既可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。
常用命令:rpush、lpop、lpush、rpop、lrange、llen
应用场景:消息队列,慢查询。
C. 集合类型 set
是String类型的无序无重复集合
常用命令:sadd、spop、smembers、scard
应用场景:需要存放的数据不能重复,以及需要获取多个数据源交集和并集等场景
D. 哈希类型hash
hash是一个string类型的field和value的映射表,hash特别适合于存储对象
常用命令:hset、hget、hgetall
应用场景:系统中对象的存储
E. 有序集合类型zset(sorted set)
有序集合zset和set集合一样也是string类型元素的集合,且不允许重复的成员。不同的是zset每个元素都会关联一个分数(分数可以重复),redis通过分数来为集合中的成员进行从小到大的排序。
常用命令:zadd、zscore、zcard、zrange
应用场景:需要对数据根据某个权重进行排序的场景。
4.Redis单线程模型
redis中的文件事件处理器,文件事件处理器是单线程模式运行的。
文件事件处理器的四个部分:
多个socket(客户端连接)
IO多路复用程序(支持多个客户端连接的关键)
文件事件分派器(将socket关联到相应的事件处理器)
事件处理器(连接 应答处理器、命令请求处理器、命令恢复处理器)
单线程为什么执行那么快
纯内存操作
避免了不必要的上下文切换
避免了多线程之间的竞争和切换而消耗CPU,避免了各种锁操作
采用了非阻塞I/O多路复用技术:这个技术让redis不需要额外创建多余的线程来监听客户端的大量连接,降低了资源消耗。
5. Redis6.0之前,为什么不使用多线程
单线程编程容易并且更容易维护
Redis的性能瓶颈不在CPU,主要在内存和网络;
多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能
6.0后为何引入了多线程?
Redis引入多线程主要是为了提高IO读写性能,这个也算是Redis中的一个性能瓶颈。
Redis6.0多线程的实现机制?
主线程负责接收建立连接请求,获取socket放入全局等待读处理队列
主线程处理完读事件后,通过RR(Round Robin)将这些连接分配给这些IO线程。
主线程阻塞等待IO线程读取socket完毕
主线程通过单线程的方式执行请求命令,请求数据读取并解析完成,但并不执行
主线程阻塞等待IO线程将数据回写Socket完毕。
6.缓存
6.1缓存淘汰
先进先出(FIFO)
近期较少使用(LFU)
最长时间未被使用哪个(LRU)
6.2 key过期删除策略
惰性删除:当使用的时候,如果过期就删除,如果没过期就使用
定时删除:key过期后设置一个定时器
定期删除:一段时间对key进行随机检查,删除。控制删除的时长和频率。
6.3 缓存穿透
当获取一个数据但是缓存中没有,数据库中也没有,多次查询使数据库宕机
解决方案;
布隆过滤器:将mysql中的key加入布隆过滤器,查询之前,查看数据库是否有这个key
在redis存在不存在的key设置value为null
6.4 缓存击穿
当获取一个数据但是缓存中没有(过期时间到,宕机),数据库中有,多次查询使数据库宕机
解决:redis集群。redis数据库中,添加缓存层或限流
6.5 缓存雪崩
同一时刻,大量缓存失效,直接请求数据库
解决:
设置不同失效时间
双层缓存
定期更新
增加过期标志
6.6 缓存阻塞
数据结构不合理
CPU饱和
持久化阻塞
6.7 热点key缓存倾斜
使用本地缓存
利用分片算法,对key加前缀,把一个热点key分散成多个key
7. 持久化
Redis的一种持久化方式叫快照(snapshotting RDB),另一种方式只追加文件(append-only file AOF).
快照持久化(RDB):定期的全盘缓存
在指定的时间间隔内将内存中的数据集快照写入磁盘,它恢复时是将快照文件直接读到内存里。
优势:适合大规模的数据恢复;对数据完整性和一致性要求不高
劣势:在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。
AOF持久化:日志文件; 触发机制,每次记录
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以写文件,Redis启动之初会读取该文件重新构建数据。
避免文件越来越大,新增了重写机制,当AOF文件的大小超过所设定的阈值的时候,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
优势:同步持久化;每秒同步;不同步
劣势:相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb
aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同
两者的比较:
AOF文件比RDB更新效率高
优先使用AOF
AOF更安全
RDB比AOF性能好
7.1Redis持久化数据和缓存怎么做扩容?
如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩写。
如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化,否则的话必须使用可以在运行时进行数据再平衡一套系统
8.Redis事务
Redis可以通过MULTI . EXEC , DISCARD, WATCH等命令来实现事务(transcation)功能
Multi开启事务
Exec执行事务代码块
Discard取消事务
Watch监制一个或多个key,如果事务执行前key被改动,事务将打断
8.1 redis事务的实现特征
所有的命令都将被串行化的顺序执行,事务执行期间,Redis不会再为其他客户提供要求
Redis事务中如果有一条命令执行失败,之后的命令仍然会继续执行
在事务开始之前,如果客户端和服务器之间出现通信故障并导致网络断开,之后的所有待执行语句都不会执行。如果exec之后网络中断后,事务中的所有命令都会被服务器执行。
当使用Append-Only模式的时候,Redis通常会调用write全部写入磁盘。当写入断电的时候,会发生数据不一致的信息,使用redis-check-aof对数据进行回滚
9.Redis集群
官方cluster集群3主3从
客户端只需要连接其中的任何一个节点
使用哈希槽(hash slot) 的方式来分配16384个slot,当新节点加入,取各个槽的前部门分给新节点。
9.1 容错性
投票:集群中所有的master节点投票,半数以上的master挂掉集群不可用
节点分配:新增节点时,从每个节点的前半部分分配给新的节点
9.2 主从复制
从机连通会给主机发送sync指令
主机进行存盘操作,发送RDB文件给从机
从机收到后,进行全盘加载
每次主机写操作,都会立刻发送给从机,从机执行相同的命令
9.3 性能优化
主机不进行持久化,从机AOF备份数据
主从位于同一局域网
避免在压力大的主库上增加从库
使用链式结构增加从机
9.3 集群不可用
主机挂掉,当前主机没有从机
半数以上的主机挂掉。
分布式问题
10.什么是分布式锁?为什么用分布式锁?
锁在程序中的作用就是同步工具,保证共享资源在同一时刻只能被一个线程访问,Java中的锁我们很熟悉,像synchronized、lock都是常见的,但是Java的锁只能保证单机的时候有效,分布式集群环境就无能无力了,这个时候我们就需要用到分布式锁。
分布式锁,就是分布式项目开发中用到的锁,可以用来控制分布式系统之间同步访问共享资源
需要满足的特点:
互斥性:在任何时刻,对于同一数据,只有一台应用可以获取到分布式锁
高可用性:在分布式场景下,一小部分服务器宕机不影响正常使用,这种情况就需要将提供分布式锁的服务以集群的方式部署
防止锁超时:如果客户端没有主动释放锁,服务器会在一段时间之后自动释放锁,防止客户端宕机或者网络不可达时产生死锁
独占性:加锁解锁必须由同一台服务器进行,也就是锁的持有者才可以释放锁。
11.常见的分布式锁有哪些解决方案?
三种解决方案:关系型数据库、Redis、ZooKeeper
12.Redis实现分布式锁
分布式锁的三大核心要素:加锁、解锁、锁超时
13.了解RedLock吗?
Redlock是一种算法,Redlock也就是Redis Distributed Lock,可以实现多节点的分布式锁
这种方法的特性:
互斥访问:即永远只有一个client能拿到锁
避免死锁:最终client都可能拿到锁,不会出现死锁的情况,即使锁定资源的服务崩溃或者分区,仍然能释放锁
容错性:只要大部分Redis节点存活(一半以上),就可以正常提供服务。
14.Redis如何做内存优化?
控制key的数量:当时用Redis存储大量数据的时候,通常会存在大量键,过多的键同样会消耗大量内存。
缩减键值对象:降低Redis内存使用最直接的方式就是缩减key和value的长度
编码优化:Redis对外提供了string,list,hash,zet,set等类型,但是Redis内部针对不同类型存在编码的概念,所谓编码就是具体使用哪种底层数据结果来实现。编码不同将直接影响数据的内存占用和读写效率
15.如果现在有个读超高并发的系统,用Redis来抗住大部分读请求,你会怎么设计?
如果是读高并发的话,先看并发的数量级是多少,因为Redis单机的读QPS在万级,每秒几万没问题,使用一主多从+哨兵集群的缓存架构来承载每秒10W的读并发,主从复制,读写分离,
使用哨兵集群主要是提高缓存架构的可用性,解决单点故障问题。主库负责写,多个从库负责读,支持水平扩容,根据读请求的QPS来决定加多少个Redis从实例。如果读并发继续增加的话,只需要增加Redis实例就行了。
如果需要缓存1T+的数据,选择Redis cluster模式,每个主节点存一部分数据,假设一个master存32G,那只需要n*32G>=1T,n个这样的master节点就可以支持1T+的海量数据的存储。
相关推荐
- Linux文件系统操作常用命令(linux文件内容操作命令)
-
在Linux系统中,有一些常用的文件系统操作命令,以下是这些命令的介绍和作用:#切换目录,其中./代表当前目录,../代表上一级目录cd#查看当前目录里的文件和文件夹ls#...
- 别小看tail 命令,它难倒了技术总监
-
我把自己以往的文章汇总成为了Github,欢迎各位大佬star...
- lnav:基于 Linux 的高级控制台日志文件查看器
-
lnav是一款开源的控制台日志文件查看器,专为Linux和Unix-like系统设计。它通过自动检测日志文件的格式,提取时间戳、日志级别等关键信息,并将多个日志文件的内容按时间顺序合并显示,...
- 声明式与命令式代码(声明模式和命令模式)
-
编程范式中的术语和差异信不信由你,你可能已经以开发人员的身份使用了多种编程范例。因为没有什么比用编程理论招待朋友更有趣的了,所以这篇文章可以帮助您认识代码中的流行范例。命令式编程命令式编程是我们从As...
- linux中的常用命令(linux常用命令和作用)
-
linux中的常用命令linux中的命令统称shell命令shell是一个命令行解释器,将用户命令解析为操作系统所能理解的指令,实现用户与操作系统的交互shell终端:我们平时输入命令,执行程序的那个...
- 提高工作效率的--Linux常用命令,能够决解95%以上的问题
-
点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf...
- 如何限制他人操作自己的电脑?(如何控制别人的电脑不让发现)
-
这段时间,小猪罗志祥正处于风口浪尖,具体是为啥?还不知道的小伙伴赶紧去补一下最近的娱乐圈八卦~简单来说,就是我们的小罗同事,以自己超强的体力,以及超强的时间管理能力,重新定义了「多人运动」的含义,重新...
- 最通俗易懂的命令模式讲解(命令模式百科)
-
我们先不讲什么是命令模式,先通过一个场景来引出命令模式,看看命令模式能解决什么样的问题。现在有一个渣男张三,他有还几个女朋友,你现在是不是还是单身狗,你就说你气不气?然后他需要每天分别叫几个女朋友起床...
- 互联网大厂后端必看!Spring Boot 中Runtime执行与停止命令?
-
你是否曾在使用SpringBoot开发项目时,遇到需要执行系统命令的场景?比如调用脚本进行文件处理,又或是启动外部程序?很多后端开发人员会使用Processexec=Runtime.get...
- Linux 常用命令(linux常用的20个命令面试)
-
日志排查类操作命令...
- Java字节码指令:if_icmpgt(0xA3)(java字节码使用的汇编语言)
-
if_icmpgt是Java字节码中的一条条件跳转指令,其全称是"IfIntegerCompareGreaterThan"。它用于比较两个整数值的大小。如果栈顶的第一个...
- 外贸干货|如何增加领英的曝光量和询盘
-
#跨境电商#...
- golang执行linux命令(golang调用shell脚本)
-
需求需要通过openssl生成rsa秘钥,然后保存该秘钥。代码实例packagemainimport("io/ioutil""bytes"&...
- LINUX磁盘挂载(linux磁盘挂载到windows)
-
1、使用root用户查看磁盘挂载情况:fdisk-l2、使用df查看当前磁盘挂载情况,根据和fdisk-l的结果进行对比,查看还有那些磁盘未使用3、挂载:mount磁盘挂载路径...
- Linux命令学习——nl命令(linux ln命令的使用)
-
nl命令主要功能为每一个文件添加行号,每一个输入的文件添加行号后发送到标准输出。当没有文件或文件为-时,读取标准输入...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)