redis简单总结

redis简述

redis是一个高性能的key-value内存数据库,一般用来缓存,还可以用作消息中间件。读写速度快,支持10W QPS
redis单进程单线程,线程安全。

redis为什么这么快

  • 直接操作内存
  • 数据结构简单
  • 单线程,避免了上下文切换

五种数据类型

  • string: 存字符串或数字,最大512m
  • hash: 一般用来存对象,常用的命令有hget、hset等
  • list: 是个双向链表,支持反向查找和遍历。可以用于消息队列
  • set: 无序集合,自动去重
  • sorted-set: 相对于set多了一个score(double类型)参数来表示优先级,用来排序

缓存

缓存穿透

请求缓存和数据库中都不存在的数据,就叫缓存穿透。如果有大量这样的请求,会造成每次都去查数据库,导致宕机。
解决办法

  1. 接口校验数据。比如id不能小于1
  2. 可以将请求的key缓存起来,值设置为null,并设置过期时间来避免
  3. 布隆过滤器(bloomFilter)

缓存击穿

高并发请求一个数据的时候缓存失效了,大量请求都去查数据库
解决办法

  1. 若未拿到缓存,后面从数据库查询的代码加互斥锁,抢到锁的线程查询数据库并缓存,未抢到锁的线程递归该方法
  2. 双缓存。一级缓存失效后,多个线程竞争锁,抢到锁的线程去查询数据库,并更新一二级缓存,未抢到锁的直接访问二级缓存(二级缓存设置失效时间比一级缓存长)

缓存雪崩

负责缓存的服务器宕机了或大量缓存数据失效时间一样,导致很多缓存同一时间失效,大量请求直接请求DB,DB挂掉
解决办法

  1. 使用集群
  2. hystrix限流

淘汰策略

redis配置的内存被用完后新增数据的处理策略

  1. noeviction(默认): 直接报错,不淘汰数据
  2. allkeys-lru: 为所有key使用LRU算法淘汰
  3. volatile-lru: 为设置了过期时间的key使用LRU算法淘汰
  4. allkeys-random: 所有key随机淘汰
  5. volatile-random: 设置过期时间的key进行随机淘汰
  6. volatile-ttl: 淘汰最早过期的key
    redis4.0新增的
  7. volatile-lfu: 有过期时间的key淘汰使用频率最少的
  8. allkeys-lfu: 所有key淘汰使用频率最少的

LRU算法: 找到到最近最少使用的数据,大概思路,维护一个链表,新插入的数据放到头部,访问过的数据放到头部,满时删除尾部的
修改策略: 通过配置 maxmemory-policy,linux系统中用命令或在redis配置文件中配置

持久化

下面配置的例子不用特别关注(配置文件的注释说明非常清楚,建议亲自去看看),用到的时候再了解也不晚

RDB

N秒内N次写操作后,将redis数据以rdb文件的形式一次性保存到硬盘内。
具体的时间和次数可以在配置文件内配置
这种方式有个缺点,两个保存点之间断电,中间的数据会丢失
主要的配置内容:

# 900秒内如有有1次写操作,就生成一次rdb文件,以此类推。多个配置来保证数据平衡
save 900 1
save 300 10
save 60 10000

# 持久化出错后主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩 这个感觉没必要开,因为压缩肯定会占CPU
rdbcompression yes

# 导入时是否检查
rdbchecksum yes

# rdb文件名称
dbfilename dump.rdb

# 文件路径
dir ./

AOF

把redis的每次操作都记录下来,重启redis后执行所有记录的命令。
AOF是默认关闭的,若开启AOF,优先使用AOF的方式来恢复数据。但是RDB更快,因为是内存映射
主要的配置内容:

# 开关
appendonly no

# 名称
appendfilename "appendonly.aof"

# 同步方式,默认everysec。
# always 每个命令都立即同步,安全但是很慢
# everysec 每秒同步一次
# no 交给操作系统处理
appendfsync everysec

