MapReduce的个人理解

2023-05-16

MapReduce的个人理解

文章目录

        • MapReduce模型简介
        • Map和Reduce函数
          • 这里给出一个简单实例
        • MapReduce的工作流程
          • 工作流程概述
          • MapReduce的各个执行阶段
        • Shuffle过程详解
          • Shuffle过程简介
          • Map端的Shuffle过程
            • (1)输入数据和执行Map任务
            • (2)写入缓存
            • (3)溢写(分区、排序和合并)
            • (4)文件归并
          • Reduce端的Shuffle过程
            • (1)“领取”数据
            • (2)归并数据
            • (3)把数据输入Reduce任务

MapReduce模型简介

MapReduce将复杂的、运行于大规模集群上的并行计算过程高度抽象到了两个函数:Map和Reduce,这两个函数及其核心思想都源自函数式编程语言。

MapReduce设计的一个理念就是 “计算向数据靠拢” ,而不是“数据向计算靠拢",因为数据需要 大量的网络传输开销 ,尤其是在大规模数据环境下,这种开销尤为惊人,所以,移动计算要比移动数据更加经济。在这种理念下,一个集群中,只要有可能,MapReduce框架就会将Map程序就近地在HDFS数据所在的节点运行,即将计算节点和存储节点放在一起运行,从而减少了节点间的数据移动开销。

MapReduce框架采用了 Master/Slave架构,包括一个 Master和若干个 Slave Master上运行JobTrackerSlave上运行 TaskTracker。用户提交的每个计算作业,会被划分成若干个任务。

  • JobTracker负责作业和任务的调度,监控它们的执行,并重新调度已经失败的任务。
  • Task Tracker负责执行由 JobTracker指派的任务。

Map和Reduce函数

MapReduce模型的核心是Map函数和Reduce函数,二者都是由应用程序开发者负责具体实现的。

Map函数和Reduce函数都是以<key, value>作为输入,按一定的映射规则转换成另一个或一批<key, value>进行输出

image-20210403145810221

这里给出一个简单实例

比如,我们想编写一个MapReduce程序来统计一个文本文件中每个单词出现的次数

  • 对于Map函数的输入**<k1,v1>而言,其具体输入数据就是<某一行文本在文件中的偏移位置,该行文本的内容>。用户可以自己编写Map函数处理过程,把文件中的一行读取后解析出每个单词,输出一批中间结果<单词,出现次数>**;

  • 然后,把这些中间结果作为Reduce函数的输入,Reduce函数的具体处理过程也是由用户自己编写的,用户可以将相同单词的出现次数进行累加,输出每个单词出现的总次数


MapReduce的工作流程


工作流程概述

​ 大规模数据集的处理包括分布式存储分布式计算两个核心环节。谷歌公司用分布式文件系统GFS实现分布式数据存储,用MapReduce实现分布式计算,而Hadoop则使用分布式文件系统HDFS实现分布式数据存储,用Hadoop MapReduce实现分布式计算。MapReduce的输入和输出都需要借助于分布式文件系统进行存储,这些文件被分布存储到集群中的多个节点上。
​ MapReduce的核心思想可以用**“分而治之”**来描述,也就是把一个大的数据集拆分成多个小数据块在多台机器上并行处理,也就是说,一个大的MapReduce作业,**首先会被拆分成许多个Map任务在多台机器上并行执行,**每个Map任务通常运行在数据存储的节点上,这样,计算和数据就可以放在一起运行,不需要额外的数据传输开销。

​ 当Map任务结束后,会生成以<key,value>形式表示的许多中间结果。

​ 然后,这些中间结果会被分发到多个Reduce任务在多台机器上并行执行具有相同key的<key,value>会被发送到同一个Reduce任务那里,Reduce任务会对中间结果进行汇总计算得到最后结果,并输出到分布式文件系统中。

image-20210403152208757

不同的Map任务之间不会进行通信,不同的Reduce任务之间爷不会发生任何信息交换;用户不能显式地从一台机器向另一台继机器发送消息,所有的数据交换都是通过MapReduce框架自身去实现的。

在MapReduce的整个执行过程中,Map任务的输入文件、Reduce任务的处理结果都是保存在分布式文件系统中的,而Map任务处理得到的中间结果则保存在本地存储中(如磁盘)。

MapReduce的各个执行阶段

image-20210403153618883


Shuffle过程详解


Shuffle过程简介

