本文将大略介绍 Redis 的一些个性、应用场景。
个性
- Redis 是始终基于 键值对 的NoSQL 数据库;
- Redis 反对 5 种次要数据结构:string、hash、list、set、zset 以及 bitmaps、hyperLoglog、GEO 等特化的数据结构;
- Redis 是内存数据库,因而它有足够好的读写性能;
- Redis 反对长久化,redis 反对 AOF 和 RDB 两种长久化形式,确保了内存中的数据不会“失落”;
- Redis 的 sentinel 和复制性能保障了 Redis 的高可用;
- Redis 反对 key 维度的数据过期;
-
Redis 反对公布订阅、“事务”、pipeline、Lua 脚本等附加性能。
应用场景
Redis 适宜做什么
- 缓存,Redis 自身是内存数据库,注定有极高的读写速度和吞吐,加上数据过期性能以及欠缺的数据淘汰策略使得 Redis 领有与生俱来的缓存潜质。
- 排行榜零碎,Redis 提供了 zset、list 等简单数据结构,以及极佳的性能,能够做出工夫、数量等各种维度的排行榜零碎。
- 计数器零碎 ,对于视频(音乐)网站的视频播放量、网页浏览量等高频操作,传统的关系型数据库不可能满足需要,Redis 自身晓得
incr
、incrby
等命令很好的反对了这计数性能。 - 社交网络,Redis 反对多种简单数据结构,比方一个用户有本人的粉丝,同时也会关注其他人,这些多能够应用 set 来存储,如果须要有序,能够应用 zset 来存储,这些简单的数据结构传统的关系型数据库并不能很好的反对,同时,因为社交网络网站自身访问量比拟大,传统数据在性能上也是不可能满足的。
- 音讯队列,Redis 提供了音讯队列性能,可能满足个别的音讯队列需要。
-
分布式锁 ,Redis 提供了
SET key value [EX seconds] [PX milliseconds] [NX|XX]
命令,以及 Lua 脚本性能,基于此可能很好的实现分布式锁性能。Redis 不适宜做什么
每种产品都有本人的特定的应用领域。Redis 也不是万能的。
- Redis 是内存数据库,相比磁盘类型的数据库老本要高不少,注定了 Redis 不能用于存储大规模的数据(土豪疏忽)。
- Redis 有足够高的性能,因而对于热数据可能很好满足需要,但如果冷数据存在 Redis 里未免过于节约(土豪疏忽)。
- Redis 数据存储在内存中,对于可用性要求极高,且须要永恒保留的数据不倡议放在 Redis 中,尽管 Redis 提供长久化、复制等性能保证数据落盘,但长久化、复制等也存在时间差,这段时间的数据也不是可能齐全保障不失落的。
-
Redis 是单线程的,对于数据比拟大的数据的读写操作会阻塞整个数据库,因而 Redis 不适宜存储单个 value 比拟大的数据。
深探入微
作为 最佳实际 本章将会把次要的关注点放和在 Redis 用户相干的一些 Redis 基本知识,这部分常识是 Redis 用户须要理解并在理论应用 Redis 过程中要思考的。比方,如果不思考 Redis 单线程的个性可能会遇到申请阻塞导致性能急剧下降的问题;不理解 Redis 的数据结构,可能导致应用存储收缩、大 value、热 key 的问题等等。
单线程
不论是单线程或者多线程都是为了晋升 Redis 的性能,Redis 作为一个基于内存的数据库,不仅仅须要进行数据的读写操作,还要解决大量的内部的网络申请,这就不可避免的要进行屡次 IO。Redis 抉择了 IO 多路复用 + 单线程的架构来解决申请。简略说:
- 应用 I/O 多路复用机制同时监听多个文件描述符的可读和可写状态。
-
一旦受到网络申请就会在内存中疾速解决,因为绝大多数的操作都是纯内存的,所以解决的速度会十分地快。
总之,单线程模式下,即便连贯的网络解决很多,因为有 IO 多路复用,仍然能够在高速的内存解决中失去疏忽,所以抉择 Redis 抉择单线程的架构。
当然,Redis 在 6.0 之后退出了多线程,因为读写网络的 read/write 零碎调用在 Redis 执行期间占用了大部分 CPU 工夫,如果把网络读写做成多线程的形式对性能会有很大晋升。数据结构
相比其余 KV 数据库,Redis 提供了丰盛的数据结构来满足用户的不同需要。同时,能够说 Redis 在内存应用是斤斤计较。为了最大可能的节约内存,Redis 的每一种数据结构都领有 2~3 种(截止 Redis6.0,后续可能会更多)的底层实现。比方,在
list
、hash
、set
、zset
等简单数据结构在数据量较小的状况下都会应用ziplist
这种数据结构等,因为ziplist
是间断空间,不影响指针等附加耗费,在数据量较小的时候读写速度劣势也并不显著,然而能够节约不少存储,尤其是在理论应用场景种往往小数据占比拟大的状况下内存节约更为显著。
表 -1 Redis 数据结构与编码类型 编码 决定条件 阐明 string int 8 个字节的带符号长整型(2^63-1) 整数编码 string embstr 小于等于 44 个字节的字符串,3.0.0 是 39 个字节 优化内存调配的字符串编码,和 StringObject 间断,一起调配一起开释,别离缩小一次内存操作 string raw 大于 44 个字节的字符串 动静字符串编码 list ziplist value 最大字节数 <= list-max-ziplist-value 且 链表长度 <= list-max-ziplist-entries list linkedlist value 最大字节数 > list-max-ziplist-value 或者 链表长度 > list-max-ziplist-entries list quicklist 3.2 版本之后新增。废除 list-max-ziplist-value 和 list-max-ziplist-value。应用新配置项:list-max-ziplist-size 示意最大压缩空间或者 ziplist 长度,取值范畴为 -5, - 1 默认是 -2(8kb);list-compress-depth 示意压缩深度,默认是 0,不压缩 思考到链表附加空间绝对太高,应用 quicklist 代替 ziplist 和 linklist hash ziplist value 最大字节数 <= hash-max-ziplist-value 且 field 个数 <= hash-max-ziplist-entries hash hashtable value 最大字节数 > hash-max-ziplist-value 或者 field 个数 > hash-max-ziplist-entries set intset 元素必须是整型,且汇合长度 <=set-max-inset-entries set hashtable 汇合长度 >set-max-inset-entries zset ziplist value 最大字节数 <= zset-max-ziplist-value 且 链表长度 <= zset-max-ziplist-entries zset skiplist value 最大字节数 > zset-max-ziplist-value 或者 链表长度 > zset-max-ziplist-entries stream rax + listpack listpack 是 ziplist 优化版本,目前(Redis 5.0.0)只应用在 stream 中 表 1 Redis 数据结构外部实现
长久化
Redis 反对 RDB 和 AOF 两种长久化机制。长久化性能可能无效的防止 Redis 服务异样退出导致数据 齐全 失落的状况。当重启 Redis 服务会主动加载长久化文件即可实现数据恢复。
RDB
RDB 长久化是将以后 Redis 过程数据快照保留到硬盘的过程,触发 RDB 生成有两种形式:手动触发和主动触发。
- 手动触发 :对应
save
和bgsave
两个命令,其中save
是阻塞的,已逐渐淘汰。 - 主动触发:主动触发大略有四种场景
-
- 应用
save
相干配置,如save m n
, 示意m
秒内数据产生了n
次批改,则字段执行bgsave
;
- 应用
-
- 从节点执行全量复制操作,主节点字主动执行
bgsave
生成 RDB 文件并发送给从节点。
- 从节点执行全量复制操作,主节点字主动执行
-
- 执行
debug reload
命令从新加载 Redis,会触发save
操作(留神,这里是save
)。
- 执行
-
- 默认执行
shutdown
命令,如果没有开启 AOF 长久化也会主动执行bgsave
。
RDB 是一个紧凑压缩的二进制文件(Redis 默认应用 LZF 压缩算法对 RDB 进行压缩),是 Redis 在某一时刻的数据快照,有如下长处:
- 默认执行
- 适宜全量复制、和冷备。
- Redis 加载 RDB 复原数据速度远快于 AOF 形式。
同样,RDB 长久化形式也有诸多毛病: - RDB 长久化形式无奈做到实时长久化。执行
bgsave
都执行fork
操作创立子过程,属于重量级操作,老本较高。 -
RDB 格局不兼容。Redis 倒退过程种有多个格局 RDB 版本,存在老版本 Redis 不兼容新格局 RDB 文件的问题。
AOF
AOF(append only file)长久化是以日志的形式记录每次写操作命令。重启 Redis 时,会通过从新执行这些命令的形式来复原数据。AOF 长久化有三点须要阐明:
- AOF 间接应用文本协定格局。
- AOF 长久化首先会将写操作命令写入
aof_buf
,而后通过提供的不同策略(always
、everysec
、no
)来将aof_buf
中的数据同步到磁盘上。 -
AOF 反对从新机制以压缩文件体积,AOF 文件从新逻辑是将 Redis 过程内的数据转换成写操作命令同步到 AOF 文件中。
复制
为了解决分布式系统中服务单点问题,Redis 引入了复制机制,实现主从架构以满足容灾和负载平衡等问题。复制实质上是数据同步的过程,Redis 反对两种数据同步形式:
- 全量同步,Redis 最早只反对全量同步,全量同步顾名思义,会将主节点的所有数据一次性的同步给从节点,这样会导致主从之间的带宽耗费累赘减轻。
-
局部同步 ,为了解决全量复制存在的问题,Redis 提供了局部复制的机制,当主从断开连接,再次建设连贯,只须要同步断开连接期间的数据。
当主节点把以后数据同步给从节点过后,就将复制流程建设起来了,后续主节点将会继续的把写操作命令发送给从节点,从而保障主从节点数据一致性。reference
Redis 官网
Redis 开发与运维
How Twitter Uses Redis To Scale – 105TB RAM, 39MM QPS, 10,000+ Instances
Latency Numbers Every Programmer Should Know