# aof重写期间(导出新的aof快照的时候)是否同步
no-appendfsync-on-rewrite no

# 重写触发配置。aof文件比上次重写增长了100%时重写。aof文件超过64m时重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载aof时如果有错如何处理。yes: 写入时发现错误会向客户端写一个log,继续执行。 no: 发现错误会停止,修复后才能加载
aof-load-truncated yes

# 文件重写策略
aof-rewrite-incremental-fsync yes

aof重写简单理解就是重新把内存中的数据逆化成命令,生成一个更小的aof文件替换旧文件,避免aof文件过大

事务

redis事务某条指令执行失败后,执行过的指令不能回滚。redis事务启用的是乐观锁
multi: 开启事务
exec: 执行事务(执行multi和exec中间的所有命令)
discard: 取消事务
watch: 所监控的键如果值被其他线程改变,则取消事务(乐观锁就是用watch实现的)

发布/订阅

发布者通过channel发布消息,订阅者订阅channel接收消息。缺点是断电期间的消息会丢失。适用于任务通知,普通的即时聊天等简单的场景
redis-cli相关指令

# 发布端
publish 频道名称 发布内容
# 订阅端
subscribe 频道名称
psubscribe 频道名称前缀*

springboot+redis实现发布订阅的例子网上有很多

主从复制

主节点(master)出现问题,从节点(slave)提供服务。可以做读写分离,在主服务器写,在从服务器读,提高并发量。同时主从复制也是实施哨兵集群的基础。
配置内容比较简单,只需要配置从服务

# 配置主服务器的ip和端口(这项配置默认是关闭的,开启后就代表该服务是从服务)
slaveof  
# 从服务只读
slave-read-only yes

一主可配多从
注:多台从服务器不要一下子都启动,否则可能造成主服务IO剧增

集群

  • 一个redis集群包含16384个哈希槽(hash slot),根据key使用CRC16算法(CRC16(key)%16384)来计算key属于那个哈希槽。
  • 集群中的每个节点服务一段slot(一般来说是均等的,并且redis建议最多1000个节点),根据slot找到节点来操作数据。
  • 集群中任意两个节点都是连通的,连接任意节点都可以通过slot转到对应的节点操作具体的key。
  • 当增加一个新节点到集群中时,已存在节点的某些槽会移动到新节点中。删除节点时,删除节点的槽会移动到其他节点。
  • 一般来说,集群中最少有3个主服务,3个从服务。每个节点都存有这个集群所有主节点和从节点的信息(配置文件cluster-config-file项)。
  • 节点之间互相ping-pong,如果一半以上节点ping某个节点时都没回应,则集群认为这个节点宕机了,它的从节点就会被设置为主节点。如果从节点全部挂了,那集群就会停止
  • 集群中超过一般的主节点宕机,集群也会停止

注:

  • springboot使用lettuce做redis集群连接需要手动开启自适应拓扑刷新

哨兵

哨兵(sentinel)的主要作用是解决主节点故障恢复的自动化问题,提高系统可用性。

  • 哨兵至少要有3个节点来保证自己的健壮性
  • 每个哨兵节点会以每秒一次的频率对redis其他节点和其他哨兵节点发送ping命令,通过回复来判断是否在线。
  • 配置文件 down-after-milliseconds 配置的毫秒时间内,如果哨兵没有收到目标主节点的回复,则判定该节点主观下线,并向其他哨兵节点询问对该节点的状态判断,如果有超过配置 quorum 数量的哨兵认定主节点不可达,则该主节点被断定为客观下线,也就是挂了
  • 哨兵监控到某个主节点挂了后,会将其中一个从节点升级为主节点,并将其他从节点设置为该节点的从节点
  • 哨兵部分节点挂了的话,整个哨兵集群依然能够继续工作

你可能感兴趣的:(中间件,redis)