redis是我们在项目中经常使用到的。
Redis(Remote Dictionary Server)是一个开源的使用ANSI C语言编写的NoSQL数据库、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis的数据是存在内存中的,所以读写非常快,被广泛应用于缓存方向,Redis也可以将数据写入磁盘内,保证数据不会丢失,而且Redis的操作是原子性的。
Redis效率高
1、基于内存:Redis是使用内存存储的,读写效率快,没有使用到磁盘IO的开销。
2、单线程实现:Redis是单线程处理,避免了多个线程之间线程切换和锁竞争的开销。
3、IO多路复用:使用单线程来轮询描述符,将数据库的操作转换成了事件,不在网络IO
浪费过多时间。
4、高效的数据类型:Redis对每种数据类型底层进行了优化,追求更高的效率。
Redis为什么使用单线程
Redis是基于内存的,Redis在操作数据的时候不需要对磁盘进行IO操作,而且使用多线程需要进行线程切换,反而会影响效率,redis可以承担Redis读的速度是110000次/s,写的速度是81000次/s ,也就是说redis的每秒查询率大概在10W量级上,当请求量超过10W+,这时候我们可以通过redis集群(读写分离,主从同步,哨兵监控健康状态)来处理。
Redis五种数据类型
1、String(字符串)是Redis最基础的数据结构,它是二进制安全的,可以存储图片或序列化
的对象,应用场景:共享sesion、计数器
2、List(列表)用来存储多个有序的字符串,应用场景:文章列表
3、Set(集合)也是存储多个字符串元素,不允许存储重复元素,应用场景:生成随机数、
用户标签、社交需求
4、Zset(有序集合)已排序的字符串集合,同时元素不能重复,应用场景:排行榜
5、Hash(哈希)键值对结构,应用场景:缓存用户信息
Redis主从复制原理
是指在redis集群里面master节点和slave节点数据同步的机制。将一台redis服务器里的数据复制到其他的redis服务器里面,其中,负责复制数据来源的节点称为master,被动接受数据同步的是slave,在redis里面提供了全量复制和增量复制两种模式。
1、全量复制:一般发生在slave节点初始化的阶段,这个时候需要把master上所有的数据全部都copy一份,具体工作原理
a、slave节点会向master发送一个sync的命令,master收到命令后会生成数据快照。
b、把数据快照发送给slave节点,slave节点收到数据之后,丢弃旧的数据并重新载入数据快
照,然后对外提供服务。
注意:在主从复制的过程中,redis并没有采用数据的强一致性,因此会存在数据同步的延迟导致数据不一致的问题。
2、增量复制:master发生数据变更之后,会把变更的数据同步给所有的slave节点,原理:
a、master和slave节点都会维护一个复制偏移量offset,用来表示master和slave传递的字节数量,每一次进行增量数据的传递,offset都会增加相应的字节数量,redis只要根据offset就可以实现增量的数据同步。
Redis哨兵模式
哨兵主要用于管理redis服务器,主要有三个任务:监控、提醒以及故障转移。
哨兵执行原理:每个哨兵会向其他哨兵、master、slave定时发送消息,确保对方还活着,如果在配置的时间内未回复,则暂时认为对方已挂,如果哨兵群中大多数都报告某一个master没响应,系统才认为该master死亡,通过vote算法从剩下的slave节点中选一个提升为master,自动修改相关配置。
哨兵模式故障迁移流程:从主服务器的从服务器中选定一个从服务器作为新的主服务器。
选点依据:
1、网络连接正常->五秒内回复info命令->10*down-after-milliseconds内与主连接过->从服务器的优先级->复制片偏移量->运行id
较小的
2、通过slave no ont 将该服务器提升为新主服务器
3、通过slaveof ip port 命令让其他从服务器复制该主服务器
缓存穿透、缓存击穿、缓存雪崩
1、缓存穿透:请求访问的时候,缓存和数据库都没有这个值,这样会导致每次对这个值的请求都会到数据库访问。
产生的原因:业务不合理的设计、业务/运维/开发事务的操作(缓存和数据库的数据都被误删)。
如何避免缓存穿透:
1、如果查询数据库为空,给缓存设置一个空值、或者默认值。当有请求访问,需要更新缓存,来保证缓存的一致性,同时,给缓存设置过期时间。
2、使用布隆过滤器判断数据是否存在,存在的话才能往下查。
布隆过滤器原理:它由初始值为0的位图数组和N个哈希函数组成。一个对一个key进行N个hash算法获取N个值,在比特数组中将这N个值散列后设定为1,然后查的时候如果特定的这几个位置都为1的值,那么布隆过滤器判断该key存在。
2、缓存击穿:缓存中没有,数据库中有,有大量热点数据并发请求过来,从而大量的请求到了DB数据库。
如何避免缓存击穿:
1、预先设置热门数据:将一些热点数据存入redis中,监控热门数据,实时调整热点key的过期时长。
2、使用分段式锁:只让一个线程构建缓存,其他线程等待构建缓存执行完毕,重新从缓存中获取数据。
3、缓存雪崩:缓存中大量数据到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据据库压力过大或宕机。
原因/解决:大量热点数据同时过期,可以均匀设置过期时间解决;redis宕机也可能引起缓存雪崩,需要搭建redis高可用集群。
Redis的持久化机制
RDB
把内存数据以快照的形式保存到磁盘上,RDB持久化是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据快照写入磁盘内,他是redis默认的持久化方法,在指定目录下生成dump.rdb,redis重启的时候,通过加载dump.rdb文件来恢复数据。
RDB触发方式:
1、手动触发:save同步,会阻塞当前redis服务器;bgsave异步,redis进程执行fork操作创建
子进程。
2、自动触发:save m n,m秒内数据集存在n次修改时,自动触发bgsave。
RDB优点:适合大规模的数据恢复场景,如备份,全量复制等。
RDB缺点:没办法做到实时持久化/秒级持久化;新老版本存在RDB格式兼容问题。
AOF(append only file)
采用日志的形式来记录每个写操作,追加到文件中,重启的时候重新执行AOF文件中的命令恢复数据,主要是解决数据持久化的实时性问题,默认不打开。
AOF的优点:数据的一致性和完整性更高
AOF的缺点:AOF记录的内容越多,文件越大,数据恢复变慢。
学习redis更主要的还是要通过实践,毕竟理论只能给实践提供概念支持,只有实际上手,才能更好的理解redis。