【Netflix Hollow系列】深入Hollow底层读写引擎及体系架

前言

作为Hollow系列的开篇,首先向大家介绍下Hollow是什么,可以做什么。Hollow是由Netflix开源的一款 Java 库和工具包,旨在有效缓存不属于“大数据”的数据集,这些数据集可以存放在本地磁盘,也可以存放在像S3这样的存储中。

Hollow基于Producer-Consumer模型定义了如何处理这些数据集,通过Producer生产Blob,然后被Consumer消费。能够为企业级元数据管理提供可靠的数据模型能力。

在国内关于Hollow的文章并不多,或者说只有一两篇介绍Hollow的文章,这几篇文章都缺少对整个Hollow的体系和设计结构的详细分析和介绍,这也让我感觉到有必要将Hollow介绍给大家。

面临的问题

架构复杂

业务系统在启动时,需要将计算过程中使用到的缓存数据加载到内存中,而这些缓存的数据很可能是存储在MySQL或者由服务通过API的形式提供。此时,我们的服务会形成一种简单的处理模型。

以上模型,对于简单的系统来讲已经足够满足业务需要,但是当系统复杂起来后,可能会变成如下图所示的模型。

上图中只是列举了两个DB,四个服务。当系统更为复杂后,这个关系将变成一团乱麻。可能一开始的刚刚接入的时候还可以忍受,但是当系统不断迭代,人员不断流动后,整个系统将变得难以维护,最终的结局可能就是推倒重构了。

重复工作

从上图中可以看出,Service-A需要依赖DB-1和DB-2两个数据库,同时,Service-B也需要依赖相同的两个DB。由于数据模型相同,加载方式也想通,Service-A和Service-B需要做相同的事情,如果Service-A和Service-B是在同一个团队中那么可能会统一抽象后进行封装避免重复工作,但是当不再一个团队中时,重复的工作可能就无法避免了。

Hollow是什么

Hollow是为了处理小型缓存数据集而设计的工具包。这些数据集可能是系统使用的元数据,类似于演员姓名、城市名称、国家代码、地理位置等。很多的元数据构成了不同业务模型的数据集,处理这种数据集的传统方法包括数据存储或串行化,但这可能会有可靠性和延迟问题。

在Netflix的内部,Hollow 取代作为取代原先的内存数据集框架Zeno被设计出来的。Hollow的数据集使用了紧凑的、固定长度的、强类型的数据编码表示。这种编码最小化了数据集占用的空间,并将编码记录“打包在 JVM 堆上合并的可重用内存条中,以避免影响繁忙的服务器上的 GC 行为。

Hollow官方对于Hollow设计出发点的阐述。

Software engineers often encounter problems which require the dissemination of small or moderately sized data sets which don’t fit the label “big data”. To solve these problems, we often send the data to an RDBMS or nosql data store and query it at runtime, or serialize the data as json or xml, distribute it, and keep a local copy on each consumer.

Scaling each of these solutions presents different challenges. Sending the data to an RDBMS, nosql data store, or even a memcached cluster may allow your dataset to grow indefinitely large, but there are limitations on the latency and frequency with which you can interact with that dataset. Serializing and keeping a local copy (if in RAM) can allow many orders of magnitude lower latency and higher frequency access, but this approach has many scaling challenges:

  • The dataset size is limited by available RAM.
  • The full dataset may need to be re-downloaded each time it is updated.
  • Updating the dataset may require significant CPU resources or impact GC behavior.

Netflix, serving many billions of personalized requests each day, has a few use cases for which the latency of a remote datastore would be highly undesirable given the frequency with which those datasets are accessed.

这里有一篇Hollow的主要作者Drew Koszewnik 介绍Hollow的访谈 ,有兴趣可以看下。

Hollow设计的目标

Hollow 在被设计之初,便围绕着以下三个目标展开:

  • 最大的开发敏捷性
  • 高度优化的性能和资源管理
  • 极高的稳定性和可靠性

开发敏捷性

开发敏捷性不仅仅针对Consumer,同时也针对Producer;可能用客户端服务端的描述更容易理解些。Hollow提供了基于HollowSchema的数据模型生成能力,通过HollowAPI体现出来。HollowAPI实际查询的数据集可以被轻松的进行索引,以实现快速的查询,此外还可以轻松实现Producer的数据merge和split,以及在Consumer的数据filter。

同时,Hollow还提供了丰富的UI工具,包括历史工具、对比工具、视图工具等。

上面的这些功能会大幅提升我们的开发效率,使得我们的开发变得更加敏捷高效。

优越的性能

通常情况下,对于缓存我们会有两种方式,一种是全量的替换,一种是增量的更新。Hollow将增量更新的逻辑进行的封装,可以方便的管理增量的数据。这样做可以无需为每次更新重新传输整个全量的数据,对于性能有较为显著的提升。如果不这样做,我们可能会遇到的一个经常的会出现的场景是,当服务端更新缓存时,客户端的响应时间会有明显的上升。

此外,Hollow基于池化的思想,可以方便的重用堆内存,进而对GC产生了很大帮助。

Hollow主要考虑的性能因素包括:

  1. 堆足迹
  2. 访问的计算成本
  3. 更新的 GC 影响
  4. 更新的计算成本
  5. 网络更新成本

Hollow的适用场景

上文中大体介绍了Hollow的设计初衷和可以完成的功能。本章节介绍下Hollow的适用场景。

H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值