Apache Spark简介与基本概念

发布时间: 2024-01-07 19:59:06 阅读量: 16 订阅数: 14
# 1. 引言 ### 1.1 Apache Spark的发展背景 Apache Spark是由加州大学伯克利分校AMPLab在2009年开发的开源集群计算系统。它最初的设计目的是为了解决Hadoop MapReduce的一些局限性,例如高延迟的磁盘读写和复杂的任务调度。Spark的出现填补了Hadoop在内存计算和迭代计算方面的不足,极大地提高了大数据处理的效率和性能。 另外,Spark还继承了Hadoop的优点,例如良好的容错性和可扩展性,使得它成为了大数据处理领域一颗耀眼的新星。 ### 1.2 为什么选择Apache Spark 相比于传统的大数据处理框架,Apache Spark具有以下几点优势: - **快速性**: Spark采用内存计算,能够比Hadoop MapReduce快上100倍,因此非常适合迭代算法、交互式数据挖掘和实时查询等应用。 - **易用性**: Spark提供了丰富的API,支持Java、Scala、Python和R语言,使得开发者能够使用自己擅长的语言来编写大数据应用。 - **通用性**: Spark不仅支持大数据批处理,还支持流式处理、SQL查询、机器学习和图计算等多种计算模型。 - **可靠性**: Spark的弹性分布式数据集(RDD)具有高容错性和自动恢复功能,能够保证计算的稳定性和可靠性。 因此,作为一种快速、通用、易用和可靠的大数据处理框架,Apache Spark受到了越来越多企业的青睐,成为了当前大数据处理领域的热门选择之一。 # 2. Apache Spark基本概念 Apache Spark 是一个开源的大数据处理框架,它提供了高效的并行计算能力和灵活的数据处理接口。一般而言,Spark 可以被认为是一个分布式计算集群,它可以对大型数据集进行高速计算。在 Spark 中,我们可以使用不同的编程语言如 Scala、Java、Python 或者 R 来进行开发。 ### 2.1 Spark的核心组件 Spark 提供了多个核心组件,包括: - **Spark Core**: 是 Spark 的基础组件,提供了任务调度、内存管理、容错等功能。 - **Spark SQL**: 提供了与结构化数据进行交互的 API,支持 SQL 查询、DataFrame 和 Dataset 等。 - **Spark Streaming**: 可以处理实时数据流,支持基于时间窗口和滑动窗口的实时数据处理。 - **MLlib**: 是 Spark 的机器学习库,提供了常见的机器学习算法和工具。 - **GraphX**: 是 Spark 的图计算库,提供了构建和分析图结构的功能。 除了以上核心组件,Spark 还支持一些其他扩展组件,如 SparkR(在 R 中使用 Spark)、PySpark(在 Python 中使用 Spark)等。 ### 2.2 Resilient Distributed Dataset(RDD)介绍 在 Spark 中,RDD 是一个核心的抽象概念,它代表了可分区、可并行计算的数据集。RDD 具有以下特点: - **容错性(Fault Tolerance)**:Spark 可以通过 RDD 的血缘关系(Lineage)来自动恢复数据集中的丢失分区。 - **并行性(Parallelism)**:RDD 可以被划分为多个分区,并在集群的多个节点上进行计算。 - **可读性(Readability)**:通过缓存和持久化操作,RDD 可以被多次读取和复用。 - **不可变性(Immutability)**:RDD 的分区数据是只读的,它们只能通过转换操作来创建新的 RDD。 - **Laziness(延迟计算)**: RDD 是按需计算的,只有当触发了一个 action 操作时,才会执行计算。 ### 2.3 Spark运行模式 Spark 支持多种运行模式,可以根据实际需求进行选择: - **Local 模式**: 在单个节点上运行 Spark,用于开发和测试环境。 - **Standalone 模式**: Spark 自带的集群管理器,可以用于运行在独立模式下的 Spark 应用程序。 - **Apache Mesos 模式**: 在 Mesos 集群上运行 Spark 应用程序。 - **Hadoop YARN 模式**: 在 Hadoop YARN 环境中运行 Spark,利用 YARN 的资源管理能力。 选择合适的运行模式可以根据应用程序的规模、资源需求和环境配置来决定。 # 3. Apache Spark简介 #### 3.1 什么是Apache Spark Apache Spark是一个快速、通用、可扩展且易于使用的大数据处理和分析引擎。它是为了解决大规模数据处理和分析的问题而设计的,并且提供了丰富的API,可以用于批处理、实时流处理、机器学习和图处理等多种场景。Spark的出现大大简化了大数据处理的复杂性,为数据科学家、工程师和分析师提供了强大的工具和平台。 #### 3.2 Apache Spark的特点 Apache Spark具有以下几个主要特点: - **快速性**:Spark采用先进的内存计算技术,通过内存计算大大提高了处理速度。它比传统的批处理引擎如Hadoop MapReduce快上百倍,比实时流处理框架如Storm和Flink快数十倍。 - **易用性**:Spark提供了丰富的API和开发工具,如Scala、Java、Python和R等编程语言的支持,使得开发者可以用自己熟悉的语言进行开发,降低了学习成本和使用难度。 - **可扩展性**:Spark支持在大规模集群上运行,提供了灵活的扩展性和高可用性。它可以无缝地与其他大数据处理框架如Hadoop和Hive集成,利用其庞大的生态系统。 - **通用性**:Spark不仅仅是一个批处理引擎,它还支持实时流处理、机器学习和图处理等多种计算模式。这使得开发者可以在一个统一的平台上进行不同类型的计算,大大简化了架构和代码的管理。 - **内置的优化器**:Spark具有智能优化器,可以自动选择最佳执行计划和调整任务调度,从而提高计算性能。它还支持内存管理和数据分区等优化技术,以进一步提高效率。 #### 3.3 Apache Spark与Hadoop的关系 Spark和Hadoop是两个独立但密切相关的项目。Spark可以独立于Hadoop使用,也可以与Hadoop集成。在独立模式下,Spark可以在本地模式或者分布式模式下运行,无需依赖Hadoop。而在与Hadoop集成时,Spark可以使用Hadoop分布式文件系统(HDFS)作为数据源,并且可以利用Hadoop的资源管理器(YARN)来进行集群资源调度。 Spark与Hadoop的集成使得Spark可以利用Hadoop的生态系统,如使用Hive作为数据仓库、使用HBase作为分布式数据库等。同时,Spark还可以直接访问Hadoop中存储的数据,并进行高效的分析和处理。 总之,Spark与Hadoop的关系是相辅相成的,它们可以共同构建起一个完整的大数据处理平台,为大数据处理和分析提供强大支持。 # 4. Apache Spark的应用场景 Apache Spark是一个功能强大的大数据处理框架,可以应用于多种不同的场景。以下是几个常见的Apache Spark的应用场景。 ## 4.1 大数据处理 Apache Spark在大数据处理方面表现出色。它可以处理大规模、高速度的数据,并能够提供快速的计算和分析能力。通过使用Spark的内存计算和并行处理技术,可以大幅提升数据处理速度。此外,Spark还提供了丰富的数据处理接口和库,包括SQL、数据流处理、图计算等,可以方便地进行数据清洗、特征提取、数据转换等操作。 以下示例展示了使用Spark进行大数据处理的场景: ```python from pyspark import SparkContext # 创建SparkContext对象 sc = SparkContext() # 读取大规模数据集 data = sc.textFile("data.txt") # 利用Spark提供的API进行数据处理 cleaned_data = data.filter(lambda x: x != "") # 统计数据集中的词频 word_count = cleaned_data.flatMap(lambda x: x.split(" ")).map(lambda x: (x, 1)).reduceByKey(lambda x, y: x + y) # 打印词频结果 for word, count in word_count.collect(): print(f"{word}: {count}") # 关闭SparkContext sc.stop() ``` 上述代码示例中,首先创建了一个SparkContext对象,然后读取了一个大规模的数据集。接着使用Spark提供的API对数据进行清洗和词频统计,并将结果打印出来。最后关闭SparkContext对象。通过使用Spark的并行计算能力,可以高效地处理大规模的数据集。 ## 4.2 实时流处理 除了批处理大数据之外,Apache Spark也可以处理实时流数据。Spark Streaming是Spark提供的流处理模块,它可以将实时数据流转化为一系列的离散的小的批处理任务,然后利用Spark的批处理能力进行处理和分析。 以下示例展示了使用Spark Streaming进行实时流处理的场景: ```python from pyspark.streaming import StreamingContext # 创建StreamingContext对象 ssc = StreamingContext(sparkContext, batchDuration=1) # 通过TCP套接字接收实时流数据 lines = ssc.socketTextStream("localhost", 9999) # 对实时流数据进行处理 cleaned_lines = lines.filter(lambda x: x != "") word_count = cleaned_lines.flatMap(lambda x: x.split(" ")).map(lambda x: (x, 1)).reduceByKey(lambda x, y: x + y) # 打印实时流数据的词频结果 word_count.pprint() # 启动StreamingContext并等待程序结束 ssc.start() ssc.awaitTermination() ``` 上述代码示例中,首先创建了一个StreamingContext对象,并设置了批处理的时间间隔为1秒。然后通过TCP套接字接收实时流数据,并对数据进行清洗和词频统计。最后将实时流数据的词频结果打印出来。 ## 4.3 机器学习与图处理 Apache Spark也被广泛应用于机器学习和图处理领域。Spark提供了丰富的机器学习库(如MLlib)和图处理库(如GraphX),可以方便地进行机器学习模型的训练和图算法的计算。 以下示例展示了使用Spark进行机器学习的场景: ```python from pyspark.ml import Pipeline from pyspark.ml.feature import VectorAssembler from pyspark.ml.regression import LinearRegression # 读取数据集 data = spark.read.format("csv").option("header", "true").load("data.csv") # 特征向量化 vectorAssembler = VectorAssembler(inputCols=["feature1", "feature2"], outputCol="features") data = vectorAssembler.transform(data) # 构建线性回归模型 lr = LinearRegression(featuresCol="features", labelCol="label") # 构建模型管道 pipeline = Pipeline(stages=[vectorAssembler, lr]) # 拟合模型 model = pipeline.fit(data) # 使用模型进行预测 predictions = model.transform(data) # 打印预测结果 predictions.select("features", "label", "prediction").show() ``` 上述代码示例中,首先读取了一个数据集,并进行特征向量化。然后构建了一个线性回归模型,并将特征向量和标签作为输入。接着使用模型管道将特征向量化和线性回归模型组合起来,构建了一个完整的机器学习模型。最后使用该模型对数据集进行预测,并打印出预测结果。 综上所述,Apache Spark在大数据处理、实时流处理和机器学习与图处理等方面具有广泛的应用场景。无论是处理大规模的数据,还是进行实时流处理或者机器学习与图处理,Spark都可以提供高效且强大的解决方案。 # 5. Apache Spark与其他大数据框架的比较 Apache Spark作为大数据处理领域的重要框架,与其他大数据框架有着一定的区别和联系。在本节中,我们将对Apache Spark与其他大数据框架进行比较分析,以便更好地理解其在大数据生态系统中的位置。 ### 5.1 Apache Spark与Hadoop的区别 在大数据领域,Apache Spark和Hadoop都是非常流行的框架。它们之间的主要区别在于数据处理方式和性能方面。 #### Apache Spark与Hadoop的区别: - 数据处理方式:Hadoop基于磁盘存储,适用于批处理任务;而Spark采用内存计算,适用于迭代计算和实时处理。 - 执行速度:由于Spark采用内存计算,因此在迭代计算和实时处理方面有更快的执行速度,而Hadoop适合于大规模的批处理任务。 #### 代码示例(Python): ```python # 使用Python的pyspark示例 from pyspark import SparkContext sc = SparkContext("local", "Hadoop vs Spark") # Hadoop示例 hadoop_data = sc.textFile("hdfs://<path>") hadoop_result = hadoop_data.map(lambda line: line.split()).flatMap(lambda words: [(word, 1) for word in words]).reduceByKey(lambda a, b: a + b) # Spark示例 spark_data = sc.textFile("hdfs://<path>") spark_result = spark_data.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b) print("Hadoop结果:", hadoop_result.collect()) print("Spark结果:", spark_result.collect()) ``` #### 代码总结与结果说明: 以上代码通过比较Hadoop和Spark对数据进行词频统计的处理方式,展示了它们在代码实现和执行效果上的区别。通过运行代码,我们可以观察到Spark的执行速度相比Hadoop更快,并且代码实现更加简洁。 ### 5.2 Apache Spark与Flink和Hive的比较 除了Hadoop之外,Apache Flink和Apache Hive也是大数据领域常用的框架。下面我们将对Apache Spark与Flink和Hive进行简要比较。 #### Apache Spark与Flink的比较: - Spark适用于数据批处理和实时处理,支持SQL、机器学习和图处理等高级API,适合迭代计算。而Flink也支持批处理和流处理,提供了更好的低延迟和高吞吐量。 - Spark使用RDD作为抽象数据集,而Flink基于数据流(DataStream)编程模型。Flink的数据流模型能够很好地支持连续事件处理和有状态的计算。 #### Apache Spark与Hive的比较: - Spark主要用于数据处理和分析,支持SQL查询和复杂的数据处理任务,适用于迭代计算和实时计算。而Hive则是基于Hadoop的数据仓库工具,主要用于数据的批处理和查询。 - Spark拥有更快的内存计算速度和更丰富的API,适合于需要快速计算的场景。而Hive适合于对数据进行结构化查询和分析。 ### 5.3 Apache Spark在大数据生态系统中的位置 在大数据生态系统中,Apache Spark扮演着重要的角色。它不仅可以与Hadoop生态系统中的HDFS、YARN等组件无缝集成,还可以与其他大数据组件如Kafka、Cassandra等进行集成,提供了更加全面和强大的数据处理能力。 总的来说,Apache Spark在大数据生态系统中的位置是非常重要的,它具有较高的灵活性和性能,能够适用于各种大数据处理场景,并且与其他大数据框架协同工作,形成一个完整的大数据解决方案。 以上是对Apache Spark与其他大数据框架的简要比较,通过对比不同框架的特点和适用场景,我们可以更好地选择合适的框架来解决不同的大数据处理问题。 # 6. 结语 ### 6.1 Apache Spark的未来展望 Apache Spark作为目前最热门的大数据处理框架之一,拥有强大的性能和丰富的功能,一直在不断发展和改进。未来,Apache Spark有以下几个主要的发展方向: 1. **性能优化**:Spark在处理大规模数据时,仍然存在一些性能瓶颈。未来的版本中,Spark将继续优化内存管理、I/O读写、并行计算等方面的性能,以进一步提升处理速度和效率。 2. **更多的支持库和扩展**:为了满足不同领域和行业的需求,Apache Spark将进一步扩展其支持库,提供更多的功能和工具。例如,Spark SQL可以支持更多数据库类型,MLlib可以提供更多的机器学习算法和模型。 3. **更好的集成和互操作性**:为了更好地融入大数据生态系统,Spark将进一步加强与其他大数据框架和工具的集成和互操作性。例如,可以更好地与Hadoop、Flink等框架配合使用,提供更灵活和高效的数据处理方案。 ### 6.2 对于Apache Spark的建议和使用注意事项 在使用Apache Spark进行大数据处理时,需要注意以下几点: 1. **合理规划集群资源**:在部署Spark集群时,需要合理规划集群资源分配,如内存、CPU等。根据实际需求和数据量大小进行配置,以充分利用集群资源,提高处理效率。 2. **选择合适的数据存储格式**:Spark支持多种数据存储格式,如Parquet、Avro等。选择合适的数据存储格式可以提高数据读取和写入的性能。同时,还可以考虑使用列式存储和压缩等技术,以减少存储空间和提升查询效率。 3. **合理设置并行度和分区数**:在进行Spark数据处理时,需要根据实际情况合理设置并行度和分区数。通过调整RDD和DataFrame的分区数,可以充分利用集群资源,提高计算和处理速度。 4. **灵活使用缓存和持久化**:Spark提供了缓存和持久化机制,可以将中间数据缓存到内存中,以加快重复计算的速度。在计算过程中合理使用缓存和持久化,可以减少重复计算,提高处理效率。 综上所述,Apache Spark作为一款强大的大数据处理框架,具有广泛的应用前景和发展潜力。通过合理规划集群资源、选择合适的存储格式、设置合理的并行度和分区数,以及灵活使用缓存和持久化,可以充分发挥Spark的优势,提高数据处理的效率和性能。希望本文对于理解Spark的基本概念和特点,以及其在大数据领域的应用场景和未来展望有所帮助。
corwn 最低0.47元/天 解锁专栏
送3个月
profit 百万级 高质量VIP文章无限畅学
profit 千万级 优质资源任意下载
profit C知道 免费提问 ( 生成式Al产品 )

