redis 学习日志 7.14

Nosql
NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,特别是大数据应用难题。

历史数据访问结构
APP->DAL->Mysql

由于数据量太大,并且需要建立索引,还要承担读写操作

衍生Memcaced(缓存层)+Mysql+读写分离
缓存:当读数据的时候会放到缓存区,之后有人访问会直接访问缓存减少了读的操作
读写分离:主机负责写操作,从机只负责读操作,降低io压力

分库分表+水平拆分+mysql集群
分库分表:数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,性能同样会下降,缓解读写的压力
水平拆分:由于数据量大划分到不同的数据库,避免记录过多问题而导致查询时间长
垂直拆分:避免数据冗余,避免表过多或者字段过多臃肿问题,拆出不常用的列,降低复杂性

表锁:当写数据的时候会锁定整个表,这在高并发下会影响效率
行锁:当写数据的时候会锁定一行

当需求越来越大的时候,数据量大并且需要快速的读写,并且各种数据格式的出现

用户->防火墙->负载均衡主从机->多台服务器->数据库群集

缓存 移动信息服务器 hadoop集群 实时通信服务器 流媒体服务器 图片服务器 文件服务器 群发服务器

CDN内容分发网络 具有分流、缓存、跨地域等特点,当用户请求过资源则会保存在CDN节点没过期的情况下再次访问可以直接获取资源,当资源过期则重新请求服务器同步更新获取资源

关系型数据库 RDBMS 例如mysql
非关系型数据库 Nosql 例如redis

传统的RDBMS
-结构化组织
-SQL
-数据和关系都存在单独的表中
-操作数据定义语言
-严格一致性
-基础的事务

Nosql
-没有固定查询语言
-多种数据格式
-键值对存储,列存储,文档存储,图形存储
-最终一致性,
-CAP定理和BASE(异地多活)
-高可用,高性能,可拓展

大数据5V:大量,多样,实时,价值(信息),质量(信息的准确)

NOSQL+RDBMS
关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库,让NoSQL数据库对关系型数据库的不足进行弥补。

非关系型数据库的优势:
1)性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
2)可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

关系型数据库的优势:
1)复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
2)事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。
nosql可以备份关系型数据库数据

行式数据库 每一行都是多种属性,一行一行查出相关属性或者不必要属性,如果数据量大建立索引需要大量时间和资源
列式数据库 每一列都是同一属性,一列直接查询对应属性,不需要建立额外索引,但如果查询所有字段则要全部查询然后拼接起来

mysql 端口号默认为3306
redis 端口号默认为6379

1.商品基本信息
名称价格商家信息
mysql
2.商品描述评论
文档型数据库,MongoDB
3.图片
分布式文件系统 FastDFS
-淘宝自己的 TFS
-Gooale的 GFS
-Hadoop HDFS
-阿里云的 oss
4.商品的关键字(搜索)
搜索引擎 solr elasticsearch lucense
-淘宝 ISERACH

5.商品热门波段信息
-内存数据库
-redis tair、memache
6.商品的交易、外部交易支付接口
-三方应用
数据类型太多了
数据源多,经常重构
————————————
KV键值对:
-redis
redis+tair
Redis+memecache
内容缓存,处理大量数据的高访问负载,也用于一些日志系统
文档型数据库(bson和json)
-mongoDB 基于分布式文件存储的数据库,C++编写,处理大量文档
-MongoDb是一个关系型和非关系型数据中的中间产品,是非关系型数据库中功能最丰富,最像关系型数据库
-ConthDB
列存储数据库
-HBase
分布式文件系统
图关系数据库
-Neo4J
放的是关系非图形,比如朋友圈社交网络一对多一对一等等构建关系图谱

7.17


Redis(remote Dictionary server) 远程字典服务
www.redis.io 官网
www.redis.cn 官方中文网
由于内存存储是断电即失、需要持久化、持久化 rdb、aof
效率高、用于高速缓存
发布订阅分析
地图信息分析
计时器计数器
windows在github上下载(停更)

