一、Redis 是什么
Redis 是内存型数据库,相比关系型数据库(比如是 MySQL)更快,由 C 开发。使用了单线程架构和 I/O 多路复用实现高性能的内存数据库服务。
Redis 相比 Memcached 很大优势就是支持多种类型,目前支持的类型有:字符串、哈希、列表、集合、有序集合。
二、Redis 特性
1、速度快
- Redis 是基于内存的数据库,避免磁盘 I/O,数据都存储在内存
- Redis 是 C 语言开发,所以执行效率高、稳定性高、兼容性好、依赖性低
- 使用单线程架构,避免上下文切换和不必要进程之间的资源竞争
2、支持多种数据类型
支持 5 种数据类型:字符串、哈希、列表、集合、有序集合,在字符串基础上延伸出位图(Bitmaps)和 HyperLogLog
3、提供了丰富的功能
- 提供键过期功能,可用于实现缓存
- 提供发布订阅功能,可用于实现消息系统
- 支持 Lua 脚本,可以 Lua 创造新的 Redis 命令
- 提供简单的事务功能,保证一定程度上的事务特性
- 提供流水线(Pipeline)功能减少网络开销,因为客户端能一次性传递一批命令到 Redis
4、支持主流编程语言:C, C++, C#, Java, PHP, Go, Python, Node.js 等。
5、Redis 提供 RDB 和 AOF 策略将数据保存到磁盘中,确保断电或机械故障时重要数据不丢失。
6、主从复制:能过复制多个相同数据的 Redis 副本,复制功能是分布式 Redis 的基础。
7、Redis 2.8 版本提供了高可用实现 Redis Sentinel,它能确保 Redis 节点故障的发现和自动转移。Redis3.0 版本提供了分布式实现 Redis Cluster,提供了高可用、读写和容量的扩展性。
三、Redis 常用的应用场景
1、缓存
Redis 提供了键值过期时间设置、灵活控制最大内存和内存溢出后淘汰策略。合理的缓存能加快数据的访问速度,降低后端的压力。
2、排行榜
排行榜是非常常见的功能,根据列表类型、有序集合类型的数据结构特点能构建各种各样的排行榜。
3、计数功能
视频播放数量、商品浏览量的增加,每次播放或浏览都需要做 +1 的实时处理,如果并发量很大对于关系型的数据库来说性能是个挑战,但对于 Redis 来说非常适合。
4、社交网络
社交网络上赞、粉丝、共同好友、推送、下拉刷新这类数据关系型数据库也是不好处理,对于 Redis 来说效果是好的。
5、消息队列系统
Redis 提供的发布订阅功能和阻塞队列的功能对于一般消息队列的功能基本满足。
四、Redis 5 种数据结构的特点以及使用场景
1、字符串
字符串是最基本的数据结构,其他数据结构都是在它基础上搭建的。键都是字符串类型,而字符串类型的值可以是字符串(例如 JSON、XML 等)、数字(整数、浮点数)、二进制(图片、音频、视频),但值最大不能超过 512MB
应用场景
-
缓存
Redis 作为缓存层,绝大多数请求从 Redis 获取,缓存能加速读写和降低服务器压力的作用。
-
计数
Redis 能实现快速计数、查询缓存的功能,数据也能异步发送给其它数据源。
-
共享 Session
分布式 Web 服务会将 Session(如用户登录信息)保存在各自的服务器,出于负载均衡的考虑,分布式服务会将用户的访问均衡到不同的服务器,这就会导致每当用户刷新后需要重新登录… 所以 Session 信息需要交给 Redis 集中管理,每次查询用户信息时从 Redis 获取。
-
限制操作频率
为了避免用户获取手机验证码过于频繁,可以限制用户每分钟获取频率,如果每 30 秒只能获取 1 次。
2、哈希
几乎所有编程语言都支持哈希(hash)类型,除了叫哈希,也有其它叫法:字典、关联数组。
在 Redis 中,哈希除了指的是键值,也指是一个键值对结构:value={{field1, value2}, …, {{field N, value N}}},映射关系是 field-value, value 是指 field 的值,而不是键的值。
应用场景:缓存
相比字符串缓存,使用哈希缓存更简单直观,合理使用能节省不少内存空间。
例如要缓存某个用户信息只需要 1 个键就能保存,可以使用用户 id 作为键值后缀存储,每个信息属性使用一对 field-value
hmset user:1 name Gnahz age 23 city Guangzhou
复制代码
3、列表
列表是用于存储多个有序的字符串,列表中的每个字符串称为元素(element),元素排列顺序是有序的,而且可以是重复的。
Redis 可对列表两端插入(push)和弹出(pop),也可获取某一个范围的所有元素或指定元素。
应用场景
- 消息队列
- 文章列表
4、集合
集合也是用于存储多个有序的字符串,但元素排列顺序是无序的,而且不可以重复,不能通过索引下标获取元素。
应用场景
- 给用户打上标签,如体育迷标签、标记喜欢哪个歌手、哪种类型的歌等
- 生成随机数,如抽奖
5、有序集合
有序集合和集合一样不能有重复的元素,但元素是可以排序的,它排序的依据是设置一个分数(score),这与列表有些区别。
元素虽说不能重复,但 score 可以重复,就如考试时考号不能重复,但成绩可以的。
五、数据结构间的特点对比
三者的异同点 | 是否允许重复元素 | 是否有序 | 有序实现方法 | 应用场景 |
---|---|---|---|---|
列表 | 是 | 是 | 索引下标 | 时间轴、消息队列等 |
集合 | 否 | 否 | 无 | 标签 |
有序集合 | 否 | 是 | 分值 | 排行榜、社交 |
缓存实现对比 | 优点 | 缺点 | 实例 |
---|---|---|---|
原生字符串:每个属性一个键 | 简单直观,每个属性都能更新 | 因为占用太多键,占用太多内存空间,同时信息内聚性比较差 ,所以一般不会在生产环境使用 | set user:1 name Gnahz |
序列化字符串:将信息序列化后保存在一个键 | 合理使用序列化能提高内存的效率 | 序列化和反序列化操作都需要一定的开销。每次更新属性信息都需要先把全部数据取出反序列化后才能更新,更新后又需要再次序列化数据保存。 | set user:1 serialize(userInfo) |
哈希:每个属性使用一对 field-value,最后用一个键保存 | 合理使用能节省不少内存空间 | 要控制 ziplist 和 hashtable 这两种内部编码的转换,hashtable 会消耗更多内存 | hmset user:1 name Gnahz |