缓存雪崩:是指缓存在同一时间大规模失效,导致后续的所有数据请求都涌向数据库,从而引起数据库的崩溃。
解决方案:
1) 将缓存数据的过期时间设置为随机值
2) 进行缓存预热
3) 使用互斥锁机制(使查询请求按顺序处理)
解决方案:
1)在接口层增加基础的数据校验机制
2)当缓存中无法获取数据时,若数据库中也不存在,则将该数据的key与null值关联并设置较短的缓存时间。
3)采用布隆过滤器,将所有可能存在的数据通过哈希函数映射到一个足够大的位图中,这样对于确定不存在的数据请求可以进行拦截,但需要注意的是,由于哈希冲突的存在,布隆过滤器可能会产生“误判”现象。
解决方案:
1)为热点数据设置永久有效的缓存,避免其过期
2)引入互斥锁机制来协调并发请求
什么是Redis?它主要用来什么的?
Redis,其英文全称为Remote Dictionary Server(远程字典服务),是一个采用ANSI C语言编写的开源项目,它支持网络访问,既可以基于内存操作也可以实现数据的持久化存储。作为一个日志型的Key-Value数据库,Redis提供了多种编程语言的API接口。
与MySQL数据库相比,Redis的一个显著特点是其数据存储在内存中,这使得Redis的读写速度极为迅速,每秒能够轻松处理超过10万次的读写操作。因此,Redis被广泛地用作缓存系统。此外,Redis还常被用于实现分布式锁的功能。除了这些应用,Redis还支持事务处理、数据持久化、LUA脚本执行、基于LRU算法的事件驱动以及多种集群部署方案。
Redis五种基本数据类型
1)String(字符串)
string 类型在 Redis 中是二进制安全的,意味着 Redis 的 string 可以包含任意类型的数据,例如 jpg 图片或者序列化后的对象。
其值的最大存储容量为512MB。
简单使用示例包括:使用 set key value
来存储数据,使用 get key
来检索数据。
incr key
命令可以将对应 key 的 value 值自增 1,如果该 key 不存在,Redis 会自动创建它并将其值初始化为 1。
decr key
命令则可以将对应 key 的 value 值自减 1。
应用场景:共享session、分布式锁,计数器、限流
2)Hash(哈希)
简单使用示例:使用 hset key field value
来设置哈希类型的数据,使用 hget key field
来获取哈希类型中指定字段的值。
内部编码方面,Redis 根据哈希类型的数据量和值的大小来选择编码方式。当哈希类型的元素个数少于 512 个且所有值的大小小于 64 字节时,Redis 会使用 ziplist(压缩列表)编码;否则,Redis 会使用 hashtable(哈希表)编码。
应用场景上,哈希类型非常适合用于缓存用户信息等场景。
在使用时需要注意,如果开发者使用 hgetall
命令来获取大量的哈希元素,可能会导致 Redis 服务器阻塞。为了避免这种情况,可以使用 hscan
命令进行逐步扫描。另外,如果只需要获取哈希中的部分字段,建议使用 hmget
命令来提高效率。
3)List(列表)
Redis 列表是一个简单的字符串集合,用于存储多个有序的字符串元素,这些元素会根据插入的顺序进行排序。你可以选择在列表的头部(左侧)或尾部(右侧)添加新的元素。值得注意的是,一个 Redis 列表最多能够存储 2^32-1 个元素,即大约 4294967295 个元素(超过40亿)。
在实际应用中,你可以通过 lpush key value [value …]
命令向列表的左侧添加元素,使用 lrange key start end
命令来获取列表中指定范围内的元素。
在内部实现上,Redis 会根据列表的大小和元素的值来选择编码方式。具体来说,如果列表中的元素数量少于 512 个,并且每个元素的值都小于 64 字节(这是默认值),Redis 会采用 ziplist(压缩列表)编码;否则,Redis 会使用 linkedlist(链表)编码。
Redis 列表的应用场景非常广泛,例如可以用作消息队列来传递信息,或者作为文章列表来展示一系列有序的内容。
4)set(无序集合)
Redis 的 Set 是一个由 string 类型元素组成的无序集合,它不允许元素重复。Set 集合是通过哈希表来实现的,因此添加、删除和查找操作的复杂度都是 O(1)。
在实际使用中,sadd key element [element …]
命令可以用来将一个或多个 string 元素添加到 key 对应的 Set 集合中。如果添加的元素已经存在于集合中,则返回 0;如果成功添加了新元素,则返回 1。
内部编码方面,Redis 会根据 Set 集合中元素的特点来选择编码方式。如果集合中的元素都是整数,并且元素个数少于 512 个,那么 Redis 会使用 intset(整数集合)编码;否则,Redis 会使用 hashtable(哈希表)编码。
需要注意的是,smembers
命令与 lrange
、hgetall
命令一样,都属于可能会产生较重负载的命令。当集合中的元素数量非常多时,使用这些命令可能会导致 Redis 服务器阻塞。为了避免这种情况,可以使用 sscan
命令来逐步扫描并获取集合中的元素。
5)zset(sorted set:有序集合)
有序集合zset:这是一个已经排序的字符串集合,其中的元素具有唯一性,不允许重复。
与 Redis 的 set 集合类似,zset 集合也是由 string 类型的元素组成,并且不允许成员重复。然而,zset 与 set 的不同之处在于,zset 为每个元素都关联了一个 double 类型的分数。Redis 根据这些分数来对集合中的成员进行从小到大的排序。需要注意的是,虽然 zset 的成员是唯一的,但与之关联的分数(score)却可以是重复的。
在实际使用中,可以通过 zadd key score member [score member …]
命令来向 zset 集合中添加元素,并同时指定每个元素的分数。
底层内部编码方面,Redis 有序集合 zset 可以选择使用 ziplist(压缩列表)或 skiplist(跳跃表)来进行实现。具体的选择依据是:当有序集合中的元素个数少于 128 个,并且每个元素的值都小于 64 字节时,Redis 会采用 ziplist 编码;否则,Redis 会选择使用 skiplist 编码。
在应用场景上,Redis 有序集合 zset 非常适用于实现排行榜功能,以及满足一些社交需求,比如用户点赞等场景。