近期准备讲解Redis,肚子里没点料怎么能行,遂找点资料充实充实自己,听说这本书还是非常不错的!
一、初识Redis
Redis是一种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是,Redis中的值可以是由string(字符串)
、hash(哈希)
、 list(列表)
、set(集合)
、zset(有序集合)
、Bitmaps(位图)
、 HyperLogLog
、GEO(地理信息定位)
等多种数据结构和算法组成,因此 Redis可以满足很多的应用场景,而且因为Redis会将所有数据都存放在内存中,所以它的读写性能非常惊人。不仅如此,Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”。除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。
特性:
- 速度快:读写性能10万/秒
- 基于键值对的数据结构服务器。
- 丰富的功能:(1)提供了键过期功能,可以用来实现缓存;(2)提供了发布订阅功能,可以用来实现消息系统;(3)支持Lua脚本功能,可以用Lua创造出新的Redis命令;(4)提供了简单的事务功能;(5)提供了流水线功能
- 简单稳定:源码少,单线程
- 客户端语言多
- 持久化:RDB和AOF
- 主从复制
- 高可用和分布式:哨兵(Sentinel)模式
启动redis的三种方式:
$ redis-sever
$ redis-server --configKey1 configValue1 --configKey2 configValue2
$ redis-server /opt/redis/redis.conf
关闭redis
$ redis-cli shutdown
关闭的过程:断开与客户端的连接、持久化文件生成,是一种相对优雅的关闭方式
二、API的理解和使用
为什么单线程还能这么快?
- 纯内存访问
- 非阻塞I/O:Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间
- 单线程避免了线程切换和竞态产生的消耗
Redis数据结构
字符串
字符串是Redis最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。
setnx
可以作为分布式锁的一种实现方案
字符串比较典型的使用场景:
- 缓存功能,其中Redis作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用
- 许多应用也会使用Redis作为计数的基础工具
- 共享Session
- 限速
哈希
列表
列表(list)类型是用来存储多个有序的字符串,一个列表最多可以存储 2 32 − 1 2^{32} - 1 232−1个元素。在Redis中,可以对列表两端插入和弹出,还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。
使用场景:
- 消息队列,通过Redis的lpush和brpop命令组合即可实现阻塞队列
- 文章列表
lpush + lpop = Stack(栈)
lpush + rpop = Queue(队列)
lpush + ltrim = Capped Collection(有限集合)
lpush + brpop = Message Queue(消息队列)
集合
集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。一个集合最多可以存储 2 32 − 1 2^{32}-1 232−1个元素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多实际问题。
集合类型比较典型的使用场景是标签(Tag)
有序集合
集合+score
$ zrank key member
:计算成员排名
使用场景:排行榜系统
键管理
Redis从2.8版本后,提供了一个新的命令scan,它能有效的解决keys命令存在的问题。和keys命令执行时遍历所有键不同,scan采用渐进式遍历的方式来解决keys命令可能带来的阻塞问题。
三、小功能大用处
慢查询分析
所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阈值,就将这条命令的相关信息(例如:发生时间,耗时,命令的详细信息)记录下来,Redis也提供了类似的功能。