文章目录
- 1.什么是redis?
-
- 2.数据类型
-
- 3.redis的持久化机制
-
- 3.1 rdb(Redis DataBase)快照
- 3.2 aof(Append-only file)
- 4.redis发布订阅(pub/sub)
- 5.高可用-- 集群+主从同步+哨兵
- 6.缓存雪崩、击穿、穿透
- 7.淘汰策略
- 8.集群-主从复制-哨兵模式搭建
1.什么是redis?
开源,基于内存的k-v结构的nosql数据库
1.1优势
1.基于内存,读写性能高;读11万/s,写8.1万/s
2.数据类型丰富;String、List、Hash、Set、Zset等
3.支持事务;单条命令具有原子性,但事务不保证原子性,且没有隔离级别的概念
4.支持数据的持久化;rdb、aof
5.单线程;redis是纯内存访问本身就很快,使用单线程没有CPU上下文切换的消耗,不会产生并发问题
6.非阻塞IO;采用epoll多路复用
2.数据类型
2.1五大数据类型
1.String缓存功能、计数器、共享用户Session
2.List(列表双向的,可重复)队列(从头进去、屁股出来,1对1)、列表、分页(高性能)
3.Hash(哈希,map集合k-v结构,)存储对象信息
4.Set(集合,值无序、不重复)交集、并集、差集的操作,比如好友等相互关系
5.Zset(有序不重复集合,set基础上加一个排序值)排行榜
2.2特殊的类型
1.Geospatial地理位置,实现附近的人
2.Bitmap位存储,实现布隆过滤器
3.Hyperloglog基数(不重复元素)网页的访问量(一个用户多次访问只算一次)
3.redis的持久化机制
3.1 rdb(Redis DataBase)快照
默认持久化方式,根据策略的某个时间点将数据写入dump.rdb文件;
恢复:将rdb文件放在redis启动目录下,redis会自动检查dump.rdb恢复数据
优点:
1.容灾性好,一个文件可以保存到安全的磁盘
2.性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO最大化。使用单独子进程 来进行持久化,主进程不会进行任何 IO 操作,保证了 redis的高性能
3.相对于数据集大时,比 AOF 的启动效率更高
缺点:
1.数据安全性低。rdb是间隔一段时间进行持久化,如果持久化之前发生故障,会发生数据丢失
3.2 aof(Append-only file)
将Reids的操作命令日志以追加的方式写入appendonly.aof文件
问题:如果aof文件有错位,这时候redis是启动不起来的,需要修复该文件(redis-check-aof --fix appendonly.aof)
优点:
1.数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次
缺点:
1.数据集大的时候,启动效率低
4.redis发布订阅(pub/sub)
1对n模式,不常用,一般会直接使用MQ
5.高可用-- 集群+主从同步+哨兵
1.集群
最低配置1主2从
2.主从同步
原因:单机QPS(查询率/s)有上限的,而且Redis的特性就是必须支撑读高并发的,那你一台机器又读又写,这谁顶得住啊;你让这个master机器去写,数据同步给别的slave机器,他们都拿去读,可以分发掉大量的请求,而且扩容还可以轻松实现水平扩容
你启动一台slave 的时候,他会发送一个psync命令给master,如果是这个slave第一次连接到master,他会触发一个全量复制,生成RDB快照发送给slave;后面的增量的数据master使用AOF进行同步
3.哨兵
哨兵必须用三个实例去保证自己的健壮性的,哨兵+主从并不能保证数据不丢失,但是可以保证集群的高可用
集群监控:负责监控 Redis master 和 slave 进程是否正常工作。
消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
6.缓存雪崩、击穿、穿透
1.缓存雪崩
理解:(缓存key大面积过期,大量请求直接落到数据库,导致数据库挂掉)
如果所有热点数据失效时间都是12小时,中午12点刷新的,晚上零点有个活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。
解决:
1.在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值,可以保证数据不会在同一时间大面积失 效
2.使用主从模式和集群模式来尽量保证缓存服务的高可用(主要用redis哨兵来解决)
3.依赖隔离组件为后端限流并降级:比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
4.使用快速失败的熔断策略,减少 DB 瞬间压力
2.缓存穿透
理解:某个key非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个key在失效的瞬间,大量的请求就直接请求数据库,导致数据库挂掉
解决:
1.可以将热点数据设置为永远不过期;
2.实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求就能通过该key访问数据
3.缓存击穿
理解:指缓存和数据库中都没有的数据,而用户不断发起请求,数据库每次都会检索一遍,导致数据库压力过大,严重会击垮数据库
解决:布隆过滤器(Bloom Filter)对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力
4.缓存更新方式
1.考虑数据源DB或远程服务
DB直接去更新DB,然后更新缓存
远程服务可能无法及时主动感知数据变更,这种情况下一般会选择对缓存数据设置失效期
5.数据不一致
原因:一般是主动更新失败,例如更新DB后,更新Redis因为网络原因请求超时;或者是异步更新失败导致
如果服务对耗时不是特别敏感可以增加重试;敏感的话用异步处理更新
7.淘汰策略
1.定期删除
定期好理解,默认100s就随机抽一些设置了过期时间的key,去检查是否过期,过期了就删了
2.惰性删除
我不主动删,我懒,我等你来查询了我看看你过期没,过期就删了还不给你返回,没过期该怎么样就怎么样
3.内存淘汰机制
noeviction:永不过期,返回错误
allkeys-lru:删除lru(最少使用的键)key
volatile-lru:只对设置过期时间的key进行lru(最少使用的键)(默认)
allkeys-random:随机删除
volatile-random:随机删除即将过期的key
volatile-ttl:删除即将过期的key
8.集群-主从复制-哨兵模式搭建
1.下载安装包
2.指定解压目录:tar -xzf /home/redis-4.0.9.tar.gz -C /usr/java/redis/
3.安装:1.cd /usr/java/redis/redis-4.0.9/
2.make
3.cd /usr/java/redis/redis-4.0.9/src/
4.make install
4.创建文件夹将config文件统一存放:mkdir etc
5.集群配置文件:port端口、bind绑定ip(0.0.0.0)、daemonize yes(后台运行)、pidfile、logfile、dbfilename(dump.rdb)
6.进入bin执行redis服务:
redis-server /usr/java/redis/redis-4.0.9/etc/redis79.conf
redis-server /usr/java/redis/redis-4.0.9/etc/redis80.conf
redis-server /usr/java/redis/redis-4.0.9/etc/redis81.conf
7.进入bin目录查看进程信息:ps -ef|grep redis
8.进入bin目录进入端口:redis-cli -p 6379 进入:info replication查看主从复制信息
9.主从复制配置:(默认情况下每台redis服务器都是主节点)(全量复制、增量复制)
在从机bin目录进入端口:127.0.0.1:6380> slaveof 47.93.87.188 6379
细节:1.主机可以写,从机不能写只能读!主机中的所有信息和数据,都会自动被从机保存
2.主机断开连接,从机依旧可以连接主机,但是没有写操作,如果主机回来了,依旧可以获取主机 写的数据
3.从机断开连接,如果用命令行配置的主从,从机重启会变回主机(无法共享主机数据),再配置为 从机(可以共享主机数据)
10.哨兵模式
创建配置文件:sentinel monitor myredis 47.93.87.188: 6379 1(代表主机挂了,slave投票让谁做主机)
启动哨兵:redis-sentinel /usr/java/redis/redis-4.0.9/etc/sentinel01.conf
如果主机断了再回来,会变为新主机的从机