快手数仓面经
Hdfs读写流程
Hadoop Distributed File System(HDFS)是 Apache Hadoop 生态系统的一部分,用于存储大规模数据的分布式文件系统。HDFS 的读写流程包括以下步骤:
HDFS 写入流程:
客户端请求: 当一个应用程序需要将数据存储到 HDFS 中时,首先由客户端发送写请求。
数据划分: 要写入的数据被划分成一系列数据块(通常是128MB 或256MB)。这些数据块会被分布式存储在 HDFS 集群中的不同节点上。
选择 DataNode: HDFS 的 NameNode 被用于维护文件系统的元数据信息,它记录了每个数据块存储在哪个 DataNode 上。客户端会向 NameNode 发送数据块的位置请求,以确定要写入的 DataNode。
客户端写入: 客户端将数据块写入选定的 DataNode,同时该 DataNode 会复制数据到其他 DataNode,以提供数据冗余和容错性。
数据复制: 数据复制是 HDFS 的一个关键特性,通常每个数据块都会复制到多个不同的 DataNode 上,以防止数据丢失。
数据流水线: 数据的写入是通过数据流水线(pipeline)进行的,以提高写入速度。在流水线上的 DataNodes 之间数据以块的形式传输,而不是整个文件。
确认写入: 当所有数据块都写入成功并复制到足够的 DataNodes 时,客户端会收到写入成功的确认。
HDFS 读取流程:
客户端请求: 当一个应用程序需要读取 HDFS 中的文件时,客户端向 HDFS 的 NameNode 发送读取请求。
元数据查询: NameNode 负责维护文件系统的元数据,它会返回文件的位置信息,包括哪些 DataNodes 上存储了数据块。
DataNode 读取: 客户端开始从最近的 DataNode 读取数据块。如果某个 DataNode 不可用,客户端会尝试从副本中的其他 DataNode 读取数据。
数据传输: 数据会通过网络传输到客户端,通常以块的形式传输,而不是整个文件。
数据组装: 客户端将从不同 DataNodes 读取的数据块组装成完整的文件。
读取完成: 一旦所有数据块都被成功读取并组装,客户端完成文件读取操作。
需要注意的是,HDFS 是为大规模数据存储和分析设计的,因此在读写时会有一些额外的优化和容错机制,以确保数据的高可用性和可靠性。此外,HDFS 还支持数据压缩和数据复制策略的配置,以满足不同应用场景的需求。流程中的一些具体细节可能会因 Hadoop 版本和配置而有所不同。
Spark和hadoop的区别
Apache Spark 和 Apache Hadoop 是两个不同但通常一起使用的大数据处理框架。它们有许多共同之处,但也有一些关键区别:
1. 处理模型:
Hadoop: Hadoop 主要使用 MapReduce 编程模型进行批处理,它适用于大规模数据的批量处理任务。Hadoop 将数据划分成块,然后在集群中的节点上运行 Map 和 Reduce 任务来处理这些数据。
Spark: Spark 提供了更广泛的数据处理模型,包括批处理、交互式查询、流处理和机器学习等。Spark 的核心概念是弹性分布式数据集(Resilient Distributed Dataset,RDD),它是一个可在内存中缓存的分布式数据集,允许高效的迭代计算。Spark 还支持 SQL 查询、流处理(例如,使用 Spark Streaming)和机器学习(例如,使用 MLlib)等高级功能。
2. 性能:
Hadoop: Hadoop 在处理大规模批量数据时表现出色,但在迭代处理和交互式查询等方面性能相对较差,因为它需要将中间数据写入磁盘。
Spark: Spark 通过将中间数据保留在内存中,能够在迭代和交互式处理任务中实现更高的性能。这使得 Spark 非常适合迭代算法和交互式数据分析。
3. 内存使用:
Hadoop: Hadoop 主要依赖于磁盘存储,中间数据通常需要写入磁盘,这可能导致较高的磁盘 IO。
Spark: Spark 更加内存密集型,允许在内存中高效存储和处理数据。这提供了更快的数据访问速度,减少了磁盘 IO 的需求。
4. 生态系统:
Hadoop: Hadoop 生态系统包括 HDFS(Hadoop Distributed File System)、MapReduce、Hive、Pig 等工具和库。
Spark: Spark 也有自己的生态系统,包括 Spark Core、Spark SQL、Spark Streaming、MLlib(机器学习库)和 GraphX(图处理库)。Spark 还可以与 HDFS 等其他存储系统和 Hive、HBase 等工具集成。
5. 编程语言:
Hadoop: Hadoop 主要使用 Java 编程,尽管也有其他编程语言的 API(如 Hive 的 HQL 和 Pig 的 Pig Latin)。
Spark: Spark 提供了多种编程语言的 API,包括 Scala、Java、Python 和 R,使开发人员能够选择他们最熟悉的语言来编写 Spark 应用程序。
Spark rdd算子有哪些
Apache Spark 中的 RDD(Resilient Distributed Dataset)是一个弹性分布式数据集,它提供了一系列用于数据转换和操作的算子(操作符)。这些算子可以分为两大类:转换算子(Transformation)和行动算子(Action)。
转换算子(Transformation) 用于从现有的 RDD 创建新的 RDD,这些操作不会立即执行,而是惰性计算,只有在行动算子被调用时才会触发计算。一些常见的转换算子包括:
map(func): 对 RDD 中的每个元素应用一个函数,返回一个新的 RDD。
filter(func): 根据给定的条件筛选 RDD 中的元素,返回一个新的 RDD。
flatMap(func): 类似于 map,但每个输入元素可以映射到多个输出元素,返回一个扁平化的新 RDD。
distinct(): 去除 RDD 中的重复元素,返回一个新的 RDD。
union(otherRDD): 将两个 RDD 合并成一个新的 RDD。
intersection(otherRDD): 返回两个 RDD 的交集。
subtract(otherRDD): 返回两个 RDD 的差集。
groupByKey(): 将 RDD 中的元素按键分组,生成(键,值列表)对的 RDD。
reduceByKey(func): 对具有相同键的元素执行 reduce 操作。
sortByKey(): 根据键对 RDD 进行排序。
行动算子(Action) 触发实际计算并返回结果,这些操作会导致计算在集群上执行。一些常见的行动算子包括:
collect(): 将 RDD 中的所有元素收集到驱动程序节点,以数组的形式返回。
count(): 返回 RDD 中元素的数量。
first(): 返回 RDD 中的第一个元素。
take(n): 返回 RDD 中的前 n 个元素。
reduce(func): 使用给定的二元运算符函数对 RDD 中的元素进行规约操作。
foreach(func): 对 RDD 中的每个元素应用一个函数,通常用于执行副作用操作。
union all会shuffue吗?
unionAll 操作(或称为 union)不会涉及数据重洗。它是一个简单的合并操作,将两个 RDD(或 DataFrame)的内容合并到一个新的 RDD(或 DataFrame)中,保留所有重复的行。这个操作是非常高效的,因为它只是简单地将两个 RDD 的分区合并在一起,而不需要重新分布数据。
例如,如果你有两个 RDD A 和 B,执行 A.union(B) 将得到一个包含 A 和 B 中所有元素的新 RDD,不会对数据进行重新分区或排序。
union 操作(有时称为 distinct)涉及数据重洗。当你执行 union 操作时,它会删除重复的行,这可能需要重新分区和重新排序数据,因此可能涉及数据的重洗。这是因为在合并两个 RDD 的时候,需要确保结果 RDD 中的数据是唯一的。
例如,如果你有两个 RDD A 和 B,执行 A.distinct().union(B.distinct()) 将得到一个包含 A 和 B 中所有唯一元素的新 RDD。这个操作可能需要对数据进行重新分区和重新排序以确保唯一性。
Flink 时间语义有哪些
事件时间(Event Time): 事件时间是数据自身携带的时间戳,通常是从事件发生的时间戳。事件时间非常适合处理乱序事件流,因为它能够有效地处理事件的延迟和重排序。在 Flink 中,您可以使用事件时间来定义窗口操作,例如事件时间窗口或会话窗口。
处理时间(Processing Time): 处理时间是 Flink 处理事件的时间,通常由系统的机器时钟来确定。处理时间窗口是基于处理时间的窗口操作,它不考虑事件的实际时间戳,而只关注事件到达 Flink 的时间。处理时间窗口对于需要低延迟的应用程序非常有用,但不适用于乱序事件流的处理。
摄取时间(Ingestion Time): 摄取时间是事件进入 Flink 的时间,通常是由数据源记录的时间戳。摄取时间介于事件时间和处理时间之间,它适用于那些不容易获取准确事件时间戳的场景。您可以使用摄取时间来定义窗口操作,类似于事件时间。
Flink 的 Watermark 是什么?
在 Apache Flink 中,Watermark(水位线)是一种用于处理事件时间数据流的关键概念。它用于解决事件时间处理中的乱序事件和延迟数据的问题,以确保窗口操作的正确性和准确性。
Watermark 是一种元数据,它随着事件时间流一起传输到 Flink 的操作符中。Watermark 携带了一个时间戳,表示在该时间戳之前的所有事件都已经到达,不会再有比该时间戳更早的事件。换句话说,Watermark 用于告诉 Flink 处理引擎:事件时间不会再早于 Watermark 所表示的时间。
Watermark 的主要作用包括:
乱序事件处理: 当事件在流中以乱序方式到达时,Watermark 可以确保 Flink 在执行窗口操作时只考虑那些在 Watermark 之前到达的事件,从而保证结果的正确性。
处理延迟数据: Watermark 可以用于处理延迟数据,确保窗口操作等在一定的时间间隔后触发,而不必等待所有数据都到达。这对于实时应用程序和需要低延迟的场景非常有用。
生成窗口: Watermark 用于确定何时触发窗口操作,例如,当一个窗口的结束时间戳不再早于 Watermark 时,Flink 可以关闭该窗口并计算结果。
通常,数据源(如 Kafka、Flink 的 Kinesis 数据源等)会在事件中嵌入时间戳,并生成 Watermark。Flink 的操作符会接收这些 Watermark,并使用它们来控制事件时间窗口和触发相应的操作。
Flink 还提供了一些内置的 Watermark 生成器,例如基于固定时间间隔的 Watermark 生成器和基于事件时间的 Watermark 生成器,用于适应不同的数据源和处理场景。通过合理配置 Watermark 生成器,您可以确保您的 Flink 应用程序能够有效地处理事件时间数据流中的乱序事件和延迟数据。
#面经#解决职场真实面试问题,分享同学真实成功案例,欢迎订阅关注!