Shuffle过程是MapReduce整个工作流程的核心环节,理解Shuffle过程的基本原理,对于理解MapReduce流程至关重要。

所谓Shuffle,是指对Map输出结果进行分区、排序、合并等处理并交给Reduce的过程。因此,Shuffle过程分为Map端的操作Reduce端的操作

image-20210403154046928

①在Map端的Shuffle过程。Map的输出结果首先被写入缓存,当缓存满时,就启动溢写操作,把缓存中的数据写入磁盘文件,并清空缓存。当启动溢写操作时,首先需要把缓存中的数据进行分区,然后对每个分区的数据进行排序(Sort)和合并(Combine),之后再写入磁盘文件。每次溢写操作会生成一个新的磁盘文件,随着Map任务的执行,磁盘中就会生成多个溢写文件。在Map任务全部结束之前,这些溢写文件会被归并(Merge)成一个大的磁盘文件,然后,通知相应的Reduce任务来领取属于自己处理的数据。

image-20210403154521609

②在Reduce端的Shuffle过程。Reduce任务从Map 端的不同 Map 机器领回属于自己处理的那部分数据,然后,对数据进行归并(Merge)后交给Reduce处理。

Map端的Shuffle过程

Map端的Shuffle过程包括4个步骤

(1)输入数据和执行Map任务

​ Map任务的输入数据一般保存在分布式文件系统(如GFS或HDFS)的文件块中,这些文件块的格式是任意的,可以是文档,也可以是二进制格式的。Map任务接受<key,value>作为输入后,按一定的映射规则转换成一批<key,value>进行输出。

(2)写入缓存

​ 每个Map任务都会被分配一个缓存,Map的输出结果不是立即写入磁盘,而是首先写入缓存。在缓存中积累一定数量的Map输出结果以后,再一
次性批量写入磁盘,这样可以大大减少对磁盘I/O的影响。因为,磁盘包含机械部件,它是通过磁头移动和盘片的转动来寻址定位数据的,每次寻址的开销很大,如果每个Map输出结果都直接写人磁盘,会引入很多次寻址开销,而一次性批量写入,就只需要一次寻址,连续写入,大大降低了开销。需要注意的是,在写入缓存之前,key与value值都会被序列化成字节数组。

(3)溢写(分区、排序和合并)

​ 提供给MapReduce的缓存的容量是有限的,默认大小是100MB。随着Map任务的执行,缓存中Map结果的数量会不断增加,很快就会占满整个缓存,这时,就必须启动溢写(Spill)操作,把缓存中的内容一次性写入磁盘,并清空缓存。溢写的过程通常是由另外一个单独的后台线程来完成的,不会影响Map结果往缓存写人。但是,为了保证Map结果能够不停地持续写入缓存,不受溢写过程的影响,就必须让缓存中一直有可用的空间,不能等到全部占满才启动溢写过程,所以,一般会设置一个溢写比例,如0.8,也就是说,当100MB大小的缓存被填满80MB数据时,就启动溢写过程,把已经写入的80MB数据写入磁盘,剩余20MB空间供Map结果继续写入。

​ 但是,在溢写到磁盘之前,缓存中的数据首先会被分区(Partition)。缓存中的数据是<key,value>形式的键值对,这些键值对最终需要交给不同的Reduce任务进行并行处理。MapReduce通过Partitioner接口对这些键值对进行分区,默认采用的分区方式是采用Hash函数对key进行哈希后再用Reduce任务的数量进行取模,可以表示成hash(key)modR。其中,R表示Reduce任务的数量,这样,就可以把Map输出结果均匀地分配给这R个Reduce任务去并行处理了。当然,
MapReduce也允许用户通过重载Partitioner接口来自定义分区方式。

​ 对于每个分区内的所有键值对,后台线程会根据key对它们进行内存排序(Sort),排序是MapReduce 的默认操作。排序结束后,还包含一个可选的合并(Combine)操作。如果用户事先没有定义Combiner函数,就不用进行合并操作。如果用户事先定义了Combiner函数,则这个时候会执行合并操作,从而减少需要溢写到磁盘的数据量。

​ 所谓**“合并”**,是指将那些具有相同key的<key,value>的value加起来,比如,有两个键值对<“xmu”,1>和<“xmu”,1>,经过合并操作以后就可以得到一个键值对<“xmu”,2>,减少了键值对的数量。这里需要注意,Map端的这种合并操作,其实和Reduce的功能相似,但是,由于这个操作发生在Map端,所以,我们只能称之为“合并”,从而有别于Reduce。不过,并非所有场合都可以使用Combiner,因为,Combiner的输出是Reduce任务的输入,Combiner绝不能改变Reduce
任务最终的计算结果,一般而言,累加、最大值等场景可以使用合并操作。

