基础数据类型
String
计数器
通过incrc
, decrc
和 incrcby
指令控制数字变化。通过计数和过期机制,可以限制用户的访问频率,达到限流的目的。
共享Session
同一个用户多次登录时,可能被不同的服务器负载。这时可以通过Redis的String数据类型保存分布式服务器共享的Session。
Hash
存储对象类型数据
比如MySQL的一行数据,里面的列名可以用Hash的key记录
hmset album:2 name LANY pub_year 2017
List
查询列表
List类型不仅支持双向插入,同时还可以通过索引查询数据。
Set
用户标签
由于Set支持集合的各类操作,可以聚类用户的操作,通过标签提高用户黏度
Zset
排行榜
根据score对数据做排序,是Zset最典型的应用场景
Bitmap
大数据量的统计
由于是通过位信息记录,Bitmap能够节省更多的内存空间,因此很适合记录大数据统计信息,例如活跃用户数等。
基于数据结构的过滤算法
下面两种并非是数据结构,而是在Redis中通过数据结构实现的算法。
布隆过滤器
建立黑名单
当名单较长时,布隆过滤器能以较小的失误率识别黑名单(会错杀,但不会漏判)
防止缓存穿透
当Redis作为其他数据库的缓存时,可以用布隆过滤器判断数据请求是否为一个合理的范围,防止恶意请求
HyperLogLog
去重计数,误差0.81%
HyperLogLog是通过哈希数据为64位,压缩数据的同时保证数据分布均匀。然后取前50位数据,做统计并记录。统计的方式可以为:记录连续为0的序列的最大长度。
在需要计数时,会分别从后14位索引的数据桶中取调和平均值(harmoic mean),再根据概率反推出数据量的大小。
这种方式能极大减少存储空间,尤其适合海量数据的统计。
持久化方式
- RDB(Redis DB)
将数据库全量保存为一个快照文件dump.rdb
- 通过指令手动触发
save
,bgsave
命令,其中bgsave会fork一个子进程,不会阻塞Reids响应客户端的请求(save命令实际中不会被用到)
- 自动触发保存
使用shut down
命令时,Redis会自动保存当前数据,再关闭数据库
根据配置文件,n秒触发了m次写操作后,会自动进行一次保存(配置文件中可以配多个保存频率)
主从复制时,会生成RDB文件用于迁移数据
如果在保存过程中,主进程在写一个数据,Reids会利用写时复制操作(copy on write)
- AOF(Append Only File)
记录每一条写操作,按记录执行操作以恢复数据
AOF流程如图。为了保证不阻塞主流程,Fsync由子线程完成,重写操作由子进程完成。
重写是指当AOF文件超过配置大小或百分比时,Redis会自动对里面记录进程优化(包括合并操作记录,直接用内存数据记录)。
耗时操作
- Rehash
Redis本质上是在内存上的一张大的哈希表,出现哈希碰撞后,会通过链表在同一个索引上不断追加数据。当链表长度过长时,就需要开辟新的空间,把原来的索引迁移过去。
这个Rehash的过程时相当耗时的,Redis通过“渐进式Rehash”,把迁移过程分解到每一次操作执行中(每执行一个操作,就迁移一个索引),做了一个平均化的过程。
- Rewrite
重写过程中,子进程和父进程需要共享同一片内存区域。当Redis数据量过大时,复制内存页签耗时明显,会阻塞主进程一段时间;这种情况在开启子进程写RDB文件时同样会发生。
所以尽量控制Redis内数据key的大小,一般在百万级就差不多。