1.安装基本的依赖
yum install -y gcc-c++
2.解压redis
根目录下make &make install
安装后路径 /usr/local/bin
复制配置文件到 目录下
3.redis默认不是后台启动
修改配置文件 redis.conf
daemonize 参数修改为yes 后台启动守护进程
4.运行服务
redis-server /usr/local/bin/redisconf/redis.conf
5.测试连接
redis-cli -p 6379
ping
keys *
6.查看进程
ps -ef|grep redis
7.关闭服务
连接端口>shutdown

redis-benchmark 压力测试工具
redis-benchmark -h localhost -p 6379 -c 连接数 -n 100000

6.0版本之前redis是单线程
redis所有的数据都是放在内存中,所以使用单线程操作效率更高,对内存系统来说没有上下文切换效率最高,多次读写都在一个cpu上的。 Redis中只有网络请求模块和数据操作模块是单线程的。而其他如持久化存储模块、集群支撑模块等是多线程的。在提升IO利用率方面上,Redis并没有采用多线程技术,而是选择I/O多路复用技术,多个线程的互相切换也会带来一定的性能开销,多线程会涉及锁

IO多路复用 socket(即套接字)需要了解TCP三次握手
LInux多路复用技术多个进程可以注册到一个管道上,这个管道会统一内核进行交互,当管道中的某一个请求需要数据准备好之后,进程再把对应的数据拷贝到用户空间中,通过一个进程处理多个io流 IO多路复用LINUX下包括select,poll,epoll三种模式

在Redis 中,文件事件处理器包括socket、I/O 多路复用程序、文件事件分派器、以及事件处理器。使用 I/O 多路复用程序来同时监听多个socket,并根据套接字目前执行的任务来为socket关联不同的事件处理器。每当一个socket准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个socket,所以多个文件事件有可能会并发地出现。

原理:多路复用程序会监听多个socket,当socket已经完成了事件复用程序会将这个socket传给文件事件处理器,当有多个socket时io复用程序会把已经完成的事件放入队列通过队列有序同步每次一个socket方式传给文件事件处理器,当事件处理器执行完毕后才会传送下一个socket


客户端访问服务器传输数据时,当客户端没有向服务器发送数据write服务器则会阻塞接收数据read,但当多个客户端同时连接服务器时服务器则会等待第一个客户端数据处理完成后才会接收第二个客户端数据那么就会有一个问题当第一个客户端一直占用连接,那么服务器server则会一直等待不处理其他请求

解决这个方法可以用多线程去监听多个socket,但是redis是在单线程中所有操作是按照顺序线性执行,一旦读写操作等待着用户输入或者输出会导致进程无法对其他客户提供服务,所以redis采用了I/O多路复用,多路指的是网络连接客户端,复用同一个线程,指一个线程检查多个socket的就绪状态,单个线程中通过记录跟踪每一个socket(I/O流)管理多个IO流。
客户端->io多路复用程序->文件处理分发器->事件处理器

例如:以 Redis 的 I/O 多路复用程序 epoll 函数为例
多个客户端连接服务端时,Redis 会将客户端 socket 对应的 fd 注册进 epoll,然后 epoll 同时监听多个文件描述符(FD)是否有数据到来,如果有数据来了就通知事件处理器赶紧处理,这样就不会存在服务端一直等待某个客户端给数据的情形。

redis I/O多路复用程序

redis(I/O多路复用程序函数有 select、poll、epoll、kqueue)
Redis 的 I/O 多路复用模式使用的是 「Reactor 设置模式」
Reactor 会监听所有请求连接然后解析事件内容分发给对应的事务处理器进行处理
优点:模型简单,没有多线程、进程通信、竞争的问题,全部都在一个线程中完成
性能问题,只有一个线程,无法完全发挥多核 CPU 的性能。Handler 在处理某个连接上的业务时,整个进程无法处理其他连接事件,很容易导致性能瓶颈
可靠性问题,线程意外终止,或者进入死循环,会导致整个系统通信模块不可用,不能接收和处理外部消息,造成节点故障
使用场景:客户端的数量有限,业务处理非常快速,比如 Redis在业务处理的时间复杂度 O(1) 的情况