​ 经过分区、排序以及可能发生的合并操作之后,这些缓存中的键值对就可以被写入磁盘,并清空缓存。每次溢写操作都会在磁盘中生成一个新的溢写文件,写入溢写文件中的所有键值对,都是经过分区和排序的。

(4)文件归并

​ 每次溢写操作都会在磁盘中生成一个新的溢写文件,随着MapReduce任务的进行,磁盘中的溢写文件数量会越来越多。当然,如果Map输出结果很少,磁盘上只会存在一个溢写文件,但是,通常都会存在多个溢写文件。最终,在Map任务全部结束之前,系统会对所有溢写文件中的数据进行归并(Merge),生成一个大的溢写文件,这个大的溢写文件中的所有键值对,也是经过分区和排序的。 所谓 “归并”(Merge),是指对于具有相同key的键值对,会被归并成一个新的键值对。具体而言,对于若干个具有相同key的键值对<k1,v1>,<k1,v2>…,会被归并成一个新的键值对<k1,<V1,V2,vn>>。
​ 另外,进行文件归并时,如果磁盘中已经生成的溢写文件的数量超过参数
min.num.spills.for.combine的值时(默认值是3,用户可以修改这个值)。那么,就可以再次运行Combiner,对数据进行合并操作,从而减少写入磁盘的数据量。但是,如果磁盘中只有一两个溢写文件时,执行合并操作就会“得不偿失”,因为执行合并操作本身也需要代价,因此,不会运行Combiner。

​ 经过上述4个步骤以后,Map端的Shuffle过程全部完成,最终生成的一个大文件会被存放在本地磁盘。这个大文件中的数据是被分区的,不同的分区会被发送到不同的Reduce任务进行并行处理。

JobTracker会一直监测Map任务的执行,当监测到一个Map任务完成后,就会立即通知相关的Reduce任务来“领取”数据,然后开始Reduce端的Shuffle过程。

Reduce端的Shuffle过程

​ 相对于Map端而言,Reduce端的Shuffle过程非常简单,只需要从Map端读取Map结果,然后执行归并操作,最后输送给Reduce任务进行处理。

image-20210403162040361

(1)“领取”数据

​ Map端的Shuffle过程结束后,所有Map输出结果都保存在Map机器的本地磁盘上,Reduce任务需要把这些数据“领取”(Fetch)回来存放到自己所在机器的本地磁盘上。因此,在每个Reduce任务真正开始之前,它大部分时间都在从Map端把属于自己处理的那些分区的数据“领取”过来。

​ 每个Reduce任务会不断地通过RPC(Remote Procedure Call)向JobTracker询问Map任务是否已经完成;JobTracker监测到一个Map任务完成后,就会通知相关的Reduce任务来“领取”数据;一旦一个Reduce任务收到 JobTracker 通知,它就会到该Map任务所在机器上把属于自己处理的分区数据领取到本地磁盘中。一般系统中会存在多个Map机器,因此,Reduce任务会使用多个线程同时从多个Map机器领回数据。

(2)归并数据

​ 从Map端领回的数据,会首先被存放在Reduce任务所在机器的缓存中,如果缓存被占满,就会像Map端一样被溢写到磁盘中。由于在Shuffle阶段,Reduce任务还没有真正开始执行,因此,这时可以把内存的大部分空间分配给Shuffle过程作为缓存。需要注意的是,系统中一般存在多个Map机器,所以,Reduce任务会从多个Map机器领回属于自己处理的那些分区的数据,因此,缓存中的数据是来自不同的Map机器的,一般会存在很多可以合并(Combine)的键值对。
当溢写过程启动时,具有相同key的键值对会被归并(Merge),如果用户定义了Combiner,则归并后的数据还可以执行合并操作,减少写入磁盘的数据量。每个溢写过程结束后,都会在磁盘中生成一个溢写文件,因此,磁盘上会存在多个溢写文件。最终,当所有的Map端数据都已经被领回时,和Map端类似,多个溢写文件会被归并成一个大文件,归并的时候还会对键值对进行排序,从而使得最终大文件中的键值对都是有序的。当然,在数据很少的情形下,缓存就可以存储所有数据,就不需要把数据溢写到磁盘,而是直接在内存中执行归并操作,然后直接输出给Reduce任务。需