相关推荐

勃斯李

大数据技术专家
超过10年工作经验的资深技术专家,曾在一家知名企业担任大数据解决方案高级工程师,负责大数据平台的架构设计和开发工作。后又转战入互联网公司,担任大数据团队的技术负责人,负责整个大数据平台的架构设计、技术选型和团队管理工作。拥有丰富的大数据技术实战经验,在Hadoop、Spark、Flink等大数据技术框架颇有造诣。
专栏简介
本专栏深入探讨了Apache Spark的内核机制和性能调优策略,涵盖了从基础概念到高级原理的全面解析。首先,介绍了Spark的基本概念和任务调度执行流程,帮助读者建立起对Spark框架的整体认识。然后,重点阐述了Spark内存管理、数据序列化优化和DAG调度器的原理与应用,深入剖析了数据分区、Shuffle优化和数据倾斜问题的解决方案。接下来,探讨了广播变量、累加器的使用与优化,以及数据存储和数据源的优化策略。此外,将重点放在了Spark SQL内部原理、性能调优和实时数据处理,还深入研究了Spark MLlib的机器学习与模型训练优化。最后,分析了Spark与多个系统的集成与优化方案,以及任务监控和调优工具的使用。通过本专栏的学习,读者将全面了解Spark的内部机制,并具备丰富的性能调优技能,为实际项目应用提供强有力的支持。
最低0.47元/天 解锁专栏
送3个月
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )

