文 / Drew Koszewnik
译 / John
原文 https://medium.com/netflix-techblog/re-architecting-the-video-gatekeeper-f7b0ac2f6b00
此文将与您分享我们的内容设置工程团队如何使用基于Netflix OSS技术的,被称为“Hollow”的Java库与工具包,简化并重新构建内容传输基本组件的历程———这段经历带给我们产业价值方面的收获,令我们受益匪浅。
上下文
Netflix平台上的每部电影与电视节目都经过精心策划以确保观众可以收获最佳观看体验,负责此策划展示的团队是“Title Operations”(标题运营)团队。此团队负责运营并确保以下事项无误:
● 视频内容遵守合同或协议 - 视频拥有正确的日期范围与可被公开的合理标题。
● 视频带有字幕,字幕与配音正确无误且能够为世界各地的观众带来高质量观看体验。
● 标题名称与概要可供使用和翻译。
● 针对不同国家/地区都有符合当地法律法规的内容分级策略。
当标题满足上述所有内容的最低要求时,我们则允许其在该服务上生效。而Gatekeeper则是Netflix上一套负责评估网站上视频等资产“活跃度”的工具,在得到Gatekeeper的批准之前,此视频的标题不会对任何成员可见———如果此标题无法通过验证,那么系统将会通过指出其相对于基准用户体验缺少的内容,协助内容生产者重新考虑更加合适的标题。
Gatekeeper通过聚合来自多个上游系统的数据并结合应用一些业务逻辑,针对不同国家/地区背景,为每个视频内容生成详细说明,从而帮助内容生产者针对不同地区生产最符合当地用户观看习惯的视频内容作品。
技术原理
Hollow 是我们几年前 发布 的一套基于 OSS 的技术,准确地来说这是一个完整的高密度近缓存(high-density near cache),其具备以下三个特性:
● 一体化:整个数据集缓存在每个节点上,不存在驱逐策略且没有处于空闲状态的缓存。
● 高密度:采用编码、位打包(bit-packing)和复制数据删除(deduplication techniques)技术来优化数据集的内存占用率。
● 就近存储:缓存存在于需要访问数据集的任何RAM中。
这里我想强调一下此技术的重要特性之一——“一体化”。“一体化”意味着我们不必担心交换内存中的记录,同时可以进行诸如假设和预计算数据集的内存表示等,脱离“一体化”就不可能实现的功能,我们期待的最终结果是这些数据集能更有效地使用RAM。然而,对于传统的局部缓存解决方案,我们需要知道此方案是否可以只缓存数据集的5%,或者缓存是否需要为数据集10%预留足够的空间,从而确保命中/未命中率符合相应要求——如果内存量相同,则可以缓存100%的数据,命中率也可被设置并达到100%。
显然,如果想要获得100%的命中率,我们需要消除访问数据所需的所有I / O ,同时尽可能实现更高效的数据访问,这无疑为我们带来了许多可能性。
亟待解决的现状
直到最近,Gatekeeper才成为一个完全的事件驱动系统。当视频在其任何一个上游系统中被更改时,该系统将向Gatekeeper发送此事件。
Gatekeeper对于此事件的响应是访问其每个上游服务并收集必要的输入数据以评估视频及其相关资产的活跃度;随后Gatekeeper将产生一个单记录输出用以详细说明该单个视频的状态。
旧版本的Gatekeeper架构
我们需要明确与此模型相关的几个问题:
● 此过程完全受I / O限制,同时会对上游系统施加大量负载。
● 因此,这会导致这些队列中的事件将一直处于排队状态并出现处理过程的延迟,继而导致标题可能无法按时正常上线。
● 更糟糕的是,个别事件有时会被遗漏。这意味着在标题运营团队的某位成员意识到这些问题之前,标题可能根本不会生效。
解决这些问题的方法是“扫描”目录,以便将符合特定标准的视频事件(例如:计划下周发布)自动加入处理队列。不幸的是,此方法会将更多的事件添加到队列当中,这无疑加剧了问题的严重。
建设性想法
我们决定采用全高密度近缓存(即Hollow)来消除这一I / O方面的瓶颈。对于每个上游系统,我们将创建一个Hollow数据集,其中包含Gatekeeper执行对其评估所需的所有数据。这样,每个上游系统都能负责更新其缓存。
新的Gatekeeper架构
利用该模型,我们可以从概念上将活跃性评估与上游系统的数据检索两大过程分离开来。Gatekeeper不会直接对事件作出反应,而是在一个重复的周期内,连续地评估所有国家所有视频中所有资产的活跃性。此循环迭代将涉及Netflix上的每个可用视频,同时系统也将计算每个视频的活跃度细节。在每个周期结束时,Gatekeeper会生成一个完整的输出(也是一个空数据集)用以表示所有国家所有视频的活跃状态细节。
我们期待实现这样一个“连续处理”模型,因为完全消除I/O瓶颈意味着我们能够更有效地控制数量级。我们认为,这种模式能为我们带来更多产业价值方面的收获:
● Gatekeeper可生成一套针对上游系统超额负载的明确解决方案
● 事件处理延迟会被完全消除,内容生产者不用担心标题错过上线日期。
● 有效减少内容运营工程团队在处理与性能相关的问题上所花费的时间。
● 改进了可调试性和活跃度处理的可见性。
随之而来的问题
Hollow更像是一台“时间机器”。在数据集随时间变化的同时,Hollow会通过将时间线分解为一系列(离散数据状态),以便于将这些更改传递给消费者。每个(数据状态)表示特定时刻整个数据集的快照。
Hollow就像一台时间机器
通常情况下,Hollow数据集的使用者会加载最新的数据状态,并在生成新状态时保持其缓存更新。但是,使用者可能会指向先前状态,并将整个数据集的视图恢复至过去某个时间点。
生成数据状态的传统方法是维护运行一个重复“循环”的单个生产者。在一个“循环周期”中,内容生产端会迭代所有源自真实来源的记录。当迭代进行时,系统将每个记录添加到Hollow库中。随后Hollow计算在此周期中添加的数据与上一个周期中添加的数据之间的差异,并将状态发布到消费者已知的位置。
传统的Hollow用法
这种全真实迭代模型的问题在于其所花费的时间十分漫长。对于一些上游系统来说可能需要数小时。如此夸张的数据传播延迟是不可被接受的——例如,如果标题运营者需要为即刻上线的电影添加评级,那么他们则需要为正在进行的实时处理耗费数小时的等待时间。
改进策略
我们需要的是一台更快的时间机器——一台具备更高处理效率的机器,只有这样消费者才能切身体验到技术带来的直观优化感受。
增量Hollow就像一台更快的时间机器
为了实现这一目标,我们首先创造了必要的增量Hollow基础组件以充分利用早期Hollow的库与工具包,并将其作为一个公共的非测试API,率先用于流媒体平台团队。
使用此基础组件,每当系统在源应用程序中检测到更改时,更新的记录都会被编码并发送到Kafka的Topic。而那些不属于源应用程序的新组件“Hollow 增量生产者”服务则会以预先定义好的节奏执行重复循环。在每个循环期间,此组件会读取来自上一个循环并已添加到主题的所有消息,同时改变Hollow状态引擎以反映更新记录的新状态。
如果来自Kafka Topic的消息中包含与Hollow数据集中已反映的部分完全相同的数据,则不执行任何操作。
Hollow增量生产服务
为了解决事件错过引起的一系列问题,我们实现了一个可周期性迭代的针对整个源数据集的扫描机制。在迭代时,系统将记录下的每条内容发送到Kafka Topic。这就使得任何可能遗漏的更新最终都会反映在Hollow数据集中。此外,由于这不是将更新传递至Hollow数据集的主要机制,其也不必如上文提到的用于传统Hollow的迭代源那样,快速或频繁地进行循环过程。
Hollow增量生成器能够从Kafka Topic中读取大量消息并在内部快速改变其Hollow状态,这也就是为什么我们可以将其循环的时间配置得非常短(我们目前将此默认为30秒)。
这就是我们构建更快时间机器的整个过程。现在,如果标题运营人员需要在即将上线的电影中快速添加电影等级,那么在30秒内该数据即可实现在相应的Hollow数据集中可用。
触手可及的成果
随着数据传播延迟问题得到了妥善解决,我们能够基于全新的Gatekeeper系统消除所有I / O边界。通过Gatekeeper的预判和决策,我们得以重新评估所有国家/地区中所有视频的所有资产,而这一切在此之前都是不可想象的——以往条件下这些工作会占用整个内容传输通道超过一周的时间,而现在只需大约30秒即可完成;与此同时,事件被错过或评估被延迟也成为了历史,而先前Gatekeeper系统被禁用也减少了我们上游系统的负载,在某些情况下甚至降低了80%。
显著减少上游系统的负载
除了以上性能参数上的优势之外,我们还获得了弹性优势。在先前的Gatekeeper系统中,如果其中一个上游服务出现故障,由于无法从该系统检索到任何数据,我们根本无法评估活跃性情况;而新Gatekeeper系统下,如果其中一个上游系统出现故障,尽管该系统会影响数据的实时发布,但我们仍能够为相应的数据集提供旧数据,同时其他所有数据集不会受到影响。例如在电影片场,如果故事大纲的翻译系统出现故障,那么在紧急上载正确的数据之后,我们仍然可以在当前片场继续拍摄电影。
无形的成果
比性能提升更有益的是,我们在该系统中的开发速度得到了显著的提高。以前动辄几天的开发工程现在仅需几分钟即可完成;而在原先的工作流程中,验证与发布可能需要几天或几周的时间,现在我们则利用相同的时间显著提升了发布的质量。
Hollow这一“时间机器”意味着每次使用Hollow作为输入数据的可靠途径,整个过程是100%可重复的。对于Gatekeeper来说,这意味着可以通过将所有输入状态恢复为时间X随后再次重新评估所有内容,从而完成对在时间X时所发生事件的精确重放。
我们利用这些特性,通过快速迭代以实现对Gatekeeper业务逻辑的更改。下图展示了我们维护一个PREPROD Gatekeeper的实际案例,PREPROD不断评估整个目录的活动性,同时其输出将会被发布到不同的Hollow数据集。在每个循环开始时,PREPROD环境将从PROD收集最新生成的状态,并将其每个输入数据集设置为与用于生成PROD所输出的完全相同的版本。
instancePREPROD Gatekeeper实际案例:“跟随”PROD实例
当我们想要对Gatekeeper业务逻辑进行更改时,我们会依据上述内容进行调整,然后将其发布到PREPROD集群。而PREPROD之后的输出状态可以与其之前所对应的输出状态区别开,开发者可通过访问PROD精准查看到逻辑改变所导致的精确效果,一目了然。以上工具帮助我们验证多项优化带来的改变精准符合预期,同时不会造成其他任何意想不到的不良影响。
Hollow产生的差异与确切的变化可以被直观看到
与部署过程的一些迭代相结合,上述一系列改进使我们的团队能够在几分钟内实现对Gatekeeper编码的关键性调整,同时完成验证、部署等一系列关键步骤,其不仅带来了一个数量级的速度提升,还让架构的整体安全性达到了前所未有过的高度。
结论
Gatekeeper系统的上述一系列改进措施,为我们收获额外的业务价值提供了机会,我们计划在未来几个季度实现这一目标。此外,这种模式可以被复制到内容工程领域等Netflix其他系统,我们也已经启动了多个后续项目从而正式化充分利用n-hollow-input架构的优势。
内容运营工程现在进入了一个崭新的发展阶段,特别是当我们扩展了我们的工作流程之后,我们得以借同样的时间生产出比以往单位时间内所能产出的更多内容。这也让我们有更多机会解决实际问题并发掘业务背后隐藏的巨大价值:借计算机科学的力量,开拓技术无限可能。
————————————————
版权声明:本文为CSDN博主「LiveVideoStack_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/100017578
「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。