6.0版本redis中引入多线程因为需要更大的QPS(每秒查询数)io多路复用技术也会阻塞线程如果能采用多线程,使得网络处理的请求并发进行,就可以大大的提升性能。多线程除了可以减少由于网络 I/O 等待造成的影响,还可以充分利用 CPU 的多核优势。但也只针对处理网络请求的接收和解析过程采用了多线程,而数据读写命令,仍然是单线程处理。只有网络请求的接收和解析,以及请求后的数据通过网络返回时,使用了多线程,数据读写依旧是单线程完成,这样不会出现并发问题

redis是内存中的数据结构存储系统,他可以用作数据库、缓存和消息中间件MQ
redis默认16个数据库

redis命令
select 切换数据库
dbsize 数据库大小
flushdb 清空当前数据库
keys 查询所有key键
exists 判断key是否存在
expire 设置某键值过期时间
ttl 查看当前key剩余时间-1代表永久 -2代表过期
del 移除key
type 查看类型
move 移动键值到某库

————————————
String 字符串类型
set 设置key
get 获取key
setex 设置过期时间
setnx 不存在设置 存在key会创建失败(分布式锁常用)
getrange 截取key 负数为倒数第几个
setrange 替换指定字符
incr 自增1
decr 自减1
incrby 自定义增加
mset 批量设置
mget 批量获取
msetnx 全部判断是否成功创建 原子性 事务的不可分割性
getset 先获取后设置
——————————————————————————
List 列表类型
LPUSH 放入键值,方向左
LRANGE 获取键值
RPUSH 放入键值,方向右
Lset 更改键值
LPOP 移除左边第一个数值
RPOP 移除右边最后一个值
lindex 获取某个下标的值
llen 获取列表长度
LREM 移除列表指定个数的value
ltrim 截取下标列表元素
rpoplpush 移动列表最后一个元素到另一个列表
linsert 指定元素前面或后面插入一个值

————————————————————————————————
Set 集合类型
sadd 加入集合
smembers 查看集合
simember 判断值存不存在集合中
scard 获取set集合个数
srandmember 随机抽取元素
spop 随机移除元素
smove 移动指定值到另一个集合中
sdiff 查看多个集合的差集
sinter 查看多个集合的交集
sunion 查看多个集合的并集

——————————————————————————————————————
Hash 哈希集合
hset 设置map集合
hget 获取map集合 嵌套
hmset 批量设置
hmget 批量获取
hgetall 获取全部
hdel 删除hash指定的key
hlen 获取hash字段数量
Hexists 判断hash中指定字段是否存在
hincrby 字段自增
hsetnx 判断hash是否字段是否存在,没有则添加
————————————————————————————
Zset 有序集合
zadd 添加集合 zadd name 1 value
zrange 查询集合 withscores 查看数值
zrangebycore 查询集合范围 -inf +inf
zrevrange 降序查询集合
zrem 删除集合的某一个值
zcard 获取集合中的个数
zcount 获取集合区间的个数

——————————————————————————————————

geospatial 地理位置
GEO 地理空间(经度,纬度,名称)#两极无法添加
geoadd 添加地理位置
geopos 获取地理位置
geodist 返回两个地理位置之间的直线距离
georadius 搜索指定地理位置距离半径的元素 withcoord 获取坐标 withdist 获取距离 count 搜索的数量
georadiusbymember 搜索目标位置距离半径内的元素
geohash 返回一个或多个元素的geohash字符串 11位
zrem 删除
zrange 查看元素也可以在geo中使用

——————————————————————————————————
Hyperloglog
PFadd 添加
PFcount 统计key里面的个数
pfmerge 两个key的交集到一个key里
————————————————————————————————————————
bitmaps 位存储
setbit 设置
getbit 获取
bitcount 统计
——————————————————————————————————————
7.21
事务
multi 开启事务进入事务命令窗口
exec 执行事务命令
watch 监视key对象 (乐观锁)
unwatch 解除乐观锁

——————————————————————————————————————
redis数据类型
Redis-key
数据结构相同
String 字符串类型:value可以是数字
计数器
统计多单位的数量
粉丝数
对象缓存存储
对象
set user:1:name zhangsan
set user:1:age 18

