目录
2、redis的持久化方案,如何保证redis中的数据不丢失
1、redis的五大基本数据类型
String:字符串类型的value值,可以占用512M的空间,所以可以存储很多的数据
list:有序的(插入的时候有序),底层是一个双向链表
set:Set的特点是无序不重复的
hash:类似于之前的map
zset:排了序的Set集合
2、redis的持久化方案,如何保证redis中的数据不丢失
一种是RDB方式,一种是AOF的方式,第一种是默认方案。
RDB方案优点
1)、对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。
2)、每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。
3)、使用RDB文件进行数据恢复比使用AOF要快很多
RDB方案缺点
1)、快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。
如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力
AOF优点:
1)、最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据
2)、AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。
3)、AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。
AOF的缺点:
1)、AOF文件通常比RDB文件更大
2)、性能消耗比RDB高
3)、数据恢复速度比RDB慢
描述一下:
aof 将用户的操作记录下来,用户操作一次就记录一次吗?不一定,看另一个配置:appendfsync
Redis的数据持久化工作本身就会带来延迟,需要根据数据的安全级别和性能要求制定合理的持久化策略:
AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响
AOF + fsync every second是比较好的折中方案,每秒fsync一次
AOF + fsync never(no) 会提供AOF持久化方案下的最优性能使用RDB持久化(保存数据交给了操作系统,不可控)。
3、什么是redis的哨兵模式?
主从模式下,master节点挂掉以后,从节点自动升级为主节点。
4、你们公司使用什么技术操作redis?
Redis命令行客户端
5、redis中的热门问题以及解决方案
1)、缓存穿透
用户一直查找一个mysql中压根不存在的数据,一直查,查不到redis就不缓存,mysql的压力巨大,最后导致崩溃,黑客就是利用这一点进行攻击的。
解决方案一:用户访问一个key值,在redis中不存在,先去数据库查询一圈,发现没有查找到,将这个空值也放入到redis缓存中,下一次再有人访问这个数据,直接返回null.缺点是假如将来这个key值在数据库中有数据了,用户会访问不到,解决方案就是redis给这样的key值加过期时间,以及后台再上架某些新的产品的时候,可以去redis中查找一圈,假如有这个数据,删除该key即可。
解决方案二:布隆过滤器其实就是一块内存区域,本质就是一个数组,数组中只有0和1。先将mysql中的商品id全部导入到布隆过滤器中,假如有一个人需要访问redis或者数据库,我先将这个商品id跟布隆过滤器中的数据对比一下(因为速度快),如果没有,直接返回null即可。如果有,再次访问redis或者mysql即可。
2)、缓存雪崩(不止一片雪花)
不太热门的key值,在同一时间,集体失效了。导致mysql的压力瞬间增大,mysql崩了。针对的是多个key值。
解决方案一:redis中的key值,设置不同的过期时间,假如是批量设置,可以编写一个随机函数,让其在1~5分钟过期即可。
解决方案二:添加多级缓存:nginx缓存 + redis缓存 +其他缓存(ehcache等)
解决方案三:还可以使用锁或者队列的方式。
3)、缓存击穿
不太热门的key值,在同一时间,集体失效了。导致mysql的压力瞬间增大,mysql崩了。针对的是多个key值。
解决方案一:预先设置热门数据,在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的时长
解决方案二:实时调整,现场监控哪些数据热门,实时调整key的过期时长(Apache Druid不是德鲁伊)
解决方案三:使用锁,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db。
6.Redis中的数据存储算法是什么,为何这样设计?
哈希函数:当客户端向Redis发送一个键时,Redis会使用哈希函数将键映射到特定的槽位上。Redis默认使用CRC16算法来计算哈希值,并将其映射到0-16383号槽位中。
数据分片:为了支持高并发和大规模存储,Redis采用了数据分片(sharding)的方式。根据哈希函数计算出的槽位号,Redis将数据平均分配给不同的节点,每个节点负责管理一部分槽位的数据。
Redis中的数据存储算法是基于键值对的。
主要有以下几个原因:
1)、简单高效:基于键值对的存储方式非常简单且易于理解,同时在处理大量数据时也非常高效。通过将键与值关联起来,可以快速地进行数据存储和检索操作。
2)、灵活性:Redis支持多种不同类型的值,如字符串、列表、哈希表、集合和有序集合等。基于键值对的存储方式可以灵活地适应各种数据类型的存储需求。
3)、快速的查找和访问:Redis使用了一种高效的哈希表实现来存储键值对。哈希表通过计算键的哈希值将键映射到槽位,并在槽位上进行链表或跳表的操作。这样可以快速定位到对应的位置并进行数据查找和访问。
4)、内存优化:为了降低内存占用,Redis还对数据存储进行了优化。例如,对于小型字符串和列表值,采用了紧凑的ziplist结构;而对于其他类型的较大值,则使用hashtable结构。此外,Redis还提供了压缩字典的功能,进一步减少内存占用。
5)、支持事务和持久化:基于键值对的存储方式使得Redis可以方便地支持事务和持久化。通过使用多个命令操作相关的键,可以将这些命令组合成一个事务进行原子性执行。同时,Redis还支持将数据持久化到磁盘上,以确保数据在重启后的恢复。