1.redis中的数据类型
Redis支持五种数据类型:string(字符串)、hash(哈希)、list(列表)、set(集合)、sorted set(有序集合)。
2.redis中的缓存雪崩,击穿,穿透问题
在理解这三个问题之前,先要了解redis的缓存处理机制,在收到用户的请求后,判断缓存中是否有数据,有就返回数据,没有就去查询数据库,如果数据库有数据,就返回数据,并且将该数据存入缓存中。
雪崩:用户发送大量请求时,redis中的key值由于过期失效,导致请求发送到数据库中,导致数据库挂掉。
雪崩解决方法:
(1)设置key值过期时间为随机数,这样不同的key值过期时间不同,可以避免key值同时挂掉引发的雪崩。
setRedis(Key,value,time + Math.random() * 10000 //random为设置随机数的方法
(2)不设置key的过期时间,key值不会过期,也就不会造成雪崩,不过会对内存带来很大的负担。
击穿:和雪崩相似,都是大量请求,key值过期,导致数据库挂掉,但不同的是,击穿就像一根针穿透一张纸一样,是单独对一个key的大量请求,当这个key过期时,请求就会都打到数据库上导致的,这种承载了大量请求的key值叫做热点key。
击穿解决方法:
(1)添加互斥锁,在第一个请求去查询的时候,等改请求查出数据并放入缓存后解锁,这样就避免了查询数据库。
(2)不设置key过期时间也同样有效。
穿透:请求大量的缓存中没有的数据并且数据库也没有的数据,这样的请求会全部打到数据库中,请求量过大就会导致数据库挂掉。
传统解决方法:
(1)对于这种不存在的数据也加到缓存中,key和value都设置为null,过期时间设置短点,不要超过五分钟。
(2)布隆过滤器,将所有可以存在的数据放到这个过滤器中,不存在的数据都会被过滤掉
(3)添加参数校验,不合法的就返回。
3.为什么要用redis,redis为什么这么快
(1)redis是一个内存数据库,所以要比非内存的数据库要快很多
(2)内存数据库也有很多,是什么让redis一枝独秀呢,先看一下redis的线程模型
可以看出来,redis是单线程的,socket事件进来后,redis用了一个io多路复用程序接受,这个程序将多个事件压到事件队列中,有序的交给文件事件分派器处理,然后分派器感觉事件的类型调用相应的处理器去处理。
io多路复用:通过socket事件驱动的连接进程,io多路复用程序会对socket进行监听,有事件时就会处理。
事件处理器分为以下几种
连接应答处理器:用于处理客户端的连接请求
命令请求处理器:用于执行客户端传递过来的命令
命令回复处理器:用于返回客户端命令的执行结果
这就是redis快的原因,总结一下:
-
基于内存的数据处理
-
使用io多路复用技术
-
单线程的模型避免了多线程频繁的上下文切换
4.redis持久化
redis的持久化有两种方式
(1)RDB:每隔一段时间对redis中的数据进行持久化。优点:速度快,缺点:数据完整性较低
(2)AOF:已日志的方式存储每条写入命令,将该日志文件作为持久化的数据来源。优点:数据完整性高,缺点:支持写的请求性能会比RDB模式的低
如何选择这两种方法:建议RDB和AOF同时开启
5.redis集群
(1)读写分离
当事务多到同时读取数据和写入数据难以承受时,可以通过集群的方式实现读写分离,redis的读写分离由一个主节点master(负责写入),一个或多个根节点slave(负责读取)组成,工作机制如下图所示
当启动slave后,slave会给redis发送sync命令(同步命令),master接收到后就会先生成RDB快照,同时吧生成快照的这段时间的请求记录,完成后一起发给slave,之后再有请求master就会直接发给slave,这样就保证了数据一致性。
(2)哨兵模式(sentinel)
哨兵模式用来监控和调整redis集群,主要功能就是当主节点master挂掉后,不至于让整个集群挂掉,而是从跟节点中选举出新的master
需要注意的是,为了保证哨兵模式的健壮性,一般需要三个哨兵来监控集群,因为如果只有两个哨兵的话,如果一个节点挂掉了,那么剩下的一个哨兵是无法完成主从切换的。
(3)cluster集群
虽然哨兵模式的集群可以很大程度上提高了集群的稳定性,但却有难以扩容的缺点,并且以为集群中只有一个主节点,当写操作并发量特别大的时候,难以缓解写操作的压力,所以在3.0版本后推出了面向分布式的cluster集群
cluster采用无中心结构,每个节点保存各自的数据和整个集群的状态,每个节点都和其他所有节点连接,客户端连接任意主节点可以对整个集群中数据进行读写,同时,cluster还集成了sentinel的功能,保证了稳定性。
分布式储存方式:使用哈希槽的模式,cluster集群有16384个哈希槽(hash slot)可以分配指定个数的槽给指定的节点,每个Key通过CRC16校验后对16384取模来决定放置哪一个槽。当存取redis key时候,redis会根据CRC16算法得到一个结果,然后把结果和16384求余,通过这个值去对应得节点获取数据。这个时候,应用客户端实际上只需要连接其中任意一个节点即可,然后Redis Cluster 中每个节点都保存了其他节点得槽信息。这样当存取key计算完槽之后,通过保存槽信息从配置中获取节点信息,然后再去对应得节点获取数据。