List 列表
是一个双向链表
key不存在,创建新链表
key存在,新增内容
移除所有值,空链表,不存在
消息队列(LPUSH RPOP) ,栈(LPUSH LPOP)

Set 集合
无序不重复集合
随机性

Hash 哈希
Map集合,key-map
本质和String类型差不多 是一个简单的key-value
存储变更数据
适合对象存储

Zset 有序集合
排行

GEO
GEO底层实现原理是Zset 有序的集合每个都有序号
可以使用zset命令操作geo

Hyperloglog 基数(不重复的元素)
基数统计算法
网页的UV(一个人访问网站多次)
使用hyperloglog优点占用内存小2^64,

Bitmaps
位存储 0 1 0 1 1
统计用户状态
——————————————————————————

事务
ACID
原子性 要么全部完成,要么全部不完成,不会结束在中间,执行过程中失败会回退到开始前状态
一致性 在事务开始前和结束后,数据库的完整性没有被破坏。表示写入的资料必须完全符合所有预设规则
隔离性 数据库允许多个并发事务同时对数据进行读写和修改能力,隔离保证多个事务执行后的数据不一致 包括未提交、提交、重复读、串行化
持久性 事务结束后对数据的修改就是永久的,系统故障也不会丢失

但是在redis单条命令支持原子性,而事务不保证原子性
redis事务:一组命令的集合,一个事务中的所有命令都会被序列化在事务执行过程中,会按照顺序执行
一次性、顺序性、排他性
redis没有隔离级别的概念

开启事务(multi)
命令入队(输入redis操作命令)
执行事务(exec)
放弃事务(discard)没有执行事务时事务中的队列都不会被执行

编译型异常 单条命令(代码有问题命令有错误),事务所有命令不会被执行
运行时异常(1/0),如果事务队列中存在语法性,执行时,其他命令依旧会执行错误会抛出(无原子性)

监控watch
悲观锁:影响性能,占用防止以外的访问去修改数据,锁定数据,保证数据安全性

乐观锁:不会锁定数据,更新数据的时候会判断有没有其他人修改数据会设置一个version,更新的时候去比较version,版本的记录机制

watch 监视key对象
在数据期间没有发生变动则正常执行,当其他线程修改了key事务则返回nil不执行事务
乐观锁锁定后执行失败需要重新解锁,重新获取乐观锁
但在redis中无论事务是否执行成功,都会取消watch监控

——————————————————————————————————————

Jedis
redis推出的JAVA连接开发工具,使用java操作redis的中间件
Jedis jedis=new Jedis(host:"",port:);
Jedis.ping();
调用命令
开启事务
Transaction multi =jedis.multi();
multi.set();
multi.exec();
dedis.close();

SpringBoot整合
SpringData
springboot2.x后,jedis替换为了lettuce
jedis:采用的是直连,多个线程操作,不安全,使用jedis pool连接池 类似BIO模式
lettuce:采用netty,实例使用多个线程进行共享,不存在线程不安全,减少线程数量 类似NIO模式

Redis.conf 配置文件

单位不区分大小写

include 导入多个配置文件
————————
network 网络配置
bind 绑定本地的ip 可以写* 也可以直接注释
protected-mod yes #安全保护模式
port 端口设置
——————————
general 通用配置
daemonize yes 以守护进程方式运行
loglevel notice/debug/verbose/warning 日志记录模式
ogfile 日志文件位置
database 16 数据库数量
always-show-logo yes logo显示

——————————
snapshotting 快照 (持久化)
save 900 1 900秒内修改了一次操作,进行持久化操作
save 300 10 300秒内进行了至少10次操作,则进行持久化操作
save 60 10000 60秒内进行了至少10000 次操作,则进行持久化操作
stop-writes-on-bgsave-error yes 如果持久化出现错误继续进行工作
rdbcompression yes 是否压缩rdb文件,消耗cpu资源
dir ./ rdb文件保存的目录
——————————————————————
Replication 复制 主从复制

————————————————————————————
security 安全
requirepass 密码
cli命令行中 config set requirepass 密码
auth 密码 登录

