Pravega架构小结

架构

开源分布式流存储服务
本质是在计算引擎与底层存储间充当解耦层,旨在解决新一代大数据平台在数据存储层上的挑战

1、数据湖

Pravega 提供的 Stream 原语可以避免现有大数据架构中原始数据在多个开源存储搜索产品中移动而产生的数据冗余现象,其在存储层就完成了统一的数据湖(一处存储,多处使用)

2、区别

区别于lambda架构和kappa架构,以 Apache Flink 作为计算引擎,通过统一的模型/API来统一批处理和流处理。以 Pavega 作为存储引擎,为流式数据存储提供统一的抽象,使得对历史和实时数据有一致的访问方式。两者统一形成了从存储到计算的闭环,能够同时应对高吞吐的历史数据和低延时的实时数据
区别于kafka,Kafka定位是消息队列,Pravega定位是存储,更关注数据的动态伸缩、安全、完整等存储特性。对于流式数据处理来说,数据应该被视为连续和无限的,而Kafka作为基于本地文件系统的消息队列,采用添加到日志文件末尾并使用offset跟踪内容的方式模拟无限的数据流,这种方式必然受限于本地文件系统的文件描述符、磁盘容量上限,因此严格来说并非无限

3、流式存储的特点

对于来自序列旧部分的历史数据,需要提供高吞吐的读性能,即 catch-up read
对于来自序列新部分的实时数据,需要提供低延迟的 append-only 尾写 tailing write 以及尾读 tailing read

4、系统架构

在控制层面,Controller 作为 Pravega 集群的主节点对数据层面的 Segment Store做管理,提供对流数据的创建,更新以及删除等操作。同时它还承担实时监测集群健康状态,获取流数据信息,收集监控指标等功能。通常集群中会有3份 Controller 来保证高可用。
在数据层面,Segment Store 提供读写 Stream 内数据的 API。在 Pravega 里面,数据是分层存储的:
  • Tier 1 存储
Tier1 的存储通常部署在 Pravega 集群内部,主要是提供对低延迟,短期的热数据的存储。在每个 Segment Store 结点都有 Cache 以加快数据读取速率,Pravega 使用 Apache Bookeeper 来保证低延迟的日志存储服务。
  • Long-term 存储
Long-term 的存储通常部署在 Pravega 集群外部,主要是提供对流数据的长期存储,即冷数据的存储。不仅支持 HDFS,NFS,还会支持企业级的存储如 Dell EMC的 ECS,Isilon 等产品
 

概念

  • Stream:把写入的数据组织成 Stream,Stream 是命名的、持久的、仅追加的、无限的字节序列
  • Stream Segments:Stream 会划分为一个或多个 Segments,相当于 Stream 中数据的分片,它是一个 append-only 的数据块,而 Pravega 也是基于 Segment 基础上实现自动的弹性伸缩。Segment 的数量也会根据数据的流量进行自动的连续更新
  • Event:client API 允许用户以 Event 为基本单位写入和读取数据,Event 具体是Stream 内部字节流的集合。如 IOT 传感器的一次温度记录写入 Pravega 就可以理解成为一个 Event
  • Routing Key:每一个 Event 都会有一个 Routing Key,它是用户自定义的一个字符串,用来对相似的 Event 进行分组。拥有相同 Routing Key 的 Event 都会被写入相同的 Stream Segment 中。Pravega 通过 Routing Key 来提供读写语义
  • Reader Group:用于实现读取数据的负载均衡。可以通过动态增加或减少 Reader Group 中 Reader的数量来改变读取数据的并发度
 

关键特性

1、读写分离

读写分离有助于优化读写性能:只从 Tier1 的 Cache 和 Tier2 Long-term 存储去读,只从 Tier1 中的 Bookkeeper 去写。
(1)写
在 Tier1 存储部分,写入数据的时候通过 Bookkeeper 保证了数据已经在所有的 Segment Store 中落盘,保证了数据写入成功。
Tier1 的 Bookkeeper 在集群不出现故障的情况下永远不进行读取操作,只进行写入操作
(2)读
在客户端向 Pravega 发起读数据的请求的时候,Pravega 会决定这个数据究竟是从Tier1 的 Cache 进行低延时的 tail-read,还是去 Long-term 的长期存储数据(对象存储/NFS)去进行一个高吞吐量的 catch-up read(如果数据不在 Cache,需要按需load 到 Cache 中)。读操作是对客户端透明的

2、弹性伸缩

(1)存储层
Stream 中的 Segment 数量会随着 IO 负载而进行弹性的自动伸缩。如图所示,
t0时刻,数据流写入Pravega,根据键会路由到S0、S1,如果写入速率不变则Segment数量不会发生变化;
t1时刻,S1写入速率增大,S1进入sealed状态,划分为S2、S3,根据键重定向到这两个Segment,即scale-up操作;
t3时刻,S2、S5写入速率减小,两者都进入sealed状态,合并成S6,即scale-down操作。
(2)应用层
以 Kubernetes Operator 来对集群各组件进行有状态的应用部署,这可以使得应用的弹性伸缩更为灵活方便。
Pravega 最近也在和 Ververica 进行深度合作,致力于在 Pravega 端实现 Kubernetes Pod 级别的弹性伸缩同时在 Flink 端通过 rescaling Flink 的 Task 数量来实现弹性伸缩

3、事务性写入

在提交事务之前,数据会根据路由键写入到不同的 Transaction Segment 中,这时候 Segment 对于 Reader 来说是不可见的。只有在事务提交之后,Transaction Segment 才会各自追加到 Stream Segment 的末尾,这时候 Segment 对于 Reader 才是可见的,这是Pravega与Flink结合支持exactly-once的关键
 

引入 Pravega 前后的解决方案比较

实现了数据湖的理念,降低存储、计算成本,减小运维压力,提高代码开发效率
 
 
posted @ 2020-08-13 10:42  码以致用  阅读(1218)  评论(0编辑  收藏  举报