Pravega是一个开源的流式存储系统,为连续和无界数据实现流式存储。本章节将分为一个系列讲述Pravega的一些基本概念。

Streams

Pravega将数据组织到Streams中。Stream是一种持久,有弹性,append-only,无限制的字节序列,具有良好的性能和强大的一致性。Pravega Stream这个语义与当前很流行的面向消息的中间件(如RabbitMQ或Apache Kafka)中的“topic”类似但更灵活。

Pravega Streams是基于append-only的日志数据结构。通过使用append-only日志,Pravega可以快速将数据提取到可持久化的存储中,也可以支持流处理,工作流引擎,面向事件的应用程序,比如Flink,发布/订阅消息,NoSQL数据库(如时间序列数据库)(TSDB)等。

当开发人员在Pravega中创建Stream时,他/她会先给Stream定义一个名称,例如“IoTSensorData”或“WebApplicationLog20170330”。Stream的名称可以帮助其他开发人员了解存储在Stream中的数据类别。值得注意的是,Pravega Stream名称是在一个Scope内组织的。Scope是一个字符串,用于数据分类,它会向开发人员传达某种含义,比如“FactoryMachines”或“HRWebsitelogs”。Scope用作Stream名称的命名空间 - 所有Stream名称在Scope中都是唯一的。因此,Stream通过其Stream名称和Scope的组合唯一标识。Scope可用于按租户(在多租户环境中),按组织中的部门,按地理位置或开发人员选择的任何其他分类来命名。

Pravega的Stream大小无限制 – Pravega本身不会对Stream中可以有多少event或Stream中存储的总字节数施加以任何的限制。Pravega的设计原则是支持从几台机器的小规模到整个数据中心的大规模。

为了处理Stream中潜在的大量数据,Pravega Streams分为Stream Segments。Segment是stream中的Shard或Partition。我们稍后将在本文档中详细介绍Stream Segments。Stream Segments是一个重要的概念,但在我们深入了解Stream Segments之前,我们还需要介绍一些其他概念。

应用程序(例如从IoT传感器读取的Java程序)将数据写入Stream的尾部(前端)。应用程序(如Flink)也可以从Stream中的任何位置读取数据。多个应用程序还可以并行读写相同的Stream。弹性且可扩展地支持大量的Streams,支持大规模的数据和应用程序是Pravega的核心设计思想。在详细介绍reader和writer时,我们将会介绍应用程序如何读取和写入Streams。

Event

Pravega的客户端API允许应用程序根据event在Pravega中读取和写入数据。event是Stream中的一组字节。event可以像来自IoT传感器的温度读数只包含少量的字节一样简单,该传感器由时间戳,度量标识符和值组成。event可以是与用户点击网站相关联的Web日志数据,也可以是表示为一组字节的任何事物。应用程序使用标准Java序列化器和反序列化器来理解event,允许它们使用类似的技术在Pravega中读取和写入对象,以便从文件中读取和写入对象。

每个event都有一个路由码。路由码允许Pravega和应用程序开发人员推断哪些event是关联的。路由码只是开发人员用于将类似event组合在一起的字符串。路由码通常是从event中自然发生的数据派生出来的,例如“customer-id”或“machine-id”,但它也可能是一些人工字符串。路由码也可以类似于日期(按时间将event组合在一起),或者路由码可能是IoT传感器ID(按机器对event进行分组)。路由码对于定义Pravega 保证的精确读写语义非常重要,稍后我们将详细介绍。

Writer Reader and ReaderGroups

producer.consumer.client.new

Pravega提供了一个用Java编写的客户端库,它为Writer和Reader应用程序实现了一个方便的API。Pravega Java客户端库封装了用于Pravega客户端和Pravega之间通信的协议。

Writer是一个创建event并将其写入Stream的应用。所有数据都可以通过append到Stream的尾部(前面)来写入。

Reader是一个从Stream读取event的应用。读者可以从Stream中的任何一点读取。一些Reader从Stream的尾部读取event。这些events将会尽可能快地被发送给这些reader。一些Reader从Stream的头部读取(称为追赶读取)。应用开发人员可以控制Reader开始读取的Stream中的位置。Pravega具有Position的概念,它表示Reader当前所在的Stream中的位置。位置对象可以用作恢复机制-应用保留Reader最后成功读取的位置,如果读失败了就从这个保存的位置从新开始读。

使用这种持久化Position对象的模式,Reader被组织成ReaderGroups。ReaderGroup是一个命名的Reader集合,它们一起并行读取给定Stream的事件。当通过Pravega数据平面API创建Reader时,开发人员包含它所属的ReaderGroup的名称。我们保证发布到Stream的每个事件都被发送到ReaderGroup中的一个Reader。ReaderGroup中可能有1个Reader,也可能有多个Reader。同一个Stream可以同时被不同的ReaderGroup读取。

