介绍
一、介绍
一个Key-Value 类型的高性能数据库,提供了丰富的数据结构,例如String、Hash、List、Set、SortedSet等。数据是存储在内存中的,同时Redis支持事务、持久化、LUA脚本、发布/订阅、缓存淘汰、流技术等多种功能特性。也提供了主从模式、Redis Sentinel和Redis Cluster集群架构三种高可用方案。
作者:安特雷兹(antirez)
- Antirez个人github:github.com/antirez
- Antirez个人博客:antirez.com/latest/0
几个用来学习 Redis 文章地址
- 官网地址:https://redis.io/
- Redis源码地址:https://github.com/redis/redis
- Redis参考:Redis中文网
二、特点
- redis的性能是极高的,据测试Redis读的速度可以达到110000次/秒,写的速度可以达到81000次/秒
- Redis数据类型丰富,不仅仅支持简单的Key-Value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- Redis支持数据的备份,即master-slave模式的数据备份
三、Redis应用场景
1、热点数据问题缓存
缓存是Redis最常见的应用场景,之所有这么使用,主要是因为Redis读写性能优异,读的速度可以达到110000次/秒,写的速度可以达到81000次/秒。而且逐渐有取代memcached, 成为首选服务端缓存的组件。而且Redis内部是支持事务的,在使用时候能有效保证数据的一致性。作为缓存使用时, 一般有两种方式保存数据:
- 方式一:读取前,先去读Redis,如果没有数据,读取数据库,将数据拉入Redis。 这种方式实施起来简单,但是有两个需要注意的地方: 1.避免缓存击穿(数据库没有就需要命中的数据,导致Redis一直没有数据,而一直命中数据库。) 2.数据的实时性相对会差一点。
- 方式二:插入数据时,同时写入Redis。 这种方式数据实时性强,但是开发时不便于统一处理。
当然,两种方式根据实际情况来适用。比如方案一适用于对于数据实时性要求不是特别高的场景。方案二适用于字典表、数据量不大的数据存储。
2、限时业务的运用
redis中可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。
3、计数器相关问题
redis由于incrby命令可以实现原子性的递增,所以可以运用于高并发的秒杀活动、分布式序列号的生成、 具体业务还体现在比如限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。
4、分布式锁
这个主要利用redis的setnx命令进行,setnx:"set if not exists"就是如果不存在则成功设置缓存同时返回1,否则返回0 ,这个特性在很多后台中都有所运用,比如在集群中执行一些定时任务时,可能在两台机器上都会运行, 所以在定时任务中首先 通过setnx设置一个lock, 如果成功设置则执行,如果没有成功设置,则表明该定时任务已执行。 当然结合具体业务,我们可以给这个lock加一个过期时间, 比如说30分钟执行一次的定时任务,那么这个过期时间设置为小于30分钟的一个时间就可以,这个与定时任务的周期以及定时任务执行消耗时间相关。 在分布式锁的场景中,主要用在比如秒杀系统等。
5、延时操作
比如在订单生产后我们占用了库存,10分钟后去检验用户是否真正购买,如果没有购买将该单据设置无效,同时还原库存。 由于redis自2.8.0之后版本提供Keyspace Notifications功能,允许客户订阅Pub/Sub频道, 以便以某种方式接收影响Redis数据集的事件。 所以我们对于上面的需求就可以用以下解决方案, 我们在订单生产时,设置一个key,同时设置10分钟后过期, 我们在后台实现一个监听器,监听key的实效, 监听到key失效时将后续逻辑加上。当然我们也可以利用rabbitmq、activemq等消息中间件的延迟队列服务实现该需求。
6、排行榜相关问题
关系型数据库在排行榜方面查询速度普遍偏慢,所以可以借助redis的SortedSet进行热点数据的排序。 比如点赞排行榜,做一个SortedSet, 然后以用户的openid作为上面的username, 以用户的点赞数作为上面的score, 然后针对每个用户做一个hash, 通过zrangebyscore就可以按照点赞数获取排行榜, 然后再根据username获取用户的hash信息,
7、点赞、好友等相互关系的存储
Redis利用集合的一些命令,比如求交集、并集、差集等。在微博应用中,每个用户关注的人存在一个集合中, 就很容易实现求两个人的共同好友功能。
8、简单队列
由于Redis有list push和list pop这样的命令,所以能够很方便的执行队列操作
四、Redis版本
如下图是redis历史版本,2022年4月27日Redis正式发布了7.0版本
Redis从发布至今,已经有十余年的时光了,一直遵循着自己的命名规则
- 版本号第二位如果是奇数,则为非稳定版本,如2.7、2.9、3.1
- 版本号第二位如果是偶数,则为稳定版
- 当前奇数版本就是下一个稳定版本的开发版,如2.9版本就是3.0版本的开发版本
我们可以通过redis.io官网来下载自己感兴趣的版本进行源码阅读,历史发布版本的源码:https://download.redis.io/releases/
五、Redis7新特性
Redis7.0是目前Redis历史版本中变化最大的版本,首先它有超过50个以上的新增命令。其次,它有大量核心特性的新增和改进。这里列举几个主要的特性
- Redis Functions Redis函数,一种新的通过服务端脚本扩展Redis的方式,函数与数据本身一起存储,简言之,redis自己要去抢夺Lua脚本的饭碗
- Client-eviction 一旦 Redis 连接较多,再加上每个连接的内存占用都比较大的时候, Redis总连接内存占用可能会达到maxmemory的上限,可以增加允许限制所有客户端的总内存使用量配置项,redis.config 中对应的配置项//两种配置形式:指定内存大小、基于 maxmemory 的百分比。 maxmemory-client 1g maxmemory-client 10%
- Multi-part AOF 7.0 版本中一个比较大的变化就是 aof 文件由一个变成了多个,主要分为两种类型:基本文件(base files)、增量文件(incr files),请注意这些文件名称是复数形式说明每一类文件不仅仅只有一个。 在此之外还引入了一个清单文件(manifest) 用于跟踪文件以及文件的创建和应用顺序(恢复)
- 访问安全性增强 ACL V2 在redis.conf配置文件中protected-mode默认为yes,只有当你希望你的客户端在没有授权的情况下可以连接到Redis server的时候可以将protect-mode设置为no
- 新增命令 Zset (有序集合)增加 ZMPOP、BZMPOP、ZINTERCARD 等命令Set (集合)增加 SINTERCARD 命令LIST(列表)增加 LMPOP、BLMPOP ,从提供的键名列表中的第一个非空列表键中弹出一个或多个元素。
- listpack替代ziplist listpack 是用来替代 ziplist 的新数据结构,在 7.0 版本已经没有 ziplist 的配置了 (6.0版本仅部分数据类型作为过渡阶段在使用) listpack已经替换了ziplist类似hash-max-ziplist-entries 的配置
- config命令增强 对于Config Set 和Get命令,支持在一次调用过程中传递多个配置参数。例如,现在我们可以在执行一次Config Set命今中更改多个参数: config set maxmemory 10000001 maxmemory-clients 50% port 6399
- RDB保存时间调整 将持久化文件RDB的保存规则发生了改变,尤其是时间记录频度变化
- 底层性能以及资源利用率提升 自身底层部分优化改动Redis核心在许多方面进行了重构和改进主动碎片整理,更快更智能,延时更低-- 集群模式下显著节省内存和延迟 -- 如果有多个哈希或set键,则可以显著节省内-- 复制积压工作和副本使用一个全局共享复制缓冲区-- 显著降低了写入时拷贝内存开销-- 释放集群发送缓冲区中未使用的容量-- 内存效率,充分利用客户端结构内存作为应答缓冲区-- 添加对列表类型的支持,以存储大于4GB的元素-- 按模块为被阻止的客户端重用临时客户端对象-- 优化列表类型操作以从最近的一端搜索-- 删除命令参数计数限制,动态增长argv缓冲区
- HyperLogLog改进 在Redis5.0中,HyperLogLog算法得到改进,优化了计数统计时的内存使用效率,7有了更好的内存统计报告
总结:大体和之前的redis版本保持一致和稳定,主要是自身底层性能和资源利用率上的优化和提高,如果生产上系统稳定,不用着急升级到最新redis7版本,如果从零开始新系统,直接上redis7.0-GA版。