最新推荐

【实战演练】使用Docker与Kubernetes进行容器化管理

![【实战演练】使用Docker与Kubernetes进行容器化管理](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8379eecc303e40b8b00945cdcfa686cc~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp) # 2.1 Docker容器的基本概念和架构 Docker容器是一种轻量级的虚拟化技术,它允许在隔离的环境中运行应用程序。与传统虚拟机不同,Docker容器共享主机内核,从而减少了资源开销并提高了性能。 Docker容器基于镜像构建。镜像是包含应用程序及

【实战演练】时间序列预测项目:天气预测-数据预处理、LSTM构建、模型训练与评估

![python深度学习合集](https://img-blog.csdnimg.cn/813f75f8ea684745a251cdea0a03ca8f.png) # 1. 时间序列预测概述** 时间序列预测是指根据历史数据预测未来值。它广泛应用于金融、天气、交通等领域,具有重要的实际意义。时间序列数据通常具有时序性、趋势性和季节性等特点,对其进行预测需要考虑这些特性。 # 2. 数据预处理 ### 2.1 数据收集和清洗 #### 2.1.1 数据源介绍 时间序列预测模型的构建需要可靠且高质量的数据作为基础。数据源的选择至关重要,它将影响模型的准确性和可靠性。常见的时序数据源包括:

【实战演练】深度学习在计算机视觉中的综合应用项目

![【实战演练】深度学习在计算机视觉中的综合应用项目](https://pic4.zhimg.com/80/v2-1d05b646edfc3f2bacb83c3e2fe76773_1440w.webp) # 1. 计算机视觉概述** 计算机视觉(CV)是人工智能(AI)的一个分支,它使计算机能够“看到”和理解图像和视频。CV 旨在赋予计算机人类视觉系统的能力,包括图像识别、对象检测、场景理解和视频分析。 CV 在广泛的应用中发挥着至关重要的作用,包括医疗诊断、自动驾驶、安防监控和工业自动化。它通过从视觉数据中提取有意义的信息,为计算机提供环境感知能力,从而实现这些应用。 # 2.1 卷积

【实战演练】通过强化学习优化能源管理系统实战

![【实战演练】通过强化学习优化能源管理系统实战](https://img-blog.csdnimg.cn/20210113220132350.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dhbWVyX2d5dA==,size_16,color_FFFFFF,t_70) # 2.1 强化学习的基本原理 强化学习是一种机器学习方法,它允许智能体通过与环境的交互来学习最佳行为。在强化学习中,智能体通过执行动作与环境交互,并根据其行为的

【实战演练】虚拟宠物:开发一个虚拟宠物游戏,重点在于状态管理和交互设计。

![【实战演练】虚拟宠物:开发一个虚拟宠物游戏,重点在于状态管理和交互设计。](https://itechnolabs.ca/wp-content/uploads/2023/10/Features-to-Build-Virtual-Pet-Games.jpg) # 2.1 虚拟宠物的状态模型 ### 2.1.1 宠物的基本属性 虚拟宠物的状态由一系列基本属性决定,这些属性描述了宠物的当前状态,包括: - **生命值 (HP)**:宠物的健康状况,当 HP 为 0 时,宠物死亡。 - **饥饿值 (Hunger)**:宠物的饥饿程度,当 Hunger 为 0 时,宠物会饿死。 - **口渴

【实战演练】综合案例:数据科学项目中的高等数学应用

![【实战演练】综合案例:数据科学项目中的高等数学应用](https://img-blog.csdnimg.cn/20210815181848798.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hpV2FuZ1dlbkJpbmc=,size_16,color_FFFFFF,t_70) # 1. 数据科学项目中的高等数学基础** 高等数学在数据科学中扮演着至关重要的角色,为数据分析、建模和优化提供了坚实的理论基础。本节将概述数据科学

【实战演练】构建简单的负载测试工具

![【实战演练】构建简单的负载测试工具](https://img-blog.csdnimg.cn/direct/8bb0ef8db0564acf85fb9a868c914a4c.png) # 1. 负载测试基础** 负载测试是一种性能测试,旨在模拟实际用户负载,评估系统在高并发下的表现。它通过向系统施加压力,识别瓶颈并验证系统是否能够满足预期性能需求。负载测试对于确保系统可靠性、可扩展性和用户满意度至关重要。 # 2. 构建负载测试工具 ### 2.1 确定测试目标和指标 在构建负载测试工具之前,至关重要的是确定测试目标和指标。这将指导工具的设计和实现。以下是一些需要考虑的关键因素:

【进阶】使用Python进行网络攻防演示

![【进阶】使用Python进行网络攻防演示](https://img-blog.csdnimg.cn/direct/bdbbe0bfaff7456d86e487cd585bd51e.png) # 2.1.1 使用Python进行网络扫描 在Python中,可以使用`socket`模块和`scapy`库进行网络扫描。`socket`模块提供了低级的网络编程接口,而`scapy`是一个强大的网络分析库,可以发送和接收各种网络数据包。 ```python import socket # 创建一个socket对象 s = socket.socket(socket.AF_INET, socket

【实战演练】前沿技术应用:AutoML实战与应用

![【实战演练】前沿技术应用:AutoML实战与应用](https://img-blog.csdnimg.cn/20200316193001567.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h5czQzMDM4MV8x,size_16,color_FFFFFF,t_70) # 1. AutoML概述与原理** AutoML(Automated Machine Learning),即自动化机器学习,是一种通过自动化机器学习生命周期

【实战演练】python云数据库部署:从选择到实施

![【实战演练】python云数据库部署:从选择到实施](https://img-blog.csdnimg.cn/img_convert/34a65dfe87708ba0ac83be84c883e00d.png) # 2.1 云数据库类型及优劣对比 **关系型数据库(RDBMS)** * **优点:** * 结构化数据存储,支持复杂查询和事务 * 广泛使用,成熟且稳定 * **缺点:** * 扩展性受限,垂直扩展成本高 * 不适合处理非结构化或半结构化数据 **非关系型数据库(NoSQL)** * **优点:** * 可扩展性强,水平扩展成本低