这是我参与「第五届青训营 」伴学笔记创作活动的第5天
Redis可以用来做什么
-
- 缓存
-
- 排行榜系统
-
- 计数器应用(如统计文章阅读次数)
-
- 社交网络(踩,赞、共同好友等)
-
- 消息队列系统(利用list结构的lpush()和rbpop()可以很容易的实现一个消息队列)
Redis的8个特性:速度快、基于键值对的数据结构服务器、功能丰富、简单稳定、客户端语言多、持久化、主从复制、支持高可用和分布式。
数据结构和内存编码
可以通过type命令查看当前键的数据类型,Redis支持string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合),但这些只是Redis对外的数据结构。实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合适的内部编码。
Redis3.2提供了quicklist,结合了ziplist和linkedlist两者,的优势,为列表类型提供了一种更为优秀的内部编码实现。
单线程架构
Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务
Redis是单线程来处理命令的,所以一条命令从客户端达到服务端不会立刻被执行,所有命令都会进入一个队列中,然后逐个被执行。所以客户端命令的执行顺序是不确定的(如图2-4所示),但是可以确定不会有两条命令被同时执行。不会产生并发问题,这就是Redis单线程的基本模型。但是像发送命令、返回结果、命令排队肯定不像描述的这么简单,Redis使用了I/O多路复用技术来解决I/O的问题。
为什么Redis使用单线程速度还这么快
- 第一,纯内存访问,Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的重要基础。
- 第二,非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间
- 第三,单线程避免了线程切换和竞态产生的消耗。
但是单线程会有一个问题:对于每个命令的执行时间是有要求的。如果某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性能的服务来说是致命的,所以Redis是面向快速执行场景的数据库。
字符串
键都是字符串类型,而且其他几种数据结构都是在字符串类型基础上构建的。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。
典型使用场景
- 缓存功能
- Redis作为缓存层,MySQL作为存储层,绝大部分请求的热点数据都从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。
- 计数
- 使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。视频播放数系统可以使用Redis作为视频播放数计数的基础组件,用户每播放一次视频,相应的视频播放数就会自增1
- 共享session
- 一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自服务器中,这样会造成一个问题,出于负载均衡的考虑,分布式服务会将用户的访问均衡到不同服务器上,用户刷新一次访问可能会发现需要重新登录,这个问题是用户无法容忍的。为了解决这个问题,可以使用Redis将用户的Session进行集中管理,在这种模式下只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。
- 限速
- 很多应用出于安全的考虑,会在每次进行登录时,让用户输入手机验证码,从而确定是否是用户本人。但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次。此功能可以使用Redis来实现,利用Redis可以设置键过期的功能,在用户首次访问时为其新建一个带有过期时间的key(如60秒),在这个key过期之前,都不允许用户再次申请短信验证码。