外行看热闹,内行看门道,盘点精彩世界杯背后你看得见的Redis身影

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 背景 6月14日晚,2018年俄罗斯世界杯在莫斯科开幕。国内数以千万的观众通过优酷、央视影音或者是咪咕视频观看了此次开幕赛。阿里云公布的一份数据显示,第一波流量洪峰出现在揭幕战开场后的第44分钟,峰值达到了1.5个2018年春晚的规模。

背景

6月14日晚,2018年俄罗斯世界杯在莫斯科开幕。国内数以千万的观众通过优酷、央视影音或者是咪咕视频观看了此次开幕赛。
_
阿里云公布的一份数据显示,第一波流量洪峰出现在揭幕战开场后的第44分钟,峰值达到了1.5个2018年春晚的规模。自此,本届世界杯也成为了史上最大规模的一次在线直播。比赛期间,预计全网70%的世界杯直播流量都跑在了阿里云上。(注:上述内容引用自:https://www.leiphone.com/news/201806/Du10JxOxuJ6Ou782.html,所属权归原作者所有。)

细心的网友们肯定已经注意到了,今年的世界杯与以往的世界杯相比,不仅比赛结果出人意料,而且观看比赛的APP客户端中也增加了丰富的互动和红包惊喜,众平台为了引流和激活“僵尸”用户也是使出了浑身解数。下面一起来盘点一下精彩世界杯背后你看得见的Redis身影吧!主要从业务架构、应用场景、高可用建设以及弹性扩缩容等几个方面进行展开。

业务架构

15300907231675

                            (图来源自网络)

上图是某企业直播解决方案,主要使用了弹性计算、CDN、智能动态编码技术、视频AI、窄带高清2.0、Redis等等产品技术,充分保证了超清画质体验的同时,节省了带宽的消耗,并最大限度优化资源和成本,给观众带来流畅和丰富多彩的互动体验,极大的满足了用户的参与感。当然,本文重点不是谈论视频如何从录制到播出的,而是要探讨一下“数据库服务器”中Redis在丰富观看直播体验中发挥的重要作用和使用场景及实现。

应用场景

Redis之所以能够被广泛的应用于企业的架构中,而且是不可或缺的重要组成部分,也可以说是标配,其中很重要的一点就是得益于它具有丰富的数据结构,这也是它逐渐替代Memcached,备受青睐的重要原因。它的数据结构有:String、List、Hash、set、Sorted set、bitmap、bit field、hyperLogLog、Geospatial Index等。
15304457602659
正是因为有了这些数据结构和Redis技术的不断完善和发展,才被广泛应用于各行各业中,应用场景也是百花齐放。比如:会话缓存(Session cache)、全页缓存(FPC)、手机验证码、访问频率限制/黑白名单、消息队列、发布与订阅、消息通知、排名/排行榜/最新列表、计数器(比如微博的转评赞计数、阅读数(浏览数,视频播放计数)、博文数(发帖数)、粉丝数、关注数(喜欢商品数)、未读数(动态数))、共同好友/喜好/标签、推送、下拉刷新、私信、商品库存管理(限时的优惠活动信息)、证券指标实时计算,发号器/UUID、以及随着LBS(基于位置服务)的发展,加入的GEO(地理信息定位)的功能和基于Lua自定义命令或功能等等。大家在使用过程中,需要结合自己的业务场景,选择正确的数据类型。那么下面以“优酷APP”为例,来看看有哪些看得见的场景用到了Redis技术。

聊天列表(评论列表)

JS5woYPoSBKerDSMO0upaw_thumb_d

这种评论列表可以用Hash来实现,比如:{userID:contents}

用户ID 评论内容
11101000 破产了

关于评论,你有没有想过一个问题,“垃圾评论” 怎么在评论列表里看不到?没有用户一直在刷评论的?是的,这个肯定是spam系统在默默工作的,这个Redis也是可以做到的,更多策略/机制需要结合drools配合完成。当然通常都是有专门的spam的系统来实现。举个例子,比如要限制某个用户一分钟内的评论次数:

Method1: 用sorted set实现。将最近一天用户评论操作记录起来, score用timestamp替代得分,然后通过Zset的命令RANGEBYSCORE、ZADD、ZRANGEBYSCORE结合实现
RANGEBYSCORE userID:10000:operation:comment 61307510405600 +inf //获得1分钟内的操作记录
redis> ZADD userID:10000:operation:comment 61307510402300 "这是一条评论" //score 为timestamp (integer) 1
redis> ZRANGEBYSCORE userID:10000:operation:comment 61307510405600 +inf //获得1分钟内的操作记录

Method2: 用Redis+Lua实现访问频率控制

# KEYS[1]表示限制次数,由调用程序传入
local key1 ,key2 = 'access:limit' ,'access:expire'
if redis.call('EXISTS' ,key2) > 0 then
   return redis.call('DECR' ,key1) ;
else 
   redis.call('SET' ,key2 ,1)
   redis.call('EXPIRE' ,key2 ,60)
   redis.call('SET' ,key1 ,KEYS[1])
   return KEYS[1]
end

赛况(赛事列表)

aaa1_jpeg
最新活动列表,可以用Redis的List数据结构或者sorted set数据结构实现,加上过期时间轻松搞定。同样的方法,也能轻松的实现最新商品列表、各种排行榜等。

消息(未读消息数)

0saJB2_uTvy_un5BoBtlOQ_thumb_f

实现思路是:使用hash存储用户上次看过的时间,使用sorted set存储每个模块(评论区、群聊)的每个信息产生的时间,并记录未读消息的数量,实现可以参考:https://yq.aliyun.com/ziliao/92283

点赞(点赞数)

GjyATfcAQe6vVwF48kwZ8Q_thumb_e

点赞数,实现相对比较简单了,用string数据结构或者Hash数据结构都能实现,这种点赞没有取消的操作,直接Incr即可。假设key为场次编号:active16

string:
INCR active16
GET active16

Hash:
HSET active:active16 zan 0
HINCRBY active:active16 zan 1
HGETALL active:active16

红包雨(传送门、红包雨)、商品库存/红包金额管理

UNADJUSTEDNONRAW_thumb_13
aaa1
下面介绍一种基于Redis的抢红包方案。

把原始的红包称为大红包,拆分后的红包称为小红包。

1、小红包预先生成,插到数据库里,红包对应的用户ID是null。

2、每个大红包对应两个Redis队列,一个是未消费红包队列,另一个是已消费红包队列。开始时,把未抢的小红包全放到未消费红包队列里。

未消费红包队列里是json字符串,activeID是活动场次,money是红包金额,product是商品个数。如{activeId:'16', money:'300'} 或 {activeID:'16',product:'50'}

3、在Redis中用一个map来过滤已抢到红包的用户。

4、抢红包时,先判断用户是否抢过红包,如果没有,则从未消费红包队列中取出一个小红包,再push到另一个已消费队列中,最后把用户ID放入去重的map中。

5、用一个单线程批量把已消费队列里的红包取出来,再批量update红包的用户ID到数据库里。

上面的流程是很清楚的,但是在第4步时,如果是用户快速点了两次,或者开了两个浏览器来抢红包,会不会有可能用户抢到了两个红包?

为了解决这个问题,采用了lua脚本方式,让第4步整个过程是原子性地执行。

下面是在Redis上执行的Lua脚本:

-- 函数:尝试获得红包,如果成功,则返回json字符串,如果不成功,则返回空
-- 参数:红包队列名, 已消费的队列名,去重的Map名,用户ID
-- 返回值:nil 或者 json字符串,包含用户ID:userId,红包ID:id,红包金额:money

-- 如果用户已抢过红包,则返回nil
if redis.call('hexists', KEYS[3], KEYS[4]) ~= 0 then
return nil
else
-- 先取出一个小红包
local hongBao = redis.call('rpop', KEYS[1]);
if hongBao then

local x = cjson.decode(hongBao);
-- 加入用户ID信息
x['userId'] = KEYS[4];
local re = cjson.encode(x);
-- 把用户ID放到去重的set里
redis.call('hset', KEYS[3], KEYS[4], KEYS[4]);
-- 把红包放到已消费队列里
redis.call('lpush', KEYS[2], re);
return re;

end
end
return nil

参考:https://blog.csdn.net/hengyunabc/article/details/19433779

消息推送

aaa1

上图中的这种弹出消息,未必是Redis实现或者说肯定不是,哈哈。但是这里想提示的是消息提醒,Redis是可以实现的。
15304588827783

这种用pub/sub机制来实现的消息通知,没有持久化机制,属于即发即弃模式。生产者不需要关心有多少的订阅者,也不用关心订阅者的具体信息,在线的客户端(消费者)正常情况下是都看到的,正如我们关注的某个节目一样,在线的时候总能关注的节目更新通知一样。

高可用建设和弹性扩展

面对世界杯这种全球性的全民赛事,尤其是在大家都比较关注的明星或球队对抗的时候(朋友圈都被刷屏的那种),那压力可想而知,虽然拿不到具体的数据,但是从我在微博时保障的热点事件来看,也能猜着个大概。它跟微博热点有很多的相似点,具有不可预见性和突发性,并且伴随着极短时间内流量的数倍增长,甚至更多,有时持续时间较长。如何快速应对突发流量的冲击,确保线上服务的稳定性,是一个非常巨大的挑战和有意义的事情。为了达到这一目标,首先需要有一个完善的,稳定可靠的,健壮的数据库运维体系来提供支撑和管理。
_

正如前面一开始提到的,优酷、央视影音、咪咕视频等视频平台,为了保障业务稳定、减少成本(不可能为了短短一个月的赛事准备4年才用到一次的基础设施),选择和公有云结合是最佳选择,这也是阿里云之所以有流量洪峰出现的重要原因。那么对于Redis来说如何去建设高可用服务以及解决弹性扩展问题?主要有两点:

高可用:异地灾备和多活能力

“不要把鸡蛋放到同一个篮子里”,相信很多架构师也肯定会这么去想,也肯定是这么做的。可以自己搭建一套高可用架构,也可以直接采用阿里云Redis服务提供的异地灾备和多活能力和, 实例部署在跨region,自动双向同步。(参考资料:https://help.aliyun.com/document_detail/71881.html?spm=a2c4g.11186623.6.660.4NtWyS
_
通过异地灾备和多活的能力,一旦发生故障,还可以通过异地快速接管业务,确保使用体验。另外,很多分布较广的业务,用户需要跨地域远距离访问服务。如果此时访问延迟大,将直接影响用户体验。云数据库Redis提供的云上多活,还可以帮助用户消除跨地域远距离访问时的延迟大问题。

弹性:资源伸缩、读写分离

一个区域出现访问异常后,仍然能通过一些手段,比如降级、切流量、限流等一系列措施来保障服务的稳定性。在云模式下,当业务量上来了,扛不住的时候,可以通过阿里云Redis服务自动具备弹性扩缩容一劳永逸,还可以精打细算使用读写分离功能小成本卸载读压力或者通过混合存储卸载存储成本等等。(参考资料:https://help.aliyun.com/document_detail/65001.html?spm=a2c4g.11186631.6.612.JcCjqf

总之,Redis是一个非常重要的组件,它能够被广泛的应用于企业的架构中,而且是不可或缺的重要组成部分。

如果之前没有了解过,那么,“Redis,请了解一下”!不足之处,欢迎批评指正。

作者简介:

张冬洪:阿里云MVP,极数云舟对外合作部总监、技术专家,Redis中国用户组主席,中国MySQL用户组主席团成员

点击以下链接报名

https://yq.aliyun.com/event/288/join/pre

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
SQL 存储 Oracle
"挑战极限!Oracle数据库精英试炼场:夺命连环5问,你能否一路披荆斩棘,登顶技术巅峰?"
【8月更文挑战第9天】Oracle,数据库领域的巨擘,以卓越的数据处理能力、稳定性和安全性成为企业级应用首选。今天我们带来“Oracle夺命连环25问”。首问:核心组件有哪些?答:实例(含内存结构和后台进程)、物理存储(数据文件、控制文件等)及逻辑存储(表空间、段等)。第二问:如何理解事务隔离级别?答:Oracle支持四种级别,默认READ COMMITTED,避免脏读,但可能遇到不可重复读和幻读。
46 0
|
安全 Java 虚拟化
涅槃重生!字节大牛力荐大型分布式手册,凤凰架构让你浴火成神
从大型机到单体架构,从微服务架构到无服务架构,每一次架构模式的演进都是一次涅槃。每一个软件系统都是由大量服务构成的生态体系,个体服务的“死亡”和“重生”是整个系统能否持续可靠运行的关键因素。笔记从5个方面全面剖析了如何构建一个可靠的分布式系统,同时给出了Spring Boot、Spring Cloud、Kubernetes、Istio、AWS Lambda五种架构风格的样例工程。
|
存储 机器学习/深度学习 缓存
【送书活动】大模型赛道如何实现华丽的弯道超车
【送书活动】大模型赛道如何实现华丽的弯道超车
|
人工智能 自然语言处理 安全
网传字节跳动实习生删除所有轻量级模型,还有救吗?
网传字节跳动实习生删除所有轻量级模型,还有救吗?
144 0
|
传感器 机器学习/深度学习 存储
重温工业4.0:(二)时光已过,她的魅力你不曾拥有
在整个工业4.0的实现过程中,肯定没有单一的、标准化的方法。
重温工业4.0:(二)时光已过,她的魅力你不曾拥有
|
JSON 算法 fastjson
Fastjon2他来了,性能显著提升,还能再战十年
阿里官方给的定义是,FASTJSON是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
548 1
|
存储 人工智能 弹性计算
首届不宕机春晚背后:国服第一程序员C位出道
首届不宕机春晚背后:国服第一程序员C位出道
259 0
首届不宕机春晚背后:国服第一程序员C位出道
|
双11 数据中心
阿里巴巴数据中心双11守夜人:把机器当“媳妇”,愿做亿万网友背后的男人
11月11日零点,全世界最热闹的时刻,你一定想不到这里——张北。 张北不只有音乐节,还有关乎双11成败的——阿里巴巴数据中心。 你买的每一件商品,交易数据流都将在这里汇聚,每一盏亮起的服务器巡视灯,就意味着数以亿计的数据流。
2246 0
|
存储 安全 大数据
确认过眼神?上云之路需要遇上对的人!
在“上云就上阿里云”解决了上什么云的问题之后,如何上云成为企业技术人员头疼的问题。业务系统云上应用基础架构应该如何设计、系统存储与数据库如何才能平滑迁移等等成为企业上云之路的障碍。为了解决企业上云前的痛点,阿里云支持与服务团队重磅推出咨询与设计场景下五款专家服务产品。

相关产品

  • 云数据库 Tair(兼容 Redis)