​ 要说明的是,把磁盘上的多个溢写文件归并成一个大文件,可能需要执行多轮归并操作。每轮归并操作可以归并的文件数量是由参数io.sort.factor的值来控制的(默认值是10,可以修改)。
假设磁盘中生成了50个溢写文件,每轮可以归并10个溢写文件,则需要经过5轮归并,得到5个归并后的大文件。

(3)把数据输入Reduce任务

​ 磁盘中经过多轮归并后得到的若干个大文件,不会继续归并成一个新的大文件,而是直接输入给Reduce任务,这样可以减少磁盘读写开销。由此,整个Shuffle过程顺利结束。接下来,Reduce任务会执行 Reduce函数中定义的各种映射,输出最终结果,并保存到分布式文件系统中。

image-20210403163316845

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MapReduce的个人理解 的相关文章

  • security.UserGroupInformation:MR 的 PrivilegedgedActionException 错误

    每当我尝试执行映射缩减作业以写入 Hbase 表时 我都会在控制台中收到以下错误 我正在从用户帐户运行 MR 作业 错误 security UserGroupInformation PriviledgedActionException 为
  • Hadoop MapReduce:可以在一个 hadoop 作业类中定义两个映射器和缩减器吗?

    我有两个独立的 java 类 用于执行两个不同的 MapReduce 作业 我可以独立运行它们 对于这两个作业 它们所操作的输入文件是相同的 所以我的问题是是否可以在一个java类中定义两个映射器和两个缩减器 例如 mapper1 clas
  • PHP MongoDB映射减少数据库断言失败

    我第一次使用 PHP MongoDB 进行 Map Reduce 运行 MapReduce 命令时遇到错误 My code map function emit this topic id re date this date posted r
  • 使用 MongoDB 的 MapReduce 选择不同的多个字段

    我想在 MongoDB 上执行这个 SQL 语句 SELECT DISTINCT book author from library 到目前为止 MongoDB 的 DISTINCT 一次仅支持一个字段 对于多个字段 我们必须使用 GROUP
  • 如何读取 RCFile

    我正在尝试将一个小的 RCFile 约 200 行数据 读入 HashMap 中以进行 Map Side 连接 但是在将文件中的数据变为可用状态时遇到了很多麻烦 这是我到目前为止所拥有的 其中大部分来自这个例子 http sumit1001
  • 如何在hadoop/map reduce中创建固定行数的输出文件?

    假设我们有 N 个具有不同行数的输入文件 我们需要生成输出文件 使得每个输出文件恰好有 K 行 最后一个输出文件可以有 是否可以使用单个 MR 作业来完成此操作 我们应该打开文件以便在reducer中显式写入 输出中的记录应该被打乱 tha
  • 如何使用新的 Hadoop API 来使用 MultipleTextOutputFormat?

    我想编写多个输出文件 如何使用 Job 而不是 JobConf 来执行此操作 创建基于密钥的输出文件名的简单方法 input data type key value cupertino apple sunnyvale banana cupe
  • 将多个前缀行过滤器设置为扫描仪 hbase java

    我想创建一台扫描仪 它可以为我提供带有 2 个前缀过滤器的结果例如 我想要其键以字符串 x 开头或以字符串 y 开头的所有行 目前我知道只能使用一个前缀 方法如下 scan setRowPrefixFilter prefixFiltet 在
  • Python - Map/Reduce - 如何在使用 DISCO 计数单词示例中读取 JSON 特定字段

    我正在按照 DISCO 示例来计算文件中的单词数 将单词数作为 Map Reduce 作业 http discoproject org doc disco start tutorial html 我对此工作没有任何问题 但是我想尝试从包含
  • 使用 Hadoop 映射两个数据集

    假设我有两个键值数据集 数据集A和B 我们称它们为数据集A和B 我想用 B 组的数据更新 A 组中的所有数据 其中两者在键上匹配 因为我要处理如此大量的数据 所以我使用 Hadoop 进行 MapReduce 我担心的是 为了在 A 和 B
  • 在映射器的单个输出上运行多个减速器

    我正在使用地图缩减实现左连接功能 左侧有大约 6 亿条记录 右侧有大约 2300 万条记录 在映射器中 我使用左连接条件中使用的列来创建键 并将键值输出从映射器传递到减速器 我遇到性能问题 因为两个表中的值数量都很高的映射器键很少 例如分别
  • Java8:使用 Stream / Map-Reduce / Collector 将 HashMap 转换为 HashMap

    我知道如何 改造 一个简单的JavaList from Y gt Z i e List
  • 在 RavenDB 中创建更多类似的内容

    我的域中有这些文档 public class Article public string Id get set some other properties public IList
  • 以编程方式读取 Hadoop Mapreduce 程序的输出

    这可能是一个基本问题 但我在谷歌上找不到答案 我有一个映射缩减作业 它在其输出目录中创建多个输出文件 我的 Java 应用程序在远程 hadoop 集群上执行此作业 作业完成后 需要使用以下命令以编程方式读取输出org apache had
  • 是否可以通过编写单独的mapreduce程序并行执行Hive查询?

    我问了一些关于提高 Hive 查询性能的问题 一些答案与映射器和减速器的数量有关 我尝试使用多个映射器和减速器 但在执行中没有看到任何差异 不知道为什么 可能是我没有以正确的方式做 或者我错过了其他东西 我想知道是否可以并行执行 Hive
  • 为什么在我的例子中 For 循环比 Map、Reduce 和 List 理解更快

    我编写了一个简单的脚本来测试速度 这就是我发现的结果 实际上 for 循环在我的例子中是最快的 这真的让我感到惊讶 请查看下面 正在计算平方和 这是因为它在内存中保存列表还是有意为之 谁能解释一下这一点 from functools imp
  • Hadoop - 直接从 Mapper 写入 HBase

    我有一个 hadoop 作业 其输出应写入 HBase 我并不真正需要减速器 我想要插入的行类型是在映射器中确定的 如何使用 TableOutputFormat 来实现此目的 从所有示例中 我看到的假设是 reducer 是创建 Put 的
  • MapReduce 中的分区到底是如何工作的?

    我认为我总体上对 MapReduce 编程模型有一定的了解 但即使在阅读了原始论文和其他一些来源之后 我仍然不清楚许多细节 特别是关于中间结果的分区 我将快速总结到目前为止我对 MapReduce 的理解 我们有一个可能非常大的输入数据集
  • Mongodb 聚合数组中的子文档

    我正在使用 mongodb 作为后端实现一个小型应用程序 在此应用程序中 我有一个数据结构 其中文档将包含一个包含子文档数组的字段 我使用以下用例作为基础 http docs mongodb org manual use cases inv
  • MapReduce 中 1 个任务的减速器数量

    在典型的 MapReduce 设置 如 Hadoop 中 1 个任务使用多少个减速器 例如计算单词数 我对 Google MapReduce 的理解意味着只涉及 1 个减速器 那是对的吗 例如 单词计数会将输入分为 N 个块 并且 N 个

