一、概述
1.什么是Redis
Redis
是一个非关系型数据库,数据存储在内存中,因此操作速度非常快,通常用来存储服务器的缓存数据。
2.为什么要用Redis
传统数据库查询速度因为有读取磁盘的瓶颈,因此无法支持过大流量的查询,将数据放在内存中,就可以避免磁盘的读写,以支持超大流量的查询。而Redis
就是这么一个缓存数据库。
3.Redis怎么样
Redis
是目前最主流的缓存数据库,除了提供缓存数据的支持外,还因为其单线程、全局唯一、高速读写等特性,可以实现如分布式锁、布隆过滤器、计数器、消息队列等更多实用功能。
二、Redis的数据类型
1.Redis支持的数据类型
1.String
字符串类型, 是平常使用最多的类型,用来存储各种字符串,也可以将整形、浮点型数据作为字符串存储,如果是整形或浮点型,还可以在Redis中做简单的加减运算。
2.Hash
散列类型,用来存储field-value(键值对) 形式的映射表,相当于一次存储了一个Map。
3.List
列表类型,相当于一个双向链表,可以往两头插入数据和获取数据,可以用来实现Redis版的消息队列。
4.Set
无序集合,类似于Java中的HashSet,可以往集合中插入数据,但没有顺序,同时具有唯一性。
5.Zset
有序集合,在无序集合的基础上增加了一个下标,插入数据时同时插入下标,使用下标进行排序。
6.Bitmap
位图 Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 Bitmap 本身会极大的节省储存空间。
7.Geospatial
地理位置,主要用于存储地理位置信息,基于 Sorted Set 实现。
通过 GEO 我们可以轻松实现两个位置距离的计算、获取指定位置附近的元素等功能。
8.HyperLogLog
HyperLogLog 是一种有名的基数计数概率算法 ,基于 LogLog Counting(LLC)优化改进得来,并不是 Redis 特有的,Redis 只是实现了这个算法并提供了一些开箱即用的 API。主要用于大数量的计数统计。
三、持久化方法
1.RDB持久化
RDB持久化是Redis
的默认持久化功能
SAVE命令 阻塞服务器,创建RDB文件
BGSAVE命令 启动子进程创建RDB文件
RDB持久化是通过时间点快照的方式持久化数据,简而言之就是只会保存执行持久化命令时间点的所有数据,执行命令后创建的数据不会保存到RDB文件中。
2.AOF持久化
与全量式RDB持久化不同,AOF提供的是增量式的持久化功能,这种持久化原理在于,服务器每次执行完写命令后,都会将以协议文本的方式将命令记录到AOF文件的末尾,服务器停机后,通过重新执行AOF文件中的命令,恢复之前的数据。
AOF的优缺点
1.AOF文件的体积比RDB文件大得多
2.AOF文件做数据恢复比RDB文件慢得多
3.进行AOF文件重写会占用大量资源,导致服务器短暂阻塞
3.RDB-AOF混合持久化
Redis4.0之后引入RDB-AOF混合持久化,
将aof-use-rdb-preamble
选项设置成yes后
Redis执行AOF重写操作时,首先会将当前数据库状态按RDB持久化方式将数据写入AOF文件中,至于持久化开始后的数据,则以AOF持久化的方式,将命令追加到AOF文件末尾。
换句话说,服务器生成的AOF文件将由两部分组成,开头是RDB文件格式,结尾是AOF格式的数据。
四、缓存击穿、雪崩等场景分析
1.缓存穿透
当大量并发请求去查询一个Redis
不存在,且数据库中不存在的数据时,大量请求透过了Redis
直接访问数据库,导致服务器宕机。
解决方案:
查询到空数据时,依然将空数据保存到Redis
中,保证请求不会直接到达数据库。当该数据新增时,删除Redis
空数据。保证读取Redis
不发生脏读现象。
2.缓存击穿
当缓存数据有过期时间时,如果过期时间刚过,此时有大量并发请求进来查询这个数据时,虽然查完数据库后会更新缓存,但依旧会有大量请求去查询数据库。此时可能因并发过高导致服务器宕机
解决方案:
可以通过分布式锁,发现数据不在Redis
,去查询数据库时加上分布式锁,保证只有一个请求去查询数据库。未获取到锁则重试Redis获取数据。大幅降低了数据库层的压力。
3.缓存雪崩
大量缓存数据设置了相同的过期时间,导致数据同时过期时,数据库请求激增,导致服务器宕机。
解决方案:
避免大量缓存数据使用相同的过期时间,通过使用随机数的方式,保证数据不在同一时间点失效。
4.缓存预热
提前将热点数据加载到Redis,降低数据库的压力,注意不要使用相同的过期时间,防止缓存雪崩。
五、Redis 内存淘汰策略
Redis
内存淘汰策略是在Redis
内存使用达到限制时,为了释放内存空间而采取的一系列策略。
Redis
提供 8 种数据淘汰策略
1.noeviction(默认策略)
Redis
默认不会淘汰数据,当内存使用达到限制时,新的写入操作会报错。
2.volatile-lru(最近最少使用)
从设置了过期时间的键中,使用 LRU(Least Recently Used,最近最少使用)算法淘汰数据。
3.volatile-ttl
从设置了过期时间的键中,优先淘汰剩余生存时间(TTL,Time To Live)较短的键。
4.volatile-random:
从设置了过期时间的键中,随机淘汰数据。
5.volatile-lfu:
从已设置过期时间的数据集中挑选最不经常使用的数据淘汰。
6.allkeys-lru:
从所有键中,使用 LRU(Least Recently Used,最近最少使用)算法淘汰数据。
7.allkeys-random:
从所有键中,随机淘汰数据
8.allkeys-lfu:
从所有键中,移除最不经常使用的 key
。