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元素组成的字典,适合存放对象
    Redis超级详解(附带实操教学)_第1张图片
  • List:列表,按照String元素插入序列排序
    Redis超级详解(附带实操教学)_第2张图片
  • Set:String元素组成的无序集合,通过哈希表实现,不允许重复
    Redis超级详解(附带实操教学)_第3张图片
  • Sorted Set 不可重复,但是可以排序
    Redis超级详解(附带实操教学)_第4张图片
  • HyperLogLog用于计数
  • Geo用来存储地理位置信息

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

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

keys命令可能带来的隐患

大数据量下会阻塞,2000W数据,卡住执行80s+
Redis超级详解(附带实操教学)_第5张图片

SCAN 指令

Redis超级详解(附带实操教学)_第6张图片
还是刚才的场景,我们用scan指令查询
Redis超级详解(附带实操教学)_第7张图片这样查询不会阻塞,但是可能会出现重复的情况,我们可能需要在应用程序中进行去重

如何通过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

Redis超级详解(附带实操教学)_第8张图片如果pop返回nil,那就说明消费完了,我们程序调用可能需要在此时进行一个延时操作(sleep一会儿再访问)

BLPOP

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

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

pub\sub主题订阅者模式

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

Redis超级详解(附带实操教学)_第9张图片缺点是
消息发布无状态,无法保证到达

Redis如何持久化

RDB持久化策略

在redis.conf文件中,这些是根据不同情况做的不同策略
Redis超级详解(附带实操教学)_第10张图片当备份进程出错,停止写入操作,保护数据
在这里插入图片描述

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

Redis超级详解(附带实操教学)_第11张图片

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

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

Copy-on-Write

Redis超级详解(附带实操教学)_第12张图片当Redis需要备份时,系统fork()创建一个子进程,父进程继续处理客户端的操作,当执行写入时,系统创建一个副本给父进程,子线程备份完毕后,父进程将副本覆盖当前资源

RDB缺点

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

AOF持久化

AOF(Append-Only-File)持久化,保存写命令
Redis超级详解(附带实操教学)_第13张图片默认不开启,需要conf文件配置,开启后需要重启
可以执行config set appendonly yes开启增量备份

日志文件过大如何处理

Redis超级详解(附带实操教学)_第14张图片

RDB于AOF优缺点

Redis超级详解(附带实操教学)_第15张图片可以使用RDB-AOF混合持久化方式,4.0版本以后默认此方式
BGSAVE做镜像全量持久化,AOF做增量持久化

Pipeline的好处

Redis超级详解(附带实操教学)_第16张图片

Redis同步机制

主从同步原理

Redis超级详解(附带实操教学)_第17张图片
只有主节点做写操作,从节点只做读操作

全同步过程

Redis超级详解(附带实操教学)_第18张图片

增量同步过程

Redis超级详解(附带实操教学)_第19张图片

Redis Sentinel

解决主从同步Master宕机后主从切换
Redis超级详解(附带实操教学)_第20张图片

流言协议Gossip

在杂乱无章种寻求一致
Redis超级详解(附带实操教学)_第21张图片

Redis的集群

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

Redis超级详解(附带实操教学)_第25张图片移除节点后的影响范围在该节点逆时针计算到遇到的第一个cache节点之间的数据节点。
Redis超级详解(附带实操教学)_第26张图片

你可能感兴趣的:(Redis)