GMTC北京站9折购票倒计时,部分日程已上线,戳此查看 了解详情
写点什么

Drew Koszewnik:弥散性缓存 Netflix Hollow

  • 2016 年 12 月 28 日
  • 本文字数:3588 字

    阅读完需:约 12 分钟

Netflix发布了基于Java 的通用缓存项目Hollow 来缓存元数据。

在数据保存到集中式存储时,常常使用缓存技术去突破网络延迟、带宽等限制。在缓存数据的过程中,开发者经常要面对一个挑战,就是如何缓存频繁访问的本地数据和保存很少访问的远程数据。但如果能缓存所有需要访问的数据,那么实现我们的应用会更容易。Hollow 采用了将所有数据提供给每一个消费者的方法,而不是将数据分布到多台服务器上,不得不为数据的持久性而考虑用什么算法去复制。

Hollow 的前身是 Zeno ,它把数据作为普通 Java 对象(POJO)来保存,导致存储空间受到了限制。Hollow 则采用了一种紧凑、固定长度、强类型的数据编码方式避免了这个问题。

InfoQ 采访了 Netflix 的高级软件工程师和主要贡献者 Drew Koszewnik,向他请教了这个项目中的一些具体细节。

InfoQ:Hollow 和其它缓存产品,特别是 Memcached 相比,有什么不同?如果开发人员已经在使用别的产品,在什么情况下他们可能会转而关注这款全新的高速缓存产品?

Drew Koszewnik:Memcached 做得很好,在 Netflix 我们曾经用 EVCache 得到了很大收益,它可以适用于 Hollow 将要面对的缓存数据尺寸等问题。另一方面,Hollow 在别的一些问题上比 Memcached 解决得更有效,特别是在跨服务器编队中如何复制整个数据集。虽然在很多情况下,工程师们对这样做是否可行持怀疑态度,但其实会发现它的表现比预期更好。你可以认为 Hollow 是一种把你的数据集压缩到内存的方法,还能对它的任何部分提供 O(1)的访问速度。

Memcached 的主要好处是它是一个分布式缓存系统,通过很多分布式的实例来形成整个内存缓存池,但它仍然是一个中心化的系统。而我们认为 Hollow 不是一个真正意义上的分布式缓存系统,它其实是一个弥散性的系统。我们选用弥散性这个单词(分布式的反义词)来表示把整个数据集复制给每一个消费者。

Hollow 是为了满足 Netflix 对高吞吐量缓存的需求而创建的,大多数的设计决策最终都源自这个要求。对每一个消费者交互复制整个数据集意味着我们不必通过网络跳转来获取任何数据,所以访问数据集的任何部分所需的延迟是可以忽略不计的。对整个数据集范围内任何数据部分的访问所产生的 CPU 成本,Hollow 也非常关心。和 Memcached 那样松散类型的键 / 值存储不同,Hollow 采用强类型和结构化数据模型,这样可以定位消耗在数据访问上的成本问题,并在许多不同的场景中实现重用。我们选择去构建一个强类型的系统,先理解数据结构再建立各种工具。 History diff 就是其中两个很好的工具,因为我们清楚数据模型,就能解释不同的两个状态之间究竟有什么变化,并围绕这些变化构建一些真正有用和通用性的应用界面元素。

顺理成章,有了完全本地结构化的数据后,在设计数据模型时你不必去考虑到底数据会被怎么使用。而在 Memcached 系统中,你不得不提前了解消费者会如何使用这些数据(它们只能利用预定义的键值来查询)。而在 Hollow 中,消费者团队可以自由地开发数据的访问模式,生产者团队也不会因此成为开发瓶颈。Hollow 在消费者端采用索引而不必在生产者端生成预定义索引,通过这种方式实现了访问模式的解耦。

InfoQ:它适用于只读数据、单生产者、多消费者的场景吗?您能详细介绍下数据是如何被持久化的吗?

Koszewnik:是的,它适用于只读数据、单个生产者、可能多个消费者的情形。Hollow 实现持久化的唯一机制是利用 BLOB 存储,它只是一个文件存储,可能是 S3、NFS、甚至一台 FTP 服务器。启动的时候,消费者们读取整个数据集的快照,并将数据集引导到内存中。通过增量的方法,可以保证内存中的数据集是最新的。对于每个消费者,内存中的数据备份是临时性的,如果消费者重新启动,需要从 BLOB 存储中重新加载快照。

实际上 BLOB 快照文件的格式很简单,它在很大程度上和在内存布局的结构相同,因此数据初始化主要是将 BLOB 的内容直接复制到内存中,这一步可以快速完成,确保了初始化的时间很短。

