Java笔记 | Redis
- Redis 基础数据类型
String:最基本的数据类型,二进制安全。可以是字符串或数字,一般做一些复杂的计数功能的缓存。最大512m。指令set、get、incr。
Hash(Hashes):由String元素组成的字典,适合用于存储对象。内部可以用 hashtable 和 ziplist 两种承载方式来实现。指令hmset、hget、hset。
List:列表,按String元素的插入顺序排序。可以做简单的消息队列的功能,比如论坛点赞人列表、微博粉丝列表等;另外还可以利用 lrange 命令,可以从某个元素开始读取多少个元素,实现简单的高性能分页,类似微博那种下拉不断分页的东西,性能极佳,用户体验好。指令lpush、lrange。
Set:由String元素组成的无序集合,不允许重复,通过哈希表实现。可以做全局去重的功能,比如说是否给帖子点赞数;也可以判断某个元素是否在 Set,比如说判断是否给某个回复点赞。另外还可以利用交集、并集、差集等操作来支撑更多的业务场景,比如说找出两个微博 ID 的共同好友等。指令sadd、smembers。
Zset(Sorted Set):相比 set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行排序。比如说可以用于取排行榜 top N 的用户。指令zrangebyscore。
bitmap:本质是String,最多存储2^32个bit。
GEO:本质是Zset,用GeoHash进行填充,存储地理坐标。
stream
- Redis 优势
- 首先 Redis 支持丰富的数据结构,新版本数据结构从最初的5种变成9种。
- 其次 Redis 是读写单进程单线程,不用考虑并发读写的复杂场景,速度也快。
- Reids 功能完备,支持数据持久化,支持主从复制和集群。
- 还有Lua脚本,事务,发布订阅模型,Reids 都支持。
缓存可以把系统响应能力提高N个数量级,减少数据传输时间,提高处理效率,这就是缓存的意义。
- Redis 单线程优势
- 单线程不代表一定就慢,单线程有一个最大好处就是节省线程切换的开销,更不用考虑并发读写带来的复杂操作场景,这就大大节省了线程间切换的时间了。
- 单线程模型避免了多线程的频繁上下文切换,这也避免了多线程可能产生的竞争问题。
- Reids 是基于内存的读写操作,内存肯定比传统磁盘IO数据库快。
- Reids 核心是基于非阻塞的IO多路复用机制。
Redis 6.0采用多个IO线程来处理网络请求,网络请求的解析可以由其他线程完成,然后把解析后的请求交由主线程进行实际的内存读写。提升网络请求处理的并行度,进而提升整体性能。
但是,Redis 的多 IO 线程只是用来处理网络请求的,对于读写命令,Redis 仍然使用单线程来处理。
- Redis 过期策略
--定期删除策略。用一个定时器来负责检查 key,过期则删除 key,注意这里并不是检查所有的 key 而是随机抽取进行检查。定期策略虽然让内存及时释放,但也会额外消耗 CPU 资源,通常 CPU 应该将时间尽量用于处理业务请求,而不是删除 key。
--惰性删除策略。在你获取某个 key 的时候,redis 会检查一下,这个 key 如果设置了过期时间那么是否过期了,如果过期则删除该 key。
- Redis 内存淘汰机制
如果定期删除没删除 key,然后也没及时去请求 key,即惰性删除也没生效,持续下去 redis 的内存会越来越高,当超过 redis 设置的内存最大使用量时,就会进行内存数据淘汰。redis 有 6 种淘汰策略:
-- volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
-- volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
-- volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
-- allkeys-lru:从所有数据集中挑选最近最少使用的数据淘汰。
-- allkeys-random:从所有数据集中任意选择数据进行淘汰。
-- noeviction:当内存不足以容纳新写入数据时,新写入操作会报错(即不淘汰)。很少使用。
前缀 volatile 和 allkeys 用于区分淘汰数据的数据集是从已设置过期时间的数据集还是从全部数据集中选取,后面的 lru、ttl 以及 random 是三种不同的淘汰策略,再加上一种 no-enviction 永不回收的策略。其中最常使用的是 volatile-lru/allkeys-lru。
- Redis 持久化方式
redis 提供两种持久化方式。
-- RDB(Redis DataBase),用数据集快照的方式,定时将 redis 存储的数据生成快照并存储到磁盘等介质上。
RDB优点:
1.特别适合备份;
2.性能最大化,fork 子进程来完成写操作,让主进程继续处理命令且不会进行任何 IO 操作的,这样就确保了 redis 极高的性能;
3.相对于数据集大时,比 AOF 的启动效率更高。
RDB缺点:
数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发 生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候;
-- AOF(Append-only file),是指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储) 保存为 aof 文件。
AOF优点:
1.数据安全,aof 持久化可以配置 append fsync 属性,比如无 fsync,每秒钟一次 fsync,或者每次执行写入命令时 fsync,一般只会丢失一秒钟的数据,或者最后一次执行的数据,对缓存来说,这已经足够。
2.某些场景下还可以恢复数据。比如说某同学在操作 redis 时,不小心执行了 FLUSHALL,导致 redis 内存中的数据全部被清空了。如果 AOF 文件还没有被重写(rewrite),我们就可以用最快的速度暂停 redis 并编辑 AOF 文件,将最后一行的 FLUSHALL 命令删除,然后重启 redis,就可以恢复 redis 的所有数据到 FLUSHALL 之前的状态了。
AOF缺点:
1.AOF 文件比 RDB 文件大,且根据不同的 fsync 策略,其恢复速度可能较慢;
2.数据集大的时候,比 RDB 启动效率低。