redis是什么介绍
redis是储存在内存中,读写很快,是基于c语言编写的,是原子性的,常用于缓存。redis可以将数据储存到磁盘中实现持久化。
redis的优点
1.基于内存,访问速度很快。
2.支持多种数据类型,如hash,String,map等
3.支持持久化
4.redis的操作是单线程的,安全
5.redis支持主从的机制
6.redis支持事务
缺点:
1.不支持结构化,不能像mysql那样实现复杂的查询。
2.受内存的限制,不能用于储存海量数据
3.难以支持在线扩容,当容量达到顶峰时很难处理。
redis为什么这么快
1.基于内存,没必要再去访问磁盘
2.io多复用模型.Redis 采用 IO 多路复用技术。Redis 使用单线程来轮询描述符,将数据库的操作都转换成了事件,不在网络I/O上浪费过多的时间
3.高效的数据结构:Redis 每种数据类型底层都做了优化,目的就是为了追求更快的速度
为什么不能将redis作为主数据库
1.不能储存海量数据
2.不支持结构化查询(体现不出外键,关系型数据库)-->只能进行简单的事务处理,和简单的数据处理。
3.安全性问题,没有像用户认证,访问控制这样的知识。
4。由于数据是第一事件储存到内存中,虽然能储存到磁盘中,但中途发生断电等操作会导致数据的消失
redis的线程模型
redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。分为4个部分。多套接字,io多复用模型,文件事件分派器,事件处理器。文件事件分派器通过io多复用模型去监视多个套接字,然后套接字产生read,write等操作。文件事件处理器就会调用与套接字关联的事件处理器去处理这个事件
Redis应用场景有哪些
1.热点缓存
2.签到,bitmap
3.分布式锁
4.分布式缓存
5.计数器(点赞功能)
6.消息队列,推送机制
7.排行榜
8.限制其(限制访问网站的数目)
Memcached和Redis的区别(缓存工具的调查,为什么选择了redis)
1.redis支持数据的持久化
2.redis支持的数据结构储存更加多元化
3.redis可以支持多集群
4.redis的value储存空间更大
5.redis是单线程的多路复用模型
为什么要用 Redis 而不用 map/guava 做缓存
redis是用于分布式,map/guava是作用于jvm中的本地,当出现多台服务器的时候会引发错误。而redis则保证了数据的一致性
Redis 数据类型有哪些
基础5种
1.hash 2.list 3.set 4.sortlist 5.string
特殊三种
1.bitmap 2.Geospatial(用于储存地理信息) 3.Hyperloglog(HyperLogLog 是用来做基数统计的算法,经常用于统计独立访客)
SortedSet和List异同点
1.都是有序的
2.都可以获得一个范围内的数据
不同点:
1.list是基于链表实现,查找中间元素久
2.sortlist是基于散列表和跳越表实现。list不可以更高元素位置,但sortlist可以
3.sortlist更加消耗内存
Redis的内存用完了会怎样
1.没有设置策略,到达顶再次插入会返回错误信息,但可以正常读
2.设置了会通过淘汰策略将老数据进行淘汰
Redis如何做内存优化
多用散列表,要用紧凑的方式储存数据来节约内存空间
Redis存在线程安全问题吗
1.在服务端执行是线程安全的
2.在客服端中,如果一个事务中包含了多个的redis语句,这些redis语句是可能出现线程不安全的。可以采取lua脚本解决。
或者通过加锁的方式。
keys命令存在的问题
因为redis是单线程,正常scan会导致线程被阻塞。所有scan采用渐进式遍历。是使用分批处理去返回扫描结果,但这同样带来了一些问题,在分批的过程中如果添加了和删除了一些元素就会导致数据的幻读。
Redis事务
通过mutli开启一个事务,在期间的命令会加入到队列不会真正执行,通过exec提交事务。事务不保证原子性,如果其中一个命令出错,不影响其他执行。
watch命令
Redis事务支持隔离性吗
支持隔离性,因为是单线程的。不会被打断。
Redis事务保证原子性吗,支持回滚吗
单条命令是原子性,事务不是原子性,事务不支持回滚
持久化机制
持久化就是要把内存的数据写入到磁盘中。
RDB
是redis的默认持久化操作
每隔一段时间将进行数据储存,主要通过bgsave,由父进程开启子进程,如果子进程存在则将其删去,开启fork进程会将数据写入临时文件,当临时文件完成后去替代磁盘的dump.rdb文件。
触发方式:
优点:
1.恢复效率快储存效率快
缺点:
1.容易造出数据的丢失
2.reids不同版本的rdb文件可能无法被兼容
AOF
写命令加入到缓冲区中,然后慢慢加入到aof文件中,aof根据配置的规律向磁盘进行数据同步,到达一定量后去清楚aof,重启时则通过aof文件去恢复还没来得及写入磁盘的数据进行恢复。
优点:
1.aof可以保证数据不易丢失,如果配置为1s同步一次,则最多丢失1s的数据
2.AOF以append-only的模式写入,所以没有磁盘寻址的开销,写入性能非常高
缺点:
1.对于同一份文件AOF文件比RDB数据快照要大
2.数据恢复速度慢
RDB和AOF如何选择
1.如果数据不敏感,可以选择关闭持久化。
2.如果数据比较重要,但可以承受几分钟的丢失可以使用rdb
3.可以都选择,默认恢复是使用aof,因为aof恢复的数据更加精确。
Redis有哪些部署方案
1.单节点部署
2.主从分布
3.哨兵模式
4.Redis cluster:服务端分片技术
主从架构
一个用于写,一个用于读。
哨兵Sentinel
工作原理:
哨兵不断的ping从节点,如果从节点发生了故障就要去验证是否下线。当确认下线后就需要选出新的状态好的节点让它作为新的主节点,然后通知其他节点更新主节点的信息。
Redis cluster
建立了多个主节点。分摊写操作。同时配置了从节点为了主节点的故障转移。
过期键的删除策略
1.被动删除:访问key时,如果已经过期将其删除。
2.主动清理:定时去检测数据,如果发现其过期则将其删除
3.内存不够时清理:当到达最大内存时将其释放
内存淘汰策略有哪些
最近少使用,任意删除,进制删除。从过期时间随机选择,从过期时间选择快要过期的。
MySQL 与 Redis 如何保证数据一致性
主要探讨更新数据库和更新缓存之间的顺序问题
解决的方法有4种。
1.删缓存再更新数据库
导致了缓存的数据白删,不是最新的数据
2.先更新数据库,再让缓存失效
3.更新缓存然后同步更新数据库
保证了缓存始终有
4.更新缓存然后异步更新数据库
3和4的方法,当redis宕机时会导致数据失效。
缓存常见问题
1.缓存击穿:访问存在值,但那个值失效了。而导致多个请求到数据库
解决:设置逻辑过期时间,加互斥锁
2.缓存穿透:访问不存在的值
解决:设置null值,设置布隆过滤器
3.缓存雪崩:因为设置了相同的过期时间,同一时间失效带来了巨大的压力,而导致请求全去访问了数据库。
解决:设计随机的ttl。设置二级缓存
4.缓存预热:为了防止刚启动时,需要去访问数据库再更新缓存。导致的压力
解决:1.手动写一个接口更新缓存然后上线去访问。2.在数据量小的情况下,在启动时加载数据到缓存中。3.定期更新缓存数据
5.缓存降级:在缓存出现问题,如网络波动,容量不足时,为了让系统不崩溃,不去使用缓存的策略。
像查询信息可以直接返回错误信息或者一些默认值,来保证西的可靠性。
Redis 怎么实现消息队列
1.list:使用lpop非阻塞的去监听队列的信息
2.pub/sub主题订阅模式:
Redis 怎么实现延时队列
使用sortedset,拿时间戳作为score,消息内容作为key,调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理
pipeline的作用
redis处理命令的流程:发生,等待,执行,返回。是一条一条的执行,使用pipline可以将数据分批的去操作。这样执行的速度比逐条的执行快。
mset和mget
LUA脚本
1.可以保证全部执行完全,中途不会离开去执行其他事件。
2.可以一次性将数据发送到redis。减少了网络的开销
什么是RedLock?
Redis大key怎么处理
表示这个键储存的值很大,则这个键就是一个大key
数据库分片就是将数据根据一定的规则分配到不同的地方,如将主键值进行hash再取余然后决定它存在的区域,
Redis常见性能问题和解决方案
1,master最好不要设置持久化操作,因为master的压力比较大,如果再设置了持久化的操作会导致宕机。
2.如果数据比较重要,可以设置aof的每秒去持久化数据
3.为了保证slave和master的稳定,他们应该在同一个局域网中
4.为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变
5.避免在压力较大的master上新增库
说说为什么Redis过期了为什么内存没释放
1.:覆盖了以前的key,导致了数据更新。
2.惰性删除和定期删除。惰性,当数据过期了也不会主动释放,当下次申请访问的时候发现过期再删除。
3.定期删除是每隔一段时间挑选一部分的数据进行检测,存在部分数据不会被检测到
Redis突然变慢,有哪些原因
1.存在bigkey,淘汰bigkey时会更加消耗内存
2.网络问题,不稳定因素。
3.频繁的短链接,tcp等网络通信也会占据一定的时间。
4.开启了内存大页:进行数据持久化的时候为了不影响期间对持久化的数据造成影响,会将数据复制一份进行储存,然后主进程的操作会再复制的副本上操作-->写时复制
但开启了内存大页,就算修改了一部分数据,也是固定的去申请2mb的内存,会导致浪费。解决:关闭内存大页。
5.内存以及达到上限:这样新添加数据都要执行一次内存清理,会导致空间的浪费。
6.使用了swap:当内存满时,会将一部分数据写入到磁盘中,这样读取这个数据会要去从磁盘中读取。解决:增加机器的内存和制定合理的内存清理策略
为什么 Redis 集群的最大槽数是 16384 个
1.带宽 2.节点少效率高 3. 值越小压缩率高
Redis存在线程安全的问题吗
在服务端中不存在,在客服端中存在。
因为客服端执行多个redis的命令的时候,由于线程的原子性无法保证导致出现线程安全。
Redis遇到哈希冲突怎么办
当2个以上的键发生了哈希冲突,和java类似,采取了链式的方法去处理。
Redis实现分布式锁有哪些方案
1.setnx
2.lua脚本
3.redssion
4.redlock
介绍分布式锁:
保证了在分布式系统中只能对一个共享资源进行操作。
1.互斥 2.超时 3.可重入 4.安全 5.高性能
- setnx配合expire使用,保证了锁会自动过期。
- 缺陷:加锁与设置过期时间是非原子操作,如果加锁后未来得及设置过期时间系统异常等,会导致其他线程永远获取不到锁。
- ETNX+value值(系统时间+过期时间)
将1的2步操作化作一步操作,以逻辑过期时间储存。将时间作为value储存。
- 缺点:要求分布式的每台服务器的时间必须同步,锁没有唯一标识,可能会被其他释放。比如说a和b同时发现了可以设置锁,进入了操作。a设置了锁,但b执行的快,导致b释放了a的锁。或者说执行周期过久导致了锁失效,a上锁锁失效了还没执行完,这时候b上锁,a释放锁将b的锁释放了。--->逻辑过期时间难以确定
- lua脚本+setnx的操作+expire。lua脚本解决了1的原子性。
- setnx+expire是可以一次性完成的