Redis超级详解(附带实操教学)

Memcache与Redis的区别

首先我们得知道为啥要用Redis

Memcache

  • 支持简单数据类型
  • 不支持数据持久化存储
  • 不支持主从
  • 不支持分片

Redis

  • 数据类型丰富
  • 支持磁盘持久化
  • 支持主从
  • 支持分片

为什么Redis能这么快

官方给出的是支持10W+QPS(QPS-query per second ,每秒查询次数)

  • 完全基于内存,绝大部分请求是纯粹的 内存操作,执行效率高
  • 数据结构简单,对数据操作简单
  • 采用单线程,单线程可以处理高并发请求,多核启动多实例
  • 使用多路IO复用模型,并非阻塞IO

多路I\O复用模型

首先知道一个概念
FD:File Descriptor文件描述符

一个打开的文件通过唯一的描述符进行引用,描述符石打开文件的元数据到文件本身的映射

Redis使用的是多路复用IO模型,防止阻塞影响性能

将监控文件是否可读,交给selector,那么线程就可以做点别的事情去了

根据不同的系统,使用不同的多路复用函数,因为所有的系统都会支持select,所以在Redis发现本系统没有更好的可用时会用select

IO多路复用函数:epoll/kqueue/evport/select

  • 因地制宜
  • 优先选择时间复杂度O(1)的作为底层实现
  • 以时间复杂度位O(n)的select作为保底(所有操作系统都实现此函数)
  • 给予react设计模式监听I/O事件

Redis数据类型

  • String:最基本的数据类型,二进制安全
  • Hash:String元素组成的字典,适合存放对象
    在这里插入图片描述
  • List:列表,按照String元素插入序列排序
    在这里插入图片描述
  • Set:String元素组成的无序集合,通过哈希表实现,不允许重复
    在这里插入图片描述
  • Sorted Set 不可重复,但是可以排序
    在这里插入图片描述
  • HyperLogLog用于计数
  • Geo用来存储地理位置信息

从海量key查询出某一固定前缀的key

首先我们要知道数据量到底有多大,再决定使用什么方式查询

keys命令可能带来的隐患

大数据量下会阻塞,2000W数据,卡住执行80s+
在这里插入图片描述

SCAN 指令

在这里插入图片描述
还是刚才的场景,我们用scan指令查询
在这里插入图片描述这样查询不会阻塞,但是可能会出现重复的情况,我们可能需要在应用程序中进行去重

如何通过Redis实现分布式锁

分布式锁需要解决的问题:

  • 互斥性
  • 安全性
  • 死锁
  • 容错

解决方案(SETNX):

SETNX key value :如果key不存在,那么创建并返回
####应用原理
一个线程占用资源时,先SETNX一个值,在执行结束后将值删除
在此期间,别的线程使用相同资源时,先SETNX同样的key,设置无效则证明资源没被释放

如何解决SETNX长期有效的问题

EXPIRE key seconds
如果使用资源长期不被释放,那么资源就会一直被占用,我们可以通过设置key过期时间
例如:我们在程序中可以如下设计

long status = redisService.setnx(key,"1");
if(status == 1){
	redisService.expire(key,expire);
	// 处理单独占用资源的逻辑
}
设计缺陷

原子性得不到满足,如上设计方案执行SETNX后挂了,那么过期时间还是没设置啊,这不还是完蛋?

解决方案(SET key+参数)

使用方式

SET key value [EX seconds] [PX milliseconds ] [NX|XX]

  • EX second:设置键的过期时间为second秒
  • PX millisecond:设置键的过期时间为millisecond
  • NX:当前无,则插入
  • XX:当前有,才插入

SET操作成功返回OK,否则返回nil

具体实现

使用以下可以保证原子性

long result = redisService.set(key,requestId,SET_IF_NOT_EXIST,SET_WITH_EXPIRE_TIME,EXPIRETIME);
if(result == "OK"){
	// 处理单独占用资源的逻辑
}

大量key同时过期,造成卡顿

设置过期时间时,会随机增加毫秒数,防止同一时间过期

如何使用Redis做异步队列

使用List进行一个入栈,出栈操作,请忽略中间两步弟弟操作。。

POP

在这里插入图片描述如果pop返回nil,那就说明消费完了,我们程序调用可能需要在此时进行一个延时操作(sleep一会儿再访问)

BLPOP

sleep的方式,总感觉会被面试官锤!!!那么BLPOP闪亮登场
BLPOP key timeout:阻塞至队列有消息或超时
缺点:只能提供给一个消费者

那肯定不得劲~还得升级!

pub\sub主题订阅者模式

发送者pub发送消息,订阅者可以关注任意数量的频道

在这里插入图片描述缺点是
消息发布无状态,无法保证到达

Redis如何持久化

RDB持久化策略

在redis.conf文件中,这些是根据不同情况做的不同策略
在这里插入图片描述当备份进程出错,停止写入操作,保护数据
在这里插入图片描述

自动化触发RDB持久化的方式

在这里插入图片描述

保存备份有两种模式,save和bgsave

  • save会阻塞当前服务,直到备份完毕
  • bgsave会创建一个子线程备份,不会阻塞当前备份,轮训访问备份是否完毕
Copy-on-Write

在这里插入图片描述当Redis需要备份时,系统fork()创建一个子进程,父进程继续处理客户端的操作,当执行写入时,系统创建一个副本给父进程,子线程备份完毕后,父进程将副本覆盖当前资源

RDB缺点
  • 内存数据的全量同步,数据量大由于IO而严重影响性能
  • 可能因为Redis挂掉而丢失当前至最近一次快照期间的数据

AOF持久化

AOF(Append-Only-File)持久化,保存写命令
在这里插入图片描述默认不开启,需要conf文件配置,开启后需要重启
可以执行config set appendonly yes开启增量备份

日志文件过大如何处理

在这里插入图片描述

RDB于AOF优缺点

在这里插入图片描述可以使用RDB-AOF混合持久化方式,4.0版本以后默认此方式
BGSAVE做镜像全量持久化,AOF做增量持久化

Pipeline的好处

在这里插入图片描述

Redis同步机制

主从同步原理

在这里插入图片描述
只有主节点做写操作,从节点只做读操作

全同步过程

在这里插入图片描述

增量同步过程

在这里插入图片描述

Redis Sentinel

解决主从同步Master宕机后主从切换
在这里插入图片描述

流言协议Gossip

在杂乱无章种寻求一致
在这里插入图片描述

Redis的集群

现在假设有4个对象:object1-object4,将四个对象hash后映射到环形空间中:
在这里插入图片描述一个cache就是一个redis节点哈
接下来把chche映射到hash空间(基本思想就是讲对象和cache都映射到同一hash数值空间中,并且使用相同的hash算法,可以使用cache的ip地址或者其他因子),假设现在有三个cache:
在这里插入图片描述
每个key顺时针往下走,找到的第一个cache节点就是存储位置:
在这里插入图片描述现在移除一个cacheB节点、这时候key4将找不到cache,key4继续使用一致性hash算法运算后算出最新的cacheC,以后存储与读取都将在cacheC上:

在这里插入图片描述移除节点后的影响范围在该节点逆时针计算到遇到的第一个cache节点之间的数据节点。
在这里插入图片描述

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值