Redis常见的使用场景
什么是Redis?
Redis是一个非常快速的开源非关系、Key-Value数据库,通常称为数据结构服务器;它存储了五种不同类型值的键映射。用作数据库,缓存和消息代理。
Redis和其他键值数据库之间的主要区别之一是Redis存储和操作高级数据类型的能力。这些数据类型是大多数开发人员熟悉的基本数据结构(列表,映射,集合和排序集)。Redis的卓越性能,简单性和数据结构的原子操作有助于解决使用传统关系数据库实现时难以实现或执行不佳的问题。
Redis的特性
一个产品的使用场景肯定是需要根据产品的特性,先列举一下Redis的特点:
- 读写性能优异
- 持久化
- 数据类型丰富
- 单线程
- 数据自动过期
- 发布订阅
- 分布式
这里我们通过几个场景,不同维度说下Redis的应用。
常见的应用场景
1、缓存
缓存是Redis最常见的应用场景,之所有这么使用,主要是因为Redis读写性能优异。而且逐渐有取代memcached,成为首选服务端缓存的组件。而且,Redis内部是支持事务的,在使用时候能有效保证数据的一致性。
不过也有需要注意的地方:
- 必须保证不同对象的key不可以重复,并且key尽量短,一般使用类名加主键拼接而成。
- 选择一个有序的序列化方式也很重要,目的是提高序列化效率和减少内存占用。
- 缓存期间的数据一致性。一般有两种做法:
- 只在数据库查询后将对象放入缓存,如果对象发生了删除或者修改操作,直接清除对应缓存(或者设置为过期)
- 在数据库新增和查询后将对象放入缓存,修改后更新缓存,删除后清除对应缓存,或者设置为过期。
2、限时业务的运用
redis中可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。
3、计数器
计数功能应该是最适合redis的使用场景之一,高频率读写特性完全可以发挥redis作为内存数据库的高效。在Redis的数据结构中,string, hash, 和sorted set都提供了incr方法用于原子性自增操作,下面举例说明它们各自的应用场景:
- 如果应用需要显示每天注册用户数,便可以使用
String
作为计数器,设定一个名为REGISTERED_COUNT_TODAY
的 key,并在初始化时给它设置一个到凌晨 0 点的过期时间,每当用户注册成功后便使用incr
命令使该 key 增长 1,同时当每天凌晨 0 点后,这个计数器都会因为 key 过期使值清零。 - 每条微博都有点赞数,评论数,转发数和浏览数四条属性,这是用
hash
进行计数会更好,该计数器的key设为为weibo:weibo_id
,hash
的 field 为like_number
、comment_number
、forward_number
和view_number
,在对应操作后通过hincrby
使hash 中
的 field 自增。 - 如果应用有一个发帖排行榜的功能,便选择
sorted set
吧,将集合的 key 设为POST_RANK
。当用户发帖后,使用zincrby
将该用户 id 的 score 增长 1。sorted set
会重新进行排序,用户所在排行榜的位置也就会得到实时的更新。
4、排行榜
使用sortedset可以轻松打造一个热度排行榜,zrevrangebyscore可以得到以分数倒序排列的序列,zrank可以得到成员在该排行榜中的作用。
5、分布式锁
在Redis2.6.12版本开始,string
的set命令增加了三个参数:
Ex
:设置键的过期时间(s)Px
: 设置键的过期时间(ms)NX
|XX
:当设置为NX
时,仅当key存在才进行操作,设置为xx时,仅当key不存在才会进行操作,这个操作是原子性的,可以简单实现一个分布式锁,例如:set key "lock" Ex 1 xx
如果操作返回false,说明key的添加不成功,即当前有人占用这把锁,而如果返回true,说明得到了锁,可以继续进行操作,操作后通过
del
释放掉锁,并且即使程序因为某些原因没有释放锁,设置了过期时间,所以该锁也会在1秒后自动释放。伪代码:
//产生锁 while lock!=1//过期时间是为了避免死锁now = int(time.time())lock_timeout = now + LOCK_TIMEOUT + 1lock = redis_client.setnx(lock_key, lock_timeout)//真正要处理的业务 doing() //释放锁 now = int(time.time()) if now < lock_timeout:redis_client.delete(lock_key)
6、延时操作
比如在订单生产后我们占用了库存,10分钟后去检验用户是够真正购买,如果没有购买将该单据设置无效,同时还原库存。 由于redis自2.8.0之后版本提供Keyspace Notifications功能,允许客户订阅Pub/Sub频道,以便以某种方式接收影响Redis数据集的事件。 所以我们对于上面的需求就可以用以下解决方案,我们在订单生产时,设置一个key,同时设置10分钟后过期, 我们在后台实现一个监听器,监听key的实效,监听到key失效时将后续逻辑加上。 当然我们也可以利用rabbitmq、activemq等消息中间件的延迟队列服务实现该需求。
7、分页、模糊搜索
redis的set集合中提供了一个zrangebylex方法,语法如下:
ZRANGEBYLEX key min max [LIMIT offset count]
通过ZRANGEBYLEX zset - + LIMIT 0 10 可以进行分页数据查询,其中- +表示获取全部数据
zrangebylex key min max 这个就可以返回字典区间的数据,利用这个特性可以进行模糊查询功能,这个也是目前我在redis中发现的唯一一个支持对存储内容进行模糊查询的特性。
8、点赞、好友等相互关系
一篇介绍微博Redis应用的PPT中,其中提到微博的Redis主要用在计数和好友关系两方面,
《Redis设计与实现》中作者最开始使用Redis中的set
是因为传统数据库无法计算集合的交集。
对于一个用户A,将它的关注和粉丝的用户id都存放到两个set中:
A:follow
:存放A所有关注的用户idA:follower
:存放A所有粉丝的用户id那么通过
sinter
命令便可以根据A:follow
和A:follower
的交集得到与 A 互相关注的用户。当 A 进入另一个用户 B 的主页后,A:follow
和B:follow
的交集便是 A 和 B 的共同专注,A:follow
和B:follower
的交集便是 A 关注的人也关注了 B。
9、队列
Redis中的list
的数据结构实现的是双向链表,所以可以非常便捷的应用于消息队列(生产者/消费者模型)。消息的生产者只需要通过lpush将消息放入list,消费者可以通过rpop取出该消息,并且保证消息的有序性。
如果需要实现带有优先级的消息队列也可以选择**sorted list
。而pub/sub
**也可以作为发布者/订阅者模型的消息。由于Redis带有持久化功能,无需担心由于服务器故障导致消息丢失的情况发生。
10、时间轴
list作为双向链表,不光可以作为队列使用,如果将它用作栈便可以成为一个公用的时间轴。当用户发完微博后,都通过lpush将它存放在一个key为LATEST_WEIBO的list中。之后便可以通过lrange取出最新的微博。
11、倒排索引
倒排索引是构造搜索功能的最常见的方式,Redis中也可以通过set建立倒排索引,这里以简单的拼音+前缀搜索城市功能举例:
假设一个城市北京
,通过拼音词库将北京
转为beijing
,再通过前缀分词将这两个词分为若干个前缀索引,有:北
、北京
、b
、be
…beijin
和beijing
。将这些索引分别作为set
的 key(例如:index:北
)并存储北京
的 id,倒排索引便建立好了。接下来只需要在搜索时通过关键词取出对应的set
并得到其中的 id 即可。
示例:秒杀和Redis的结合
秒杀是现在互联网系统中常见的营销模式,作为开发者,其实最不愿意这样的活动,因为非技术人员无法理解到其中的技术难度,导致在资源协调上总是有些偏差。秒杀其实经常会出现的问题包括:
- 并发太高导致程序阻塞。
- 库存无法有效控制,出现超卖的情况。
其实解决这些问题基本就两个方案:
- 数据尽量缓存,阻断用户和数据库的直接交互。
- 通过锁来控制避免超卖现象。
现在说明一下,如果现在做一个秒杀,那么,Redis应该如何结合进行使用?
- 提前预热数据,放入Redis
- 商品列表放入Redis List
- 商品的详情数据 Redis hash保存,设置过期时间
- 商品的库存数据Redis sorted set保存
- 用户的地址信息Redis set保存
- 订单产生扣库存通过Redis制造分布式锁,库存同步扣除
- 订单产生后发货的数据,产生Redis list,通过消息队列处理
- 秒杀结束后,再把Redis数据和数据库进行同步
以上是一个简略的秒杀系统和Redis结合的方案,当然实际可能还会引入http缓存,或者将消息对接用MQ代替等方案,也会出现业务遗漏的情况,这个只是希望能抛砖引玉。
Redis常见的使用场景相关推荐
- Redis学习总结(18)——Redis 常见的使用场景汇总
1.缓存 缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓 ...
- MQ(消息队列)常见的应用场景解析
MQ(消息队列)常见的应用场景解析 原文:MQ(消息队列)常见的应用场景解析 前言 提高系统性能首先考虑的是数据库的优化,之前一篇文章<数据库的使用你可能忽略了这些>中有提到过开发中,针对 ...
- 【面试经典】redis 常见数据结构以及使用场景分析
1.String 常用命令: set,get,decr,incr,mget 等. String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字. 常规key- ...
- Redis常见数据结构以及使用场景(微博)分析
1. String 常用命令: set,get,decr,incr,mget 等. String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字. 常规key ...
- 【带你重拾Redis】Redis常见知识点
什么是Redis? Redis是一个使用ANSI C语言编写,遵守BSD协议规范的开源的K-V类型的NoSQL数据库服务器. Redis是当前最流行的K-V类型的NoSQL数据库之一,在通往系统架构的 ...
- Spring Boot常见企业开发场景应用、自动配置原理结构分析
读者应具备: Spring SpringMVC服务器端开发基础 Maven基础 本篇主要介绍Spring Boot在企业开发中常见场景的使用.以及Spring Boot的基本原理结构. 以下为本篇设计 ...
- Redis数据库的应用场景介绍
https://www.jb51.net/article/68262.htm 一.MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载 ...
- Redis:常见的面试题
Redis的那些最常见面试问题 先把这些面试题给浏览一遍,大概知道redis的一些相关名词,接下来几篇博客才会继续的详细一些写redis的一些特性~~然后慢慢把redis学会. 1.什么是Redis? ...
- redis常用数据类型的场景,你真的用对了么?
关注微信公众号"虾米聊吧",每天更新一篇技术文章,文章内容涵盖架构师成长必经之路应掌握的技术,一起学习,一起交流. redis常用数据类型的场景,你真的用对了么? redis常用数 ...
最新文章
- SoapUi测试,测试相关问答知识
- 小米今日正式进军越南市场 借助合作方铺渠道分销
- prometheus命令_Prometheus入门教程(一):Prometheus 快速入门
- mysql备份恢复数据库据/表
- mac上c++11的编译问题
- 菜鸟打印助手接口_打印快递单,这4件事儿你非做不可
- ORACLE数据库空间满了如何进行空间扩展
- Openerp对象字段定义详解
- 灵州会盟及民族友好历史传统研讨会在吴忠召开
- 音视频多媒体开发基础概述之颜色空间(2)YUV YIQ YCrCb CMY颜色空间
- 春秋杯CTF2022 WP
- 解决google浏览器无法自动播放音视频问题
- 【整理】图形学EI论文部分整理
- OpenAI Codex、DeepMind AlphaCode论文精读阅读笔记
- 制定当前学习目标与学习方法
- 预告 · 5月26日IGS大会腾讯云游戏新文娱分论坛遇见TcaplusDB
- epic显示游戏服务器离线,无主之地3Epic离线如何进入游戏 想要Epic离线一键进入游戏就这么做...
- Retina MBP的Windows虚拟机视网膜屏的显示效果问题总结
- 腾讯、百度和360三大平台网站拦截误报申诉入口
- nginx 配置登陆密码