————————————————
clients 限制客户端
maxclients 10000 最大连接数
————————————————
maxmemory 最大内存容量
maxmemory-policy noeviction 内存满后策略可配置删除过期的key
————————————————————
append only mod (aof持久化配置)
appendonly no 默认不开启原因默认使用rdb持久化
appendfilename "" 持久化文件
appendfsync eversec 每秒执行一次sync,/always每次修改/ no

————————————————————————

持久化:规定时间执行了多少次操作,则会持久化到文件 .rdb .aof 相当于本地数据库或者备份
redis是内存数据库,如果不保存,断电重启后将会消失
RDB(redis database)指定时间里内存的数据集写入到磁盘
相当于快照,恢复时将快照文件读入到内存

redis会单独创建父进程(fork)一个子进程来进行持久化,父进程和子进程共用内存,将内存数据写入到一个临时文件中再用这个临时RDB文件替换上次持久化文件,整个过程不进行I/O操作,确保极高的性能,如果进行了大规模数据恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB缺点最后一次持久化 后的 数据可能丢失
只需要放到redis启动目录下即可
适合大规模数据恢复

AOF(Append only File)
将所有命令都记录下来,history,恢复时把所有命令都执行一遍,不记录执行写操作
当持久化文件出错可以用 redis-check-aof redis-check-rdb修复
数据文件大小 aof大于rdb
当一个AOF达到一定大小 配置文件可设置重写操作 新建一个新的AOF文件
aof默认文件的无限追加
fork一个子进程根据内存做数据快照写入重建数据库状态命令,父进程写命令缓存起来或者写入旧的AOF文件,子进程写完后通知子进程,父进程将缓存写入AOF临时文件,父进程用临时文件替换旧的AOF文件,后面写的命令直接往AOF文件追加

群集里的redis主从会比较两个文件哪个最新以恢复数据

——————————————————

Redis发布订阅
redis发布订阅(pub/sub)是一种消息通信模式:pub发送,sub接收
redis会创建一个字典 频道作为键,在channel字典中查找记录了订阅这个频道的所有客户端链表,遍历这个链表发送给所有订阅者
redis客户端可以订阅任意数量的频道
publish 频道号 消息 发送消息到频道
subscribe 频道号 订阅频道号或建立

——————————————————————
redis主从复制(master/leader)
数据的复制都是单向,只能由主节点到从节点,master以写为主,leader以读为主
默认情况下,每台redis服务器都是主节点,一个主节点可以有多个从节点,但一个从节点只能由一个主节点
主节点停机后,根据哨兵模式从节点投票可以筛选出新的主节点,但需要有3个redis服务器作为群集(基本一主二从)
主从复制作用:
1.数据冗余:主从实现了数据热备份,是持久化的一种数据冗余方式
2.故障恢复:当主节点出现问题时,可以由节点提供服务,实现故障恢复
3.负载均衡:配合读写分离,分担服务器负载,提高服务器的并发量
4.高可用:哨兵和集群保证可靠性

结构上,单个redis服务器发生节点故障,并且一台服务器需要处理请求负载,压力大
容量上,单个redis服务器内存容量有限,不能将所有内存用作redis存储内存
一般来说单台redis最大内存不超过20G,超过服务器压力大

————————————————————————————————

集群环境配置 redis-replication

info查看信息
info replication 查看节点信息
————————————————
global
————————————————
redis.conf配置文件
port 修改端口
pidfile 修改pid文件目录
logfile 修改log文件名
dbfilename 修改rdb文件名

命令行方式加入主从复制
redis-cli命令行下
slaveof 指定服务器的从属机 当开启了集群不可用
命令行中从机重启后会重置配置从机会变回主机,获取不了主机数据库
slaveof no one 自己作为主节点

配置文件下加入主从复制
replicaof 有密码配置密码
masterauth
replica-read-only 设置从机只读

但断开后无法选举主节点,且只能主机写,从机读,从机写也不能同步到主机,主机重启后会获取从机数据同步,从机也可以指定从机作为主节点

主机->从机2台
主机->从机->从机

原理:slave启动后连接到master后会发送sync同步命令master接到命令,启动后台存盘进程,同时接收用于修改数据集的命令,在后台进程执行完毕后,master将整个数据文件到slave,并完成一次完全同步

