Redis基础
为什么要使用Redis
读写性能优异
数据类型丰富
原子性
丰富的特性
持久化
发布订阅模式
分布式
使用场景
热点数据缓存
缓存是Redis最常见的应用场景,之所有这么使用,主要是因为Redis读写性能优异。
作为缓存使用时,一般两种方式保存数据:
读取前,先去读Redis,如果没有数据,读取数据库,将数据拉入Redis。
插入数据时,同时写入Redis。
方案一:实施起来简单,但是有两个需要注意的地方:
避免缓存穿透。(数据库没有,redis也没有,会给数据库造成很大的压力)
数据的实时性会差一点
方案二:数据实时性强,但是开发时不便于统一处理
方案一适合对于数据实时性要求不是特别高的场景。方案二适用于字典表、数据量不大的数据存储。
限时业务的运用
redis可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。
计数器相关问题
redis的incrby命令可以实现原子性的递增,可以运用于高并发的秒杀活动、分布式序列号的生成、具体业务还有限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。
分布式锁
这个主要利用redis的setnx命令进行。set if not exists
延时操作
比如订单的超时时间。通过设置一个key,10分钟过期,后期实现监听器,如果key失效,则还原库存
排行榜相关问题
关系型数据库在排行榜方面查询速度普遍较慢,所以可以借助redis的SortedSet进行热点数据的排序
点赞、好友等相互关系的存储
Redis 利用集合的一些命令,比如求交集、并集、差集等。
在微博应用中,每个用户关注的人存在一个集合中,就很容易实现求两个人的共同好友功能
简单队列
由于Redis有list push和list pop这样的命令,所以能够很方便的执行队列操作。
Redis基础数据类型
redis所有的key都是字符串。我们讨论基础数据结构时,讨论的是存储值的数据类型,主要包括常见的5种数据类型
String
可以是字符串、整数或浮点数。
对整个字符串或字符串的一部分进行操作;对整数或浮点数进行自增或自减操作
List
一个链表,链表上每一个节点都包含一个字符串
对链表的两顿进行push和pop操作,读取单个或多个元素;根据值查找or删除元素
Set
包含字符串的无序集合
字符串的集合,包含基础的方法:查看是否存在,添加、获取、删除;还包括计算交集、并集、差集等
Zset
和Hash一样,用于存储键值对
字符串成员与浮点数之间的有序映射;元素的排列顺序由分数的大小决定;
包含方法有添加、获取、删除单个元素以及根据分值范围或成员来获取元素
Hash
包含键值对的无须散列表
添加、获取、删除单个元素
String字符串
redis的String类型是二进制安全的,意思是redis的string可以包含任何数据。如数字、字符串,jpg图片或者序列化的对象
常用的命令如下:
get
set
del
incr
decr
incrby 将键存储的值加上整数
decrby 将键存储的值减去整数
可以通过set命令为一个key绑定一个数值类型,然后使用incr等指令进行增加和减少
使用场景
缓存:经典使用场景,把常用信息、字符串、图片或者视频等信息放到redis种,redis作为缓存层,mysql做持久化,降低mysql的读写压力
计数器:redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。
session:常见的方案为spring session + redis实现session共享
List列表
Redis中的列表其实就是链表(Redis使用双端链表实现List)
使用List结构,我们可以轻松实现最新消息排队功能。List的另外一个应用就是消息队列,可以利用List的Push操作,将任务存放在list中,然后工作线程用pop操作将任务取出执行。
常用的命令
rpush 给定值推入到列表右端
lpush
rpop
lpop
lrange 获取列表再给定范围上的所有值。这里也是元素的下标范围
lindex 通过索引获取列表中的元素。 这里的索引是元素在list中的下标
lpush+ltrim = Capped Collection(有限集合)
lpush+brpop = Message Queue(消息队列)
ltrim是删除list某个下标范围内的数据
brpop是获取并删除list的最后一个元素,如果列表为空,则阻塞列表或者直到超时。
使用场景
微博的timeline
消息队列
Set集合
Redis的Set是String类型的无序集合。集合成员是唯一的,这意味着集合中不能出现重复的数据
常用命令:
sadd
向集合添加一个或者多个成员
scard
获取集合的成员数
smembers
返回集合中的所有成员
sismember
判断member元素是否是集合key的成员
使用场景
标签(tag),给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人。
点赞,或点踩,收藏等,可以放到set中实现。
Hash散列
Redis hash 是一个string类型的field(字段)和value(值)的映射表,hash特别适合用户存储对象
常用命令
hset 添加键值对
hset usermap name hao
hget
hgetall,获取散列中包含的所有键值对
hdel,如果给定键存在于散列中,那么就移除这个键
使用场景
缓存:能直观,相比string更节省空间,的维护缓存信息,如用户信息,视频信息等。
Zset有序集合
Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每一个元素都会关联一个double类型的分数。redis证书通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。有序集合是通过两种数据结构实现:
压缩列表(ziplist):ziplist是为了提高存储效率而设计的一种特殊编码的双向链表。它可以存储字符串或整数,存储整数时是采用整数的二进制而不是字符串形式存储。它能够在O1的时间复杂度下完成list两端的push和pop操作。但是因为每次操作都需要分配ziplist的内存,所以实际时间复杂度和ziplist的内存使用量有关。
跳跃表(
zSkiplist):跳跃表的性能可以保证在查找、删除、添加等操作的时候在对数学期望时间内完成,这个性能是可以和平衡树来相比较的,而且在实现方面比平衡树要优雅,这是采用跳跃表的主要原来。跳跃表的复杂度为O(log(n))
常用命令
zadd 将一个带有给定分值的成员添加到有序集合方面。
zrange 根据元素在有序集合中所处的位置,从有序集合中获取多个元素。
zrem 如果给定元素成员存在于有序集合中,那么移除这个元素。
HyperLogLogs(基数统计)
基数是指不重复元素。
解决什么问题
这个结构可以非常省内存的去统计各种基数,比如注册IP数,每日访问IP数,页面实时UV,在线用户数,共同好友数等。
它一个基于基数估算的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值。
使用命令
pfdd命令pfcount统计元素的基数数量pfmerage合并两个组pfcount
Bitmap(位存储)
Bitmap即位图数据结构,都是操作二进制来进行记录,只有0和1两个状态。
主要统计用户信息,活跃,不活跃!登录,未登录!打卡,不打卡!两个状态的,都可以Bitmaps!
使用命令:
setbit key offset valuegetbit key offsetbitcount sign
geospatial(地理位置)
// todo
Stream
从功能上看,Stream是Redis对消息队列的完善和实现。
基于Redis的消息队列实现有很多种,例如:
pub/sub,订阅/发布模式
但是发布订阅模式是无法持久化的,如果出现网络断开、Redis宕机等,消息就会被丢弃。
基于List Lpush+brpop 或者 基于Sorted-set的实现
支持了持久化,但是不支持多播,分组消费等。
结构

Consumer Group:消费组,一个消费组有多个消费者(Consumer),这些消费者之间是竞争关系。last_delivered_id:游标,每个消费组会有个游标last_delivered_id,任意一个消费者pending_ids:消费者(Consumer)的状态变量,作用是维护消费者的未确定的id。pending_ids记录了当前已经被客户端读取的消息,但是还没有被ack。如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack,它就开始减少。这个pending_ids变量在Redis官方被称为PEL,也就是Pending Entries list。它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没有处理。
此外还有两点:
消息ID:消息ID的形式是timestampInMillis-sequence,即1527846880572-5是指在1527846880572时产生,且是第五条消息消息内容:消息内容即为键值对。
增删改查
XADD - 添加消息到末尾
XTRIM - 对流进行修剪,限制长度
XDEL - 删除消息
XLEN - 获取流包含的元素数量,即消息长度
XRANGE - 获取消息列表,会自动过滤已经删除的消息
XREVRANGE - 反向获取消息列表,ID 从大到小
XREAD - 以阻塞或非阻塞方式获取消息列表
最后更新于
这有帮助吗?