InfoQ:它能解决 CAP 定理中列出的问题么?例如,当出现间歇性的网络连接问题时,怎么处理过时数据?

Koszewnik:因为 Hollow 不是传统意义上的分布式存储,针对这个网络连接的问题对于 CAP 定理会有一些不同的考虑。我想你可以认为,Hollow 通过牺牲一致性来满足了可用性和分区容错性。

由于消费者都在 RAM 中保留了一份数据集的全拷贝,所以可用性是非常好的,一旦消费者完成初始化,完全不会受到由于环境不同而带来的问题所影响。至于分区容错性,它没有任何分区,对于每个消费者而言要么拥有整个数据,要么就没有。

一致性是比较有趣的话题,Hollow 将随时间而变化的数据集切割成离散的数据状态,每一个部分是特定时间点的数据快照。按照有规律的节奏,可以每隔几分钟生成这些快照。因此,必须要在一定程度上容忍数据集的传播延迟。你可以采取一些别的措施来缓解这个问题,例如,通过单独的渠道发送紧急更新来覆盖数据。

InfoQ:这种缓存机制并不是对所有的数据都有效,主要还是针对较小的元数据,对吗?如果本地服务器上的内存资源被耗尽会发生什么?

Koszewnik:对,Hollow 主要针对中小型数据集。根据经验,MB 到 GB 的数据规模比较合适,TB 或者 PB 就有点问题了。在因为一个数据集对于 Hollow 来说过大而被排除掉之前,不妨再考虑下,一个接近 1TB 的基于 JSON 的文档如果存在 Hollow 中会节省很多的空间。Hollow 的超高效存储性能结合一个优化后的数据模型可以把大的数据集转变成中等的。

正如 Google 的 Jeff Dean 所教导的,系统设计应该考虑数据增长性,确保它能在 10 倍或 20 倍数据增长情况下正常工作,暂时还不需要考虑 100 倍时的情况。这里 Hollow 的规则是,面对不断增长的数据集,提供一些工具对堆栈使用率进行细粒度分析,从而识别出要优化的目标。把分析出的指标按照时间做比较,这对于在早期发现潜在问题是非常有用的。特别要留意如果某个类型的数据出现了超线性的增长,也许就是数据模型设计得不够优化的信号,或者是新的增长维度被忽略了。

数据的建模在这里非常重要,数据结构化方法对 Hollow 删除重复数据的效果有着巨大影响,也决定了能压缩多少数据。一种通用的压缩算法是利用数据的特性来构造 Huffman 树,而 Hollow 是用数据模型里的记录结构作为数据特性。虽然这样做需要事先知道记录的结构,但关键是保持了随机访问的高吞吐量,同时实现了很好的压缩率。

InfoQ:请谈谈压缩算法,是什么让你们没有采用 POJO?

Koszewnik:Hollow 通过很多不同的方式实现压缩,其中包括去重、编码、打包、释放 Java 对象。虽然 Zeno 提供了去掉重复数据的方法,但如果不抛弃 POJO,我们也许就不能实现编码、打包、对象释放了。

再来说说性能,我们需要一种手段,以便在访问 Hollow 数据集时既能对 CPU 影响最小,又能让数据显示所需的堆占用最小。在数据布局时,我们在数据末尾用了一个固定长度的位对齐,这样每个字段占用所有记录最大值所需的字节数。然后,利用非对齐内存访问等技术来最小化检索数据所需的指令数。如果这样优化,Hollow 就可以支持 x86-64 框架,该框架目前要求用低字节序来排序,并且假定非对齐访问不会导致(或可以忽略)性能损失。在未来,会利用这些优化方案来实现更大的可移植性。

InfoQ:关于 Java 还有两个问题。为什么决定使用 Java 来实现(而不是 Go)?non-Java 的应用可以采用 Hollow 吗?

Koszewnik:我们用 Java 来实现 Hollow,因为我们每一个客户系统都用基于 JVM 的开发语言来建立它们的视频元数据,而基于 non-JVM 的语言目前还不能利用 Hollow。

InfoQ:最后一个问题。它是专门为 AWS 和 S3 特制的么?您能分享一些它的基准测试或者发展路线图吗?

Koszewnik:不,Hollow 没有提供或者特指什么架构,只是把产生的 BLOB 从生产者扩散到消费者。如果潜在的用户开始阅读快速启动指南,它介绍了如何嵌入基于AWS 的S3/DynamoDB 架构,也用一个项目示例介绍了如何实现可伸缩性的。不过相对容易点的,是把这些例子当成指南,学会在任何架构下实现_Publisher_、 AnnouncerHollowBlobRetrieverHollowAnnouncementWatcher