您可以将ReaderGroup视为“复合阅读器”或“分布式阅读器”,它允许分布式应用程序并行读取和处理流数据,以便协调的ReaderGroup可以使用大量的流数据。在ReaderGroup中,并行处理流数据的Flink是ReaderGroup的一个很好的用例。

更多关于Pravega Reader和Writer如何使用的详细信息,请参阅 使用Pravega:基本Reader和Writer章节。

我们需要更详细地讨论Reader,ReaderGroup和Streams之间的关系以及Pravega提供的顺序保证。但是,我们需要先描述一下segment是什么。

Pravega入门

了解Pravega最好方法就是自己动手部署一个,然后跑一把Pravega示例。

部署Pravega其实很简单,以下是步骤:

Java版本:Java 8

下载Pravega

可以从 https://github.com/pravega/pravega/releases 下载Pravega编译好的发行版。如果您想自己构建Pravega,也可以自己下载代码并运行:

1
$./gradlew distribution

多细节可以查看Pravega README.md

解压:

1
$ tar xfvz pravega-0.1.0.tgz

然后以standalone模式运行Pravega,这种模式会在本地机器上启动Pravega的所有组件。注意:这仅用于测试/演示目的,请勿在生产环境中使用!更多内容请 查看

1
2
$ cd pravega-0.1.0
$ bin / pravega-standalone

执行这个命令即可拉起一个本地化的pravega 集群, 这样就可以跑pravega。

Pravega“Hello World”示例

Pravega为示例维护一个单独的github库:https://github.com/pravega/pravega-samples

Pravega依赖关系会自动从maven中心拉下来。注意:示例还可以使用本地编译的Pravega。有关这方面的更多信息,请参阅README.md中maven发布的注释。

下载Pravega-Samples git库

1
2
$ git clone https://github.com/pravega/pravega-samples
$ cd pravega-samples

生成示例程序

1
$ ./gradlew installDist

运行示例“HelloWorldWriter”,将“hello world”消息作为事件写入Pravega stream。

1
2
$ cd pravega-samples/standalone-examples/build/install/pravega-standalone-examples
$ bin/helloWorldWriter

HelloWorldWriter的输出

1
2
3
...
Writing message: 'hello world' with routing-key: 'helloRoutingKey' to stream 'examples / helloStream'
...

若想使用不同的参数运行HelloWorldWriter,更多信息请参阅pravegs-samples中的readme.md文件

运行示例“HelloWorldReader”

1
2
$ cd pravega-samples/standalone-examples/build/install/pravega-standalone-examples
$ bin/helloWorldReader

示例HelloWorldReader的输出

1
2
3
4
5
6
...
Reading all the events from examples/helloStream
...
Read event 'hello world'
No more events from examples/helloStream
...

有关HelloWorldReader的更多详细信息,请参阅pravega-samples中的readme.md文件

当前的大数据处理系统无论是Lamda架构还是Kappa架构都面临一个问题,即:“计算是原生的流计算,而存储却不是原生的流存储” 。

作为存储业界首屈一指的领导者,DELL EMC的存储专家们重新思考了这一基本的数据处理和存储规则,为这一场景重新设计了一种新的存储类型,即原生的流存储,命名为”Pravega”,在梵语里是“Good Speed”的意思。

Pravega是一种流数据存储系统,其具有可持久化,弹性,数据只追加,字节序列无限制,性能良好和强一致性的特点。并且根据Apache 2.0许可证开源,DELLEMC的存储专家们相信这一颠覆性的技术应该开源出来与开源社区一起拥有与推动,Pravega相应的介绍以及代码可以从pravega.io获得。

主要特性

  • 正好一次 – 不管是客户端、服务端还是网络出现了故障,Pravega都能确保每个事件都只被传递和处理正好一次(exactly-once)。

  • 自动伸缩 – 不同于静态分区系统只有固定大小的存储空间,当数据采集速率发生变化时Pravega可以根据场景自动调整空间大小以自动适应数据规模的变化。

  • 分布式计算原语 – Pravega具有和zookeeper一样的选主功能,支持进程间传递消息,支持数据存储,非常适用于分布式计算场景。

  • 写入效率好 – 目前Pravega 的写入时延在毫秒级,还能无缝的扩展以支持数千个客户端的同时并发读写,是IOT和其他时延敏感型应用的理想选择。

  • 无限保存 – 数据永远都在流中采集、处理和保存,对于实时数据和历史数据使用一样的处理范式。

  • 高效存储 – Pravega构建了一种数据处理通道,支持将批处理,实时处理以及其他应用比如数据检索,都构建在一个数据处理通道内,无需为每个处理模式都保留一份数据副本。

  • 持久化 – Pravega保证无需在高性能,可持久化和一致性之间做权衡,在客户端确认写入操作已完成之前,Pravega将一直存留并保护数据。

  • 支持事务 - 开发人员使用Pravega事务来确保一组事件原子性的写入流中。