背景介绍
回顾2015年在鸟巢举行的第一届双11晚会,我们可以称之为“全民互动”的晚会。因为不止是现场的几千位观众,全国所有在电视机面前的观众朋友,都可以拿起手机,打开天猫客户端或淘宝客户端,参与到晚会现场的各个明星互动游戏中来,进行红黑押宝,获胜的人,还能抢到一元商品。
而刚刚过去的,在深圳大运中心的2016第二届双11晚会,更是有了历史性的突破,是一场“双向互动”的晚会。电视机前的观众,可以不只是单向的接收舞台上的剧情变化,也可以用手机APP参与互动,来改变舞台上的剧情发展,支持哪位明星,就一起努力让TA赢。对于无法观看电视浙江卫视的用户,还可以打开天猫客户端,观看舔屏版的网络直播并同步参与互动。
今年的直播渠道也有很多,手机天猫、手机淘宝、优酷、来疯、今日头条、Youtube,这样全世界的会员和粉丝,都能及时参与到晚会的互动中来,参与一场全球的狂欢盛宴。这种“双向互动”的玩法,无论在国内还是国外,都是首创。超级碗和《美国偶像》的总制片人、88届奥斯卡颁奖典礼总导演、天猫双11狂欢夜总导演David Hill称之为“好莱坞+硅谷”融合的里程碑式的创新。而作为技术的我们,面对这些技术挑战,也是心潮澎湃。
双向互动怎么玩?
首先说“红黑大PK”,这个互动去年就有,在主持人说“开启押宝通道”后,用户可以选择的红队或黑队,然后明星开始游戏,当其中一个队伍获胜时,押中队伍的用户有机会,就可以得到一个宝箱,开宝箱会有机会获得指定商品的1块钱购买权。今年这个游戏支持了双向互动,在选择完队伍之后,用户还可以继续努力点赞,为支持的队伍“点赞赢时间”、“点赞得道具”等等,增加胜利的概率。粉丝们终于可以为自己的爱豆,贡献自己的力量了。
其他双向互动玩法还有“AB剧”、“跨屏抢星衣”、“满天星”等等。因为是技术文章,这里不再一一细说,其关键点,都是在“舞台、电视机、手机”三者之间,跨越距离和时间,让用户能有一种“身临其境”的感觉,看电视的同时,也能无缝的参与到我们的互动中来。
双向互动的难点在哪里?
前面介绍双向互动时说到了“跨越时间”,所以先看看这个时间上的难点在哪里。
如图,可以看到,“开启点赞事件”,首先由舞台发生,经卫星传递画面,60秒后在电视画面出现,此时,用户拿起手机开始点赞。然而,这个点赞数据,开始从0到1的时候,舞台内容其实已经过去了60秒了,这时候舞台只能拿到刚刚开始变化的点赞数据。虽然数据比实际要小,但我们肯定不会去造假夸大,只能用。所以舞台上的主持人及明星嘉宾,必然是在一个事件发生的60秒之后,才能看到数据反馈的(从现场L屏看到)。那么关键性的问题来了:现场L屏的数据,到了电视里,已经是60秒之后了,手机上,怎么同步和电视L屏出现一样的数据?
这个问题其实有点烧脑了,我们先从一个简单的问题来说:舞台事件发生的60秒后,电视画面出现了相应的“口播”,手机端怎么知道,要“开启点赞事件”了,可以开始从0到1的计数了?
这个问题,其实我们去年就解决了,我们设计了一个时差同步的专利,大致流程是这样的:
互联网导播点击“开启点赞”按钮
—>互动后台校准时间,预计电视在X分Y秒时,才会出现对应的画面
—>推拉结合预告手机端,在60秒内手机端能知道 “开启点赞”事件将要发生在X分Y秒
—>到了X分Y秒,手机端,执行相应的事件处理
这样就解决了手机端和电视同步出现一样的内容,然后再回来说,怎么和电视L屏出现一样数据:
互联网导播点击“开启点赞”按钮
—>互动后台校准时间,预计电视在X分Y秒时,才会出现对应的画面
—>手机端推拉结合,在60秒内,获知“开启点赞”事件发生在X分Y秒
—>到了X分Y秒,手机端,执行相应的事件处理
—>现场L屏开始获取当前时刻的数据(同时将数据持久化起来),数据合成到电视信号,在X分Y秒,出现在了电视L屏
—>X分Y秒,手机端取用的不是当前时刻的数据,而是约60秒之前,持久化起来的数据
具体些,将每秒的数据存下来,每毫秒的数据都hash到秒,每秒的数据由定时钟写入,然后L屏后台获取的是当时的数据,而手机端用户请求的是,60秒前,存入的数据。这里的60秒,只是一个估算的值,具体需要节目卫星通道建立之后,再进行对时校准得出。
无时无刻实时点赞排名
点赞,常见于现在比较热的手机主播直播,而在大型电视现场直播节目中出现、使用,也是头一次。前面提到的“双向互动”,主要的互动参与方式:就是简单的“点赞”,一直狂点。很多人技术同学,可能会不以为意,点赞后台不就是个计数器吗?这有什么难的,两行代码就能搞定。
然而我们要面临的是千万级的点赞用户量,和时间非常集中的点赞请求,最终预估会有百亿千亿级别的点赞数。同时,我们要“实时”给出单节目PV、UV、用户排行榜。
刚接到这个需求的时候也是觉得很棘手。关于单纯的点赞数(PV)功能,我们就做了很多技术选型,DB、缓存,都有难以突破的热点瓶颈,而我们分布式的后端,因为是分布式集群,用纯内存也并不那么放心。
最后,我们的解决方案是两者结合,用内存计数来顶住峰值浏览,但内存中只放入2秒的数据,每2秒会有机制去做持久化,这样就算真的遇到万一,丢了2秒的数据,也关系不大。我们构造了一个新的数据结构,称之为MIT(Memory Increase Tools),对外暴露的能力只有increase,然后内部封装了定时做持久化的逻辑,并且每次持久化都不阻塞其他increase线程。
刚刚的MIT设计,也只是解决了PV统计的问题,UV还需要再想办法。传统的UV统计,大多需要在每个用户第一次点赞时,写入保存一个标识,然后每次点赞的时候,判断是不是存在这个标识,不存在时UV加1。
为了避免对于性能极大浪费的情况,特别是对于晚会这种苛刻的场景,我们仔细思考了一下上下文逻辑、意图,通过判断点赞数从0变为了1,就能判断用户是否来过,可以省下一次缓存,使大部分的点赞请求,就只有一次缓存的写入,其他都是内存操作,保证了接近极致的性能。
最后来看实时排行。动态数据的排行榜,最直接能想到的高性能解决方案也就是redis的zadd了,但这样的话,一来zadd的key就成为了热点,并发冲突变多、QPS能力必然受限于单机;二来上千万的数据进行内存zadd,内存大小、RT也会暴露问题;三来就是成本,成本问题先不多说,值得说的是,这回钱不一定能解决问题。
果然上帝关上一扇门,又开启了一扇窗。冥思苦想,我们发现,前面MIT的思路,恰恰好地,也可以用于排行计算。我们可以用内存,持有一个单机版的排序,然后每2秒,刷入到一个缓存,然后定时把所有机器的缓存,合并出一个最终的排行榜。如图:
这里有一个关键点主要注意:持有一个单机版的排序,这里需要有一个在高并发下线程安全、定时刷入时不阻塞其他线程、能自动排序、自动逐出末尾的数据结构。这个数据结构,我们基于跳表也实现了出来,但限于篇幅,后面单独分享。
尖刺请求也要保成功
前面说过,晚会主打的玩法是“红黑PK”,在主持人一声令下“开启押宝通道”时,所有用户蜂拥而至,押宝接口将迎来巨大的洪水流量,而这些流量,我们还不能过早过低限流,因为会直接影响用户体验、互动参与率、甚至客诉。所以我们需要做的是极致的优化!
但是又需要持久化,所以我们限制自己,只能有一次tair的写入。最终我们的写法是:
oniszTair.versionPrefixPut(pKey(userId), sKey(pkId), target, 2, expire);
这里,用的是主子key的方式,这样有几个好处:
1、一次主pkey查询可以查出所有的押注记录,查询时,也可以节约tair网络交互延迟;
2、version=2,确保只有第一次才能写入成功;(第一次写入成功后版本为1,传入非1的数字都会cas校验失败,不能写入)
3、写入失败时,不会立即反查一次,而是让前端友好提示,这样在重试时,其实已经错开了峰值;
互联网导播控制台
也就是我们的“核按钮”所在。说到这里,有必要说一下“互联网导播”这个职业,这个职业也是双11天猫晚会首创,去年才有。类似于电视导播,在导播车盯着十几个摄像机机位画面,将最好的画面切换给观众。互联网导播则是将最合适的互动内容(可以是匹配电视舞台内容或业务场景需要给的内容),切换给成千上万、甚至上亿的手机设备。这个工作会更个性化、更复杂,也更有挑战。
区别于电视导播的控制台,互联网导播使用的是自定义的H5页面控制台。2015年的第一版是这样的,巨丑版:
2016年,我们用上了Bootstrap,漂亮多了。
然而无论样式是怎样的,这个控制台都需要有如下特点:
1、一键式。任何场景,同一时间的指令,导播只需要点一个按钮。(人需要有反应时间,所以一般只来得及点一次。)
2、信息要全。要关注的信息,比如输入&输出&反馈,要一目了然,不需要再开新窗口。
3、预案灵活。百密也总有一疏,用于修复&纠正的预案,总是要有的。
剩下的,就是等待晚会开始,Rock&Roll !
跨终端Web动画制作工具
这是本次晚会前端的一个技术亮点:产出了通用动画导出工具。由于这是一场时尚的晚会,很多明星大腕,对视觉的要求也会非常高,尤其是对展现给用户的动画特效,更是苛刻的要求。素材制作上,设计师给出的视觉呈现,就给前端同学带来不小困难,比如:酷炫的动画过于复杂,如果按照视觉稿一帧一帧还原的话,需要耗费极大的人工成本,而且一旦动画出现需求调整,对前端开发人员来说,简直就是灾难,时间精力完全耗不起。
这种情况下,机智的晚会开发同学产出了通用动画导出工具,设计师只需要使用 After Effector(AE) 制作动画,前端就可以通过写 ExtendScript 脚本导出动画数据,优化、解析动画数据后,使用 canvas 来播放动画。
开启AR跨屏抢星衣
“跨屏抢星衣”是今年准备的一个特色环节,导演组安排了刘浩然和林志玲两位明星,在某个节目中各丢出一件衣服,电视机前的观众,拿起手机可以参与抢“原味星衣”。明星在丢衣服之前,主持人会口播提示用户“使用手淘或者猫客的摄像头对准屏幕”,用户手机对准后,客户端通过 AR 识别技术进行识别和定位,识别成功后,在明星丢出衣服的瞬间,用户在手机上会看到衣服从电视中浮出,砸碎屏幕,到了自己的手机上,效果如图:
做到这点,需要各个环节恰到好处的衔接。逻辑如图:
这个衔接,一方面是明星、电视导播、互联网导播,对于内容Q点的约定,另外一方面,是基于前面说过的技术(推拉结合预告手机端),才能让互联网导播的按钮指令,及时的下达到手机。另外,值得一说的是,猫客在AR这块,用了一个使用率较低、视觉融合较难,但是效果却特别好的开源算法(Traditional Template Square Marker),建议可以了解一下,多一种选择总是好的。参看:
https://artoolkit.org/documentation/doku.php?id=3_Marker_Training:marker_training
感想&展望
双11晚会,在技术眼中,就像是码农们进了娱乐圈,连代码都需要写的高大上。要应对各种集中的流量(口播、Q点、抢)、还要把已经很酷炫的视觉稿还原的更加酷炫。在观众看着电视明星流口水的同时,还能参与互动,给心仪的明星支持,然后拿到礼品。这需要有着如丝般柔顺的体验,用户才会愿意玩。
这些特性,在晚会史上都是前无古人的。即便是双11天猫晚会本身,在2016年也是超越了2015年太多的。可以预见的是,明年肯定有更多想不到的玩法,我们不断的创新,只为更high更好玩。各种新的技术,新的玩法,新的可能性,只有想不到,没有做不到。
回想起晚会平稳落幕的瞬间,技术人员内心的喜悦,是无法比拟的。本届互联网导播,控制核按钮的“那之手”说:我感觉更加耐操了,以后各种互动都不怕了!期待明年晚会的新挑战!