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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云数据库 Tair(兼容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
目录
相关文章
|
7月前
|
NoSQL Java 程序员
成功上岸!一路披荆斩棘腾讯6面面经,大厂远没想象中的难
随着互联网行业的蓬勃发展,越来越多的Java开发程序员渴望加入大公司,以拓宽自己的视野和提升技术水平。对于两年经验的开发者来说,要通过头部互联网公司如美团的面试并不容易,不仅需要掌握扎实的基础知识,还需要在面试中展现出独到的思路和解决问题的能力。
|
传感器 安全 物联网
聊一聊V2X,我眼中的V2X
聊一聊V2X,我眼中的V2X
惊险!备战3个月,五面蚂蚁金服差点倒在最后一面
作为程序员,免不了要经历面试这关,虽然平时工作勤勤恳恳,但是面试上面未必能展示的出来,比如平时都是做增删改查的业务系统,面试官非要问你如何处理高并发大数据,本来是写java代码,非要问你大型网站架构,这些问题防不胜防,本文就自己一次在蚂蚁金服的面试经验来总结一下,抛砖引玉。
|
人工智能 自然语言处理 安全
网传字节跳动实习生删除所有轻量级模型,还有救吗?
网传字节跳动实习生删除所有轻量级模型,还有救吗?
149 0
|
人工智能 运维 算法
“开盖有奖”背后的攻防战:我卧底进500个黑产群、捡了3000个瓶盖
没想到,“开盖有奖”的活动被黑灰产、羊毛党们盯上了,不止一名消费者在网上发起投诉。
508 0
“开盖有奖”背后的攻防战:我卧底进500个黑产群、捡了3000个瓶盖
|
程序员
揭秘:一篇文章揭穿创业公司的套路
揭秘:一篇文章揭穿创业公司的套路
98 0
|
数据中心
阿里云黑科技太厉害了 脑子进水还算得更快
热得快可以快速烧水是利用了浸没的优势,那么如果要降温呢? 阿里云科学家在4月26日的云栖大会·南京峰会上展示了全浸没的“凉得快”服务器——麒麟,把整台服务器浸在液体里循环冷却,这一方案可以无需使用空调,能源使用率(PUE)逼近了理论极限值1.0。
1666 0
|
双11 数据中心
阿里巴巴数据中心双11守夜人:把机器当“媳妇”,愿做亿万网友背后的男人
11月11日零点,全世界最热闹的时刻,你一定想不到这里——张北。 张北不只有音乐节,还有关乎双11成败的——阿里巴巴数据中心。 你买的每一件商品,交易数据流都将在这里汇聚,每一盏亮起的服务器巡视灯,就意味着数以亿计的数据流。
2246 0
|
程序员
女网友吐槽程序员眼光高, 要钱要颜, 阿里网易程序员最现实
现在程序员无疑是一个高薪岗位,在如今互联网时代,一个技术型人才在社会上真的太吃香了,现在很多知名互联网公司员工的待遇也是十分优渥,但是有一个尴尬的问题是很多程序员人是单身。
1164 0
|
存储 安全 大数据
确认过眼神?上云之路需要遇上对的人!
在“上云就上阿里云”解决了上什么云的问题之后,如何上云成为企业技术人员头疼的问题。业务系统云上应用基础架构应该如何设计、系统存储与数据库如何才能平滑迁移等等成为企业上云之路的障碍。为了解决企业上云前的痛点,阿里云支持与服务团队重磅推出咨询与设计场景下五款专家服务产品。

相关产品

  • 云数据库 Tair(兼容 Redis)