而对于不同的数据模型来说,它们各自的基准测试有很大的不同,所以我尽量避免下什么结论,因为用例的不同会误导出另一个方向的结论。可以下的结论,只是相比较 POJO 而言,Hollow 使用记录来访问数据,以极小的代价大大的减少了堆占用。

也没有严格的发展路线图,虽然有几件事我真的很希望能去解决,但从发展的角度看更希望能从我们的社区得到一些反馈。特别希望通过我们的努力,这个项目能让可用性得到极大的改进。

Hollow 的 github 网站提供了更多信息以帮助如何开始学习。

查看英文原文 Q&A with Drew Koszewnik on a Disseminated Cache,Netflix Hollow


感谢冬雨对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016 年 12 月 28 日 18:0011452
用户头像

发布了 40 篇内容, 共 30.1 次阅读, 收获喜欢 129 次。

关注

评论

发布
暂无评论
发现更多内容

啃书一年多的我,推荐Python初学者不要在乱看书了,有这三本就妥妥的

冇先生

API网关在API安全性中的作用

互联网架构师小马

TRTC代码示例文档集合完毕!哪里不会点哪里!

腾讯云音视频

腾讯云 音视频 API sdk

编译脚本:编写CMakeFile(一)

正向成长

CMakeFile

面试官:你了解JVM的锁优化吗?

百度开发者中心

Java 最佳实践 方法论 语言 & 开发

2021Java面经:Android屏幕适配-重点盘点

策划Java工程师

Java 程序员 后端

ironSource 在 2021 ChinaJoy 举办多场活动赋能中国开发者

Python代码阅读(第2篇):数字转化成列表

Felix

Python 编程 Code Programing 阅读代码

gitlab无法通过ssh拉代码

阿呆

#GitLab

当企业遭遇分布式拒绝服务 (DDoS) 攻击时,第一时间该如何进行操作?

九河云安全

频繁出现的分布式拒绝服务 (DDoS) 攻击​,有什么办法可以抵御吗?

九河云安全

区块链技术如何有效应对气候变化

CECBC

2021Java大厂面试集合,java多线程

策划Java工程师

Java 程序员 后端

2021Java春招面试真题详解,Git-如何优雅地回退代码

策划Java工程师

Java 程序员 后端

关于Spring注解开发教程,打包全送你

华为云开发者社区

Java spring 容器 注解 组件

FIL分币系统源码|分销商城功能开发模式介绍

Geek_23f0c3

fil Fil算力挖矿分币系统 Filecoin分销商城

DataPipeline荣膺CFS第十届财经峰会“2021数字化转型推动力奖”

DataPipeline数见科技

大数据 数据融合 数据管理

Java代码中,如何监控Mysql的binlog?

互联网架构师小马

Linux 网络管理技术 OSI 七层模型和 TCP/IP 四层模型

学神来啦

Linux 运维 IP

双非本化学跨专业,投岗阿里/滴滴后端三面,最终拿下offer

编程菌

Java 编程 程序员 面试 计算机

mybatis源码分析

普普通通程序员

下一个颠覆的领域:区块链如何影响审计行业?(下)

CECBC

Hologres揭秘:深度解析高效率分布式查询引擎

阿里云大数据AI技术

2021Java笔试题总结!Java个人学习之旅(第十天)

策划Java工程师

Java 程序员 后端

基于 Apache APISIX,新浪微博API网关的定制化开发之路

Apache APISIX 中国社区

Apache 网关 APISIX 微博

企业安全运维重点是什么?如何做?

行云管家

数据库 运维 企业管理 企业运维 安全运维

你使用的SimpleDateFormat类还安全吗?

华为云开发者社区

Java 安全 线程 高并发 SimpleDateFormat类

FastApi-04-请求体-1

Python研究所

FastApi 8月日更

从河南暴雨、疫情反弹看区块链“灾疫”治理

CECBC

防火墙 Keepalived 异常双活恢复后部分外网访问中断问题分析

Qunar技术沙龙

运维 防火墙 网络 故障诊断 keep-alive

2021年Java开发实战!仿微信的网络聊天室项目开发【完整源码讲解

策划Java工程师

Java 程序员 后端

Drew Koszewnik:弥散性缓存Netflix Hollow_语言 & 开发_Rags Srinivas_InfoQ精选文章