随机推荐

  • Ubuntu使用管理员(root)身份登录系统

    Ubuntu使用管理员 xff08 root xff09 身份登录系统 一 Ubuntu安装好后 xff0c Ubuntu系统默认root用户是不能登录的 xff0c 密码也是空的 如果想要使用root用户登录 xff0c 必须先为root
  • Android使用代码进行界面布局和改变图标、标题、名称、主界面

    一 代码进行界面布局 lt xml version 61 34 1 0 34 encoding 61 34 utf 8 34 gt 二 Android Studio改变图标 标题 名称 主界面 注意 xff1a 64 表示是在哪个目录或者是
  • Linux(Ubuntu)系统如何安装Python

    Linux 系统是为编程而生的 xff0c 因此绝大多数的 Linux 发行版 xff08 Ubuntu CentOS 等 xff09 都默认自带了 Python 有的 Linux 发行版甚至还会自带两个版本的 Python xff0c 例
  • 如何用python实现多线程爬虫

    当单线程python爬虫已经不能满足企业需求时 xff0c 很多程序员会进行改代码或者增加服务器数量 xff0c 这样虽说也能达到效果 xff0c 但是对于人力物力也是一笔不小的消耗 如果是技术牛点的 xff0c 正常都会自己重新改写多线程
  • ## Hive分析疫情数据

    拿到的数据部分如下 xff1a 4月27日 黑龙江 境外输入 不详 0 45 0 黑龙江卫健委 https m thepaper cn newsDetail forward 7160075 4月27日 内蒙古 境外输入 不详 0 8 0 央
  • python --根据windows窗口名称、进程pid打开窗口(pygetwindow详解)

    pygetwindow详解 简介 pygetwindow是一个Python库 xff0c 用于获取 操作和管理当前打开的窗口 它提供了一些常用的窗口操作方法 xff0c 包括获取窗口句柄 xff0c 获取窗口位置和大小 xff0c 移动和调
  • Redhat Linux advance Server V2.1无法进入桌面(转)

    Redhat Linux advance Server V2 xff11 无法进入桌面 转 64 more 64 在本地调试安装了个Redhat Linux advance Server V2 1 xff0c 一共有5张光盘 xff0c 我
  • Mac上类似于xshell的远程工具:finalshell 和 royal tsx

    FinalShell 国产 国产 国产 自己研发的 是一体化的的服务器 网络管理软件 不仅是ssh客户端 还是功能强大的开发 运维工具 充分满足开发 运维需求 特色功能 免费海外服务器远程桌面加速 ssh加速 本地化命令输入框 支持自动补全
  • css查找元素注意事项

    一 CSS ID 选择器查找元素 1 注意 xff1a 如果元素的ID不唯一 xff0c 或者是动态的 或者name以及linktext属性值也不唯一 我们就需要考虑用Xpath来查找元素了 xff0c 然后再对元素执行操作 不管用什么方式
  • OS2.3.7:多生产者,多消费者问题

    文章目录 0 问题描述1 问题分析2 实现3 总结 0 问题描述 桌子上有一只盘子 xff0c 每次只能向其中放入一个水果 爸爸专向盘子中放苹果 xff0c 妈妈专向盘子中放橘子 xff0c 儿子专等着吃盘子中的橘子 xff0c 女儿专等着
  • java 方法名类名命名规范

    一 命名规范 1 项目名全部小写 2 包名全部小写 3 类名首字母大写 xff0c 如果类名由多个单词组成 xff0c 每个单词的首字母都要大写 大驼峰 xff0c 如 xff1a public class MyFirstClass 4 变
  • Qt arm环境安装

    一 相关工作准备 Qt opensource 和 Qt everywhere 下载 链接 版本为5 9 8 arm linux gcc下载 链接 版本为4 8 3 tslib 下载 链接 版本为1 21 ps 可以不安装Qt opensou
  • STM32驱动ST7789V2 tft屏幕

    一 简介 本次教程使用的是1 54寸240 240像素的tft屏幕 xff0c 其接口协议为SPI协议 在使用的过程中仅需要四根数据即可驱动点亮屏幕 然后硬件使用的是STM32F103C8T6核心板 xff0c 用的是SPI2 一般购买屏幕
  • linux设置复杂度策略、登录超时处理功能

    1 在字符终端下 xff0c 实现某一用户连续错误登陆N次后 xff0c 就锁定该用户X分钟 pam tally2 执行 vi etc pam d login 在 PAM 1 0 下新起一行 xff0c 加入 auth required p
  • 飞控陀螺仪,磁力计,加速计,四元数姿态结算

    MPU6050主要包含陀螺仪和加速度计 陀螺仪主要测量角速度 xff0c 即可以测出某一时间段物体转过的角度 加速度计测量的是物体的加速度 xff0c 重力加速度即物体受重力作用的情况下具有的加速度 xff0c 物体静止时 xff0c 加速
  • 智慧物业管理系统(Springboot)

    开发工具 xff1a IDEA xff0c jdk1 8 数据库 xff1a mysql5 7 前台框架 xff1a layui 后端技术 xff1a springboot 项目描述 xff1a 1 前台住户登录 2 智慧物业管理后台 2
  • 北京大学2020公开课 AVL-Python实现代码

    class TreeNode def init self key val left 61 None right 61 None parent 61 None self key 61 key self payload 61 val self
  • Docker-2020详细教程<配合千锋Java学习营>

    Docker 2020详细教程 lt 配合千锋Java学习营 gt 2020 Docker最新超详细版教程通俗易懂 一 Docker介绍 1 下载Dcoker依的赖环境 想安装Docker xff0c 需要先将依赖的环境全部下载下来 xff
  • 使用阿里云部署Flask网页

    使用阿里云部署Flask网页 前端网页部署 阿里云apache CentOS 配置好Apache后 xff0c 将一整个html css js文件全部copy进 var www html目录下 之后就可以通过访问IP地址访问到你的index
  • MapReduce的个人理解

    MapReduce的个人理解 文章目录 MapReduce模型简介Map和Reduce函数这里给出一个简单实例 MapReduce的工作流程工作流程概述MapReduce的各个执行阶段 Shuffle过程详解Shuffle过程简介Map端的