增量复制:master继续将新收集的修改命令传给slave,完全同步(全量复制)但只要重新连接master,一次完全同步将会被自动执行

哨兵模式(自动选举)
没有哨兵模式前主从复制需要手动更改主节点自己设置slaveof no one
需要建立一个哨兵的进程后台监控主机是否故障,故障了根据投票自动转换为主库,通过给redis服务器发送命令等待服务器回应查看是否正常运行。哨兵也可以配置集群保证冗余,哨兵之间互相监控,形成多哨兵模式
多哨兵模式下,主服务器宕机,哨兵1先监测到结果,并不会马上进行failover过程,只是哨兵1主观认为主服务器不可用,这现象为主观下线,当后面的哨兵也监测到主服务器不可用,并达到一定值那么哨兵会发起投票,投票结果由一个哨兵发起,进行failover故障转移操作,切换成功后会通过订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,过程称为客观下线

1.创建哨兵配置文件
sentinel.conf

sentinel monitor [name] [ip] [port] 1 #表示监控的服务器 1代表多少个哨兵认为主节点失联那么就判断这个主节点确实失联

2.启动哨兵

redis-sentinel sentinel.conf

主机重启后加入主从,将会降为slave
哨兵集群,基于复制模式,所有主从配置都有
主从切换,故障转移
哨兵模式,让主从自动切换
缺点:
redis集群到达上限,在线扩容麻烦
哨兵模式配置繁琐

在安装目录下的 sentinel.conf
port 26379 默认端口 集群必须配置
daemonize no 后台启动 需要配置log文件
dir /tmp 哨兵模式的工作目录
sentinel monitor mymaster 127.0.0.1 6379 1 必须配置
sentinel auth-pass 主节点名称 密码 主从密码要统一 可选配

redis缓存穿透和雪崩
缓存查询
客户端的读请求会先去缓存中查找,数据查询不到则会去数据库查找

缓存穿透(查询空值)
当多个用户去查询数据在缓存没有命中的情况下会往数据库中查询,这时就会给持久化数据库造成压力,这就是缓存穿透
解决方法:在请求的过程中加个过滤器或者在缓存中加个空值
1.布隆过滤器
布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层进行校验不符合则丢弃,避免对底层存储系统的查询压力
2.缓存空对象
当存储层不命中,即使返回空对象也将其缓存起来,同时会设置一个过期时间,之后在访问这个数据,会从缓存中获取,保护了后端数据源,但当搜索的空值太多也会存储更多的空值需要大量空间,即使对空值设置了过期时间,还会存在缓存层和存储层的数据有一段时间窗口不一致(缓存层存了空值之后数据层添加了这个数据)这对于需要保持一致性的业务会有影响

缓存击穿(大量同一请求)
和缓存穿透的区别在于,一个是绕过缓存直接查询持久化层,一个是查询缓存层突然全部流量去查询持久化层
当多个用户查询数据,高并发的查询着缓存,当缓存过期失效的瞬间,请求就会去查询数据库造成压力
解决方案:设置过期时间永不过期,加互斥锁
1.设置过期时间永不过期,但会占用存储空间
2.互斥锁:使用分布式锁,保证每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁权限则等待。这种方式会将高并发压力转移到分布式锁

缓存雪崩(压力峰值)
指在某一时间段,多个缓存集中过期失效,redis受到大量请求宕机
和缓存击穿的区别在于缓存击穿是大量请求访问同一数据缓存失效,而缓存雪崩是大面积数据缓存同一时间失效
客户端请求数据,会从缓存层获取,当缓存层失效后大量请求使数据库满载宕机
原因在于同个时间段创建缓存,对数据库周期性压力的影响
解决方法:服务降级限流、数据预热、redis高可用
1.保证高可用,关闭不必要的功能或服务提高服务器性能,通过加锁或队列来控制读数据库写缓存进程数量(对某一key只允许一个线程查询其他线程等待)
2.正式部署前把可能访问的数据线访问一遍这样大量访问数据会加载到缓存中。即将发送大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效时间尽量均匀
3.服务器搭建集群,添加服务器(异地多活)