redis数据类型的具体使用场景
一. String类型
业务场景1
大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键ID必须保证统一性,不能重复。Orcal数据库具有sequence设定,可以解决问题,但是MySQL数据库并不具有类似的机制,那么如何解决?
解决方案:引入redis,使用string类型的
incr key
操作 或者inceby key munber
操作
Redis用于控制数据库主键id,为数据库主键提供生成策略,保证数据库表的主键唯一性
业务场景2
“最强女生”启动海选投票,只能通过微信投票,每个微信号每4小时只能投1票。
电商商家开启热门商品推荐,热门商品不能一直处于热门期,每种商品热门期维持3天,3天后自动取消热门。
新闻网站会出现热点新闻,热点新闻最大的特点是时效性,如何自动控制热点新闻的时效性。
解决方案:设置数据具有指定的生命周期
setex key seconds value
psetex key milliseconds value
Redis控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作
业务场景3
主页高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量
解决方案
- 在Redis中为大V用户设置用户信息,以用户主键和属性作为key,后台设定定时刷新策略即可
eg: user: id:123456:fans 1222109
eg: user: id:123456:blogs 6164
eg: user: id:123456:focus 88- 在Redis中以json格式存储大V用户信息,定时刷新
eg: user: id: 123456 {id:123456,name:喜剧人,fans:1222109,blogs:6164,focus:88}
Redis应用于各种结构型和非结构型高热度数据访问加速
数据库中的热点数据key命名惯例:
表名:主键名:主键值:属性
二. hash类型
业务场景1
电商网站购物车设计与实现
业务分析
- 仅分析购物车的Redis存储模型
添加,浏览,更改数量,删除,清空 - 购物车于数据库间持久化操作(不讨论)
- 购物车于订单关系(不讨论)
提交购物车:读取数据生成订单
商家临时价格调整:隶属于订单级别 - 未登录用户购物车信息存储(不讨论)
cookie存储
解决方案:
- 以客户id作为key,每位客户创建一个hash存储对应的购物车信息
- 将商品编号作为field,购买数量作为value进行存储
- 添加商品:追加全新的field于value
- 浏览:遍历hash
- 更改数量:自增/自减,设置value值 hincrby
- 删除商品:删除field
- 清空:删除key hdel
当前设计是否加速了购物车的呈现?
当前仅仅是将数据存储到redis中,并没有起到加速的作用,商品信息还需要二次查询数据库
- 每条购物车中的商品记录保存成两条field
- field1专用于保存购买的数量
命名格式:商品id:nums
保存数据:数值- field2专用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息等
命名格式:商品id:info
保存数据:json可以把field2独立出来,商品hash,还可以商品分类,不同的hash保存不同的类
业务场景2
双十一活动日,销售手机充值卡的商家对移动,联通,电信的30元,50元,100元商品推出抢购活动,每种商品抢购上限1000张
解决方案:
- 以商家id作为key
- 将参与抢购的商品id作为field
- 将参与抢购的商品数量作为对应的value
- 抢购时使用降值的方式控制产品数量 hincrby 商家id 商品id[field] -数量
实际业务中海油超卖等实际问题,这里不做讨论
redis应用于抢购,限购类,限量发放优惠券,激活码等业务的数据存储设计
三. list类型
- 数据存储需求:存储多个数据,并对数据进行存储空间的顺序进行分区
- 需要的存储结构:一个存储空间保存多个数据,切通过数据可以体现进入顺序
- list类型:保存对个数据,底层使用双向链表存储结构实现
业务场景1
规定时间内获取并移除数据
blpop key1 [key2] timeout
brpop key1 [key2] timeout
业务场景2
微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息
如果取消点赞,移除对应好友信息
如果取消的是妲己怎么办?
移除指定的数据
lrem key count value 其中count是数量,value是删除的具体数据
演示代码如下:
业务场景3
twitter,新浪微博,中个人用户的关注列表需要按照用户的关注顺序进行展示,粉丝列表需要将最新关注的粉丝列在前面
新闻,资讯类网站如何将最新的新闻或资讯按照发生的时间顺序展示
企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?
解决方案:
- 依赖list的数据具有顺序的特征对信息进行管理
- 使用队列模型解决多了信息回总合并的问题
- 使用栈模型解决最新消息的问题
演示代码如下:
四. set类型
- 新的存储需求:存储大量的数据,在查询方面提供更高的效率
- 需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询
- set类型:与hash存储结构完全相同,仅存储键,不存储值,并且值是不允许重复的
业务场景1
每位用户首次使用今日头条时会设置3项爱好的内容,但是后期为了增加用户的活跃度,兴趣点,必须让用户对其他信息类别逐渐产生兴趣,增加客户留存度,如何实现?
业务分析
- 系统分析出各个分裂的最新或最热点信息条目并组织成set集合
- 随机挑选其中部分信息
- 配合用户关注信息分类中的热点信息组织成展示的全部信息集合
解决方案
- 随机获取集合中指定数量的数据
srandmember key [count]
- 随机获取集合中的某个数据并将该数据移除集合
spop key
演示代码如下:
业务场景2
交友平台【脉脉/新浪/qq】为了增加用户之间的交流,提高用户留存性,需要让用户拥有大量的好友,如何快速为用户基类更多的好友?如何提高用户关注他人的总量?
微信公众号是微信信息流通的渠道之一,增加用户关注的公众号成为提高用户活跃度的一种方式,如何帮组用户积累更多关注的公众号?
解决方案
- 求两个集合的交,并,差集
sinter key1 [key2]
sunion key1 [key2]
sdiff key1 [key2]
- 求两个集合的交,并,差集并存储到指定集合中
sinterstore destination key1 [key2]
sunionstore destination key1 [key2]
sdiffstore destination key1 [key2]
- 将指定数据从原始集合中移动到目标集合中
smove source destination member
演示代码如下:
业务场景3
公司对旗下新的网站做推广,统计网站的PV(访问量),UV(独立访客),IP(独立IP)
PV:网站被访问次数,可通过刷新页面提高访问量
UV:网站被不同用户访问的次数,可通过cookie统计访问量,相同用户切换不同IP地址,UV不变
IP:网站被不同IP地址访问的总次数,可通过IP地址统计访问量,相同IP不同用户访问,IP不变
解决方案:
- 利用set集合的数据去重特征,记录各种访问数据
- 建立string类型数据,利用incr统计日访问量(PV)
- 建立set模型,记录不同cookie数量(UV)
- 建立set模型,记录不同IP数量(IP)
五. sorted_set类型
- 新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式
- 需要的存储结构:新的存储模型,可以保存可排序的数据
- sorted_set类型:在set的存储结构基础上添加可排序字段
业务场景1
票选湖北十大杰出歌手,各类综艺选秀海选投票
各类资源网站TOP10(电影,歌曲,游戏)
聊天室活跃度统计
游戏好友亲密度
解决方案
- 获取数据对应的索引(排名)
zrank key member
zrevrank key member
- score值获取与修改
zscore key member
zincrby key increment member
演示代码如下:
redis应用于计数器组合排序功能对应的排名
六. 综合案例
案例1
人工智能领域的语义识别与自然对话将是未来服务业机器人应答呼叫体系中的重要技术,百度字眼用户评价语义识别服务,免费开放给企业试用。现在对试用用户的使用行为进行限速,限制每个用户每分钟最大发起10次调用。
解决方案
- 设计计数器,记录调用次数,用于控制业务执行次数。以用户id作为key,使用次数作为value
- 在调用前获取次数,判断是否超过限定次数
不超过次数的情况下,每次调用技术+1
业务调用失败,技术-1 - 为技术器设置生命周期为指定周期,例如1秒/分钟,自动清空周期内使用次数
演示代码如下:
上面这种方案,每次get时都会判断value是否大于10,容易影响效率,可以使用数字的最大值,当超过最大值时就会报错,然后再重新赋值。
解决方案改良
- 取消最大值的判定,利用incr操作超过最大值抛出异常的形式替代每次判断
- 判断是否为nil
如果是,设置为Max-次数
如果不是,计数 + 1
业务调用失败,计数 -1 - 遇到异常即+ 操作超过上限,视为使用达到上限
演示代码如下: