当前位置: 首页 > news >正文

MapReduce,Yarn,Spark理解与执行流程

MapReduce的API理解

Mapper

  • 如果是单词计数:hello:1, hello:1, world:1
public void map(Object key, // 首字符偏移量Text value, // 文件的一行内容Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {

Reduce

  • 注意拿到的是value的集合
  • 如果是单词计数:hello:【1,1】,world:【1】
  public void reduce(Text key, // Map端 输出的 key 值Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException{

整体架构

在这里插入图片描述

  • NameNode: 负责存储文件的元信息(如文件的大小、块信息、存储位置等)。通常会部署一个 Secondary NameNode 来周期性合并 NameNode 的 edit log 以减少恢复时间,但它并不是热备,而是辅助管理。避免单点故障
  • JobTracker:负责 Hadoop MapReduce 任务的调度和资源管理,接收作业请求并将任务分配给不同的 TaskTracker(工作节点)
  • DataNode:实际存储数据的节点,存有多个数据块(Block),128MB
  • TaskTracker:实际进行mapper和reduce工作的节点,可以看到图中TaskTracker接近DataNode,这是“移动计算比移动数据更便宜” 的设计理念,目的是减少数据传输,提高计算效率

输入阶段

  1. 文件存储到 HDFS(Hadoop Distributed File System)
  2. 当文件上传到 HDFS 时,文件会先到达 NameNodeNameNode 负责存储文件的元信息(如文件的大小、块信息、存储位置等)。
  3. 随后,文件会被分割成固定大小的数据块(Block),默认每块大小是 128 MB(可以通过配置调整)。
  4. 这些数据块会被分布式地存储到集群中的不同 DataNode 节点上,通常每个块有多个副本(默认是 3 个),以保证数据的可靠性,同步到指定数量的副本后,才向NameNode确认写操作成功,保证一致性。TiDB的底层TiKV的存储也类似这个结构,根据键值对分为多个region,且不同的节点保存奇数个副本,并有raft协议保证一致性。

Mapper阶段

  • TaskTracker 和 Mapper 的运行:
    1. 当执行 MapReduce 作业时,JobTracker会负责任务的调度。
    2. 根据 NameNode 提供的块位置信息,JobTracker 会在包含该块数据的 DataNode 上启动 Mapper,这是数据本地化优化的核心。
    3. 每个 Mapper 会处理一个或多个数据块。
    4. Mapper会将每一行的文件处理成键值对形式,也可以进行数据预处理(过滤、清洗):
// input.txt:
apple 10
banana 20
apple 5// after mapper:
(apple, 5), (apple, 10), (banana, 20)
  1. Mapper 的输出结果存储在本地磁盘的缓存文件中或者磁盘中,并分为多个分区,每个分区对应一个 Reducer

Shuffle 阶段

什么是 Shuffle?

Shuffle 是将 Mapper 输出的中间数据(键值对)分发给 Reducer 的过程。
其主要任务包括:

  1. 对 Mapper 输出的数据进行分区。
  2. 将分区数据从 Mapper 节点移动到 Reducer 节点。
  3. 对分区数据进行排序和合并。
Shuffle 的执行角色
  • Mapper 节点执行分区:

    • 在 Mapper 阶段结束后,输出结果会被分区(默认使用 HashPartitioner)。
    • 每个分区对应一个 Reducer。Mapper 的数据会按照分区规则存储到本地磁盘的多个文件中。
  • JobTracker(或 Yarn)负责协调:

    • JobTracker 会通知各 Reducer 节点**从相应的 Mapper 节点拉取(pull)属于自己的分区数据。
  • Reducer 节点的数据迁移:

    • 每个 Reducer 从多个 Mapper 节点拉取自己的数据。
    • 拉取的数据会临时存储在 Reducer 节点上,并在内存中进行排序和合并,以便 Reducer 处理。

Shuffle 阶段会涉及到数据从 Mapper 节点到 Reducer 节点的迁移,这也是整个 MapReduce 流程中最耗时的一部分。

举个例子,更好理解如何分区以及数据传输:

Shuffle例子

输入文件内容:

File1: Hello Hadoop Hello
File2: Hadoop MapReduce Hadoop

分块:

  • Block1(File1)
  • Block2(File2)
Mapper 输出:

假设有 2 个 Mapper 和 2 个 Reducer,并用 key.hashCode() % 2 作为分区规则。

MapperKeyPartition (Reducer)Output
Mapper1Hello0{Hello: 1}
Mapper1Hadoop1{Hadoop: 1}
Mapper1Hello0{Hello: 1}
Mapper2Hadoop1{Hadoop: 1}
Mapper2MapReduce0{MapReduce: 1}
Mapper2Hadoop1{Hadoop: 1}
Shuffle 阶段:

在 Shuffle 阶段,每个 Reducer 会从多个 Mapper 拉取数据:

ReducerData SourceReceived Data
Reducer0Mapper1 + Mapper2{Hello: [1, 1], MapReduce: [1]}
Reducer1Mapper1 + Mapper2{Hadoop: [1, 1, 1]}
Reducer 聚合:

最终,Reducer 聚合数据,输出结果:

Reducer0: {Hello: 2, MapReduce: 1}
Reducer1: {Hadoop: 3}

Reduce阶段

前面提到,reduce时会向map的节点获取数据,它是如何直到那个mapper节点的呢?
具体是这样的:map任务成功完成后,它们会使用心跳机制通知它们JobTracker。因此,对于指定作业JobTracker 知道 map输出和主机位置之间的映射关系。reducer 中的一个线程定期询问 JobTracker 以便获取 map输出主机的位置,直到获得所有输出位置。

Reduce 任务执行完毕后,输出结果会直接存储到 HDFS,但是Reduce 节点不会主动通知 NameNode 数据位置,而是 HDFS 负责数据存储的元数据管理,Reduce 任务会通过 HDFS 客户端 API 将数据写入 HDFS

写数据到 HDFS 的过程(详)

  1. 客户端请求写入文件:

    客户端(例如 Reducer 或用户程序)向 HDFS 的 NameNode 发起写入请求。
    客户端需要告诉 NameNode 文件的元信息(如文件名、大小等)
    NameNode 分配数据块

    NameNode 根据文件大小、HDFS 的配置(如块大小和副本数量),分配该文件需要的 数据块(Block)

    对于每个块,NameNode 会选择多个 DataNode(通常是 3 个)作为存储目标,并将这些位置信息返回给客户端。

  2. 分配数据块:

    通常会优先选择离客户端最近的节点,或者是同一个机架的节点,来减少网络延迟。副本的存储节点也会尽量分布在不同的机架上,提高数据可靠性

    客户端直接写入 DataNode:客户端根据 NameNode 返回的块位置信息,开始向第一组目标 DataNode 写入数据。写入过程是 流式传输,数据被切分为块后,直接发送给第一个 DataNode

    DataNode 进行副本复制:第一台 DataNode 在接收到数据后,会立即将该数据块传输到下一台 DataNode,依此类推,直到完成所有副本的写入(链式复制)

  3. DataNode 汇报块信息:

    每个 DataNode 在数据写入完成后,会向 NameNode 汇报存储的块信息(如块 ID、块大小、存储位置)

  4. 写入完成:
    当所有数据块都写入成功,并且所有副本都存储完成后,HDFS 客户端通知 NameNode 文件写入完成,保证数据的一致性

    NameNode 将文件的元数据标记为 “完成状态”

MapReduce框架的Java实现

这里手写一个简易的java实现的框架,方便大家理解

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;// 定义 Mapper 接口
interface Mapper {List<Pair<String, Integer>> map(String input);
}// 定义 Reducer 接口
interface Reducer {Pair<String, Integer> reduce(String key, List<Integer> values);
}// 定义 Pair 类,用于存储键值对
class Pair<K, V> {public final K key;public final V value;public Pair(K key, V value) {this.key = key;this.value = value;}@Overridepublic String toString() {return key + ": " + value;}
}// 实现支持多个 Mapper 和 Reducer 的 MapReduce 框架
class ParallelMapReduceFramework {private List<Mapper> mappers;private List<Reducer> reducers;private int reducerCount;public ParallelMapReduceFramework(List<Mapper> mappers, List<Reducer> reducers) {this.mappers = mappers;this.reducers = reducers;this.reducerCount = reducers.size();}public Map<String, Integer> execute(List<String> inputs) throws InterruptedException, ExecutionException {ExecutorService executor = Executors.newFixedThreadPool(mappers.size());// 1. Map 阶段:将输入数据分给多个 Mapper 并行处理List<Future<List<Pair<String, Integer>>>> mapResults = new ArrayList<>();int chunkSize = inputs.size() / mappers.size();for (int i = 0; i < mappers.size(); i++) {int start = i * chunkSize;int end = (i == mappers.size() - 1) ? inputs.size() : (i + 1) * chunkSize;List<String> chunk = inputs.subList(start, end);Mapper mapper = mappers.get(i);mapResults.add(executor.submit(() -> {List<Pair<String, Integer>> results = new ArrayList<>();for (String input : chunk) {results.addAll(mapper.map(input));}return results;}));}// 收集所有 Mapper 生成的键值对List<Pair<String, Integer>> allMappedData = new ArrayList<>();for (Future<List<Pair<String, Integer>>> future : mapResults) {allMappedData.addAll(future.get());}// 2. Shuffle 阶段:将键值对分片,分配给不同的 ReducerMap<Integer, List<Pair<String, Integer>>> reducerInput = new HashMap<>();for (int i = 0; i < reducerCount; i++) {reducerInput.put(i, new ArrayList<>());}for (Pair<String, Integer> pair : allMappedData) {int reducerIndex = Math.abs(pair.key.hashCode() % reducerCount);reducerInput.get(reducerIndex).add(pair);}// 3. Reduce 阶段:每个 Reducer 处理一个分片数据List<Future<Map<String, Integer>>> reduceResults = new ArrayList<>();for (int i = 0; i < reducers.size(); i++) {int index = i;Reducer reducer = reducers.get(i);List<Pair<String, Integer>> inputForReducer = reducerInput.get(index);reduceResults.add(executor.submit(() -> {// 按键分组Map<String, List<Integer>> groupedData = new HashMap<>();for (Pair<String, Integer> pair : inputForReducer) {groupedData.computeIfAbsent(pair.key, k -> new ArrayList<>()).add(pair.value);}// Reduce 操作Map<String, Integer> result = new HashMap<>();for (Map.Entry<String, List<Integer>> entry : groupedData.entrySet()) {result.put(entry.getKey(), reducer.reduce(entry.getKey(), entry.getValue()).value);}return result;}));}// 收集所有 Reducer 的结果Map<String, Integer> finalResult = new HashMap<>();for (Future<Map<String, Integer>> future : reduceResults) {finalResult.putAll(future.get());}executor.shutdown();return finalResult;}
}// 实现单词统计的 Mapper 和 Reducer
class WordCountMapper implements Mapper {@Overridepublic List<Pair<String, Integer>> map(String input) {String[] words = input.split("\\s+");List<Pair<String, Integer>> result = new ArrayList<>();for (String word : words) {result.add(new Pair<>(word.toLowerCase(), 1));}return result;}
}class WordCountReducer implements Reducer {@Overridepublic Pair<String, Integer> reduce(String key, List<Integer> values) {int sum = values.stream().mapToInt(Integer::intValue).sum();return new Pair<>(key, sum);}
}// 测试并行 MapReduce 框架
public class ParallelWordCountExample {public static void main(String[] args) throws InterruptedException, ExecutionException {// 输入数据List<String> inputs = Arrays.asList("Hello world hello","MapReduce is powerful","Hello MapReduce world","Java is great","Hello from the other side");// 创建多个 Mapper 和 Reducer 实例List<Mapper> mappers = Arrays.asList(new WordCountMapper(), new WordCountMapper());List<Reducer> reducers = Arrays.asList(new WordCountReducer(), new WordCountReducer());// 执行 MapReduceParallelMapReduceFramework framework = new ParallelMapReduceFramework(mappers, reducers);Map<String, Integer> wordCounts = framework.execute(inputs);// 输出结果wordCounts.forEach((word, count) -> System.out.println(word + ": " + count));}
}

Yarn(MapReduce2)

MapReducer1的问题:

前面提到的MapReducer的模型的问题:

  1. JobTracker的负载(可扩展性):MapReduce 1 中,,obtracker 同时负责作业调度(将任务与 tasktracker 匹配)和任务进度监控(跟踪任务、重启失败或迟缓的任务;记录任务流水,如维护计数器的计数)。当任务实例过多时,会导致系统无法再扩展
  2. JobTracker的可用性:由于JobTracker管理所有应用的状态,为了实现其可用性,就要创建副本并同步内存中的数据,强一致性意味着性能的损耗,弱一致性意味着故障恢复时的数据的差异。
  3. 节点的利用率:MapReduce 1中,每个tasktracker都配置有若干固定长度和类型的slot,这些slot是静态分配的,在配置的时候就被划分为map slot和reduce slot。一个map slot仅能用于运行一个map任务,一个reduce slot仅能用于运行一个reduce任务,所以分配不当就会导致系统性能低下

针对以上几个问题,Yarn将jobTracker的工作拆分,分为资源管理器(负责作业调度),以及application Master(负责任务进度监控,一个MapperReducer应用对应一个application Master),通过合理的资源分配提高节点的利用率,每个应用交由一个master管理,可以无限扩展资源避免单点的负载过大,还可以通过zookeeper等机制分别实现资源管理器和application master的高可用(如失败后再次申请资源)。

还有一个优点就是实现了多租户,对于资源的抽象和分配机制,可以在Yarn上构建不同的应用,如Spark等
![[Pasted image 20250126181445.png]]

MapReducer2的工作流程

申明几个概念

  1. Yarn的资源管理器,申请的资源即为一个container,可以指定其计算机的资源数量(内存和CPU),可以理解为之前版本的DataNode拆分成了多个容器
  2. Map,reduce的执行是容器中的进程,而前面提到的Application Master实际上也是容器中的进程,只是功能较为特殊
  3. 一个MapReduce应用对应一个Application Master
  4. 一个节点对应一个Node Manager,负责管理该节点上的所有容器和心跳

![[Pasted image 20250126182139.png]]

  • 1-5的步骤较为简单,就是创建一个container用于生成application master。具体是资源管理器收到调用它的submitApplication()消息后,便将请求传递给 YARN调度器(scheduler)。调度器分配一个容器,然后资源管理器在节点管理器的管理下在容器中启动application master的进程
  • 接下来,它接受来自共享文件系统的、在客户端计算的输入分片(步骤7)。然后对每一个分片创建一个 map任务对象以及由mapreduce.job.reduces 属性(通过作业的 setNumReduceTasks()方法设置),根据配置确定多个reduce任务对象
  • application master就会为该作业中的所有map任务和reduce任务向资源管理器请求执行具体任务的容器
  • 一旦资源管理器的调度器为任务分配了一个特定节点上的容器,application master就通过与节点管理器通信来启动容器(步骤9a和9b)。该任务由主类为YarnChild的一个 Java 应用程序执行。在它运行任务之前,首先将任务需要的资源本地化,包括作业的配置、JAR 文件和所有来自分布式缓存的文件(步骤 10)。最后,运行map任务或reduce任务(步骤11)。

Spark

适用场景

Spark 最突出的表现在于它能将作业与作业之间产生的大规模的工作数据集存储在内存中。MapReduce的数据集始终需要从磁盘上加载。从Spark 处理模型中获益最大的两种应用类型分别为迭代算法(即对一个数据集重复应用某个函数,直至满足退出条件)和交互式分析(用户向数据集发出一系列专用的探索性查询,比如查出数据后,根据数据在进行多次筛选分析)。

相关概念

RDD

RDD(Resilient Distributed Dataset)是 Spark 的核心抽象,用于表示分布式、不变、容错的数据集。

RDD的分区(Partition) 是 Spark 对数据的基本并行处理单元。RDD会被分割成多个分区,并在多个节点上并行处理,以实现高效的分布式计算。分区的大小就是HDFS 文件默认块大小(HDFS block size),通常为 128MB。可以理解为从HDFS中读取block到内存中,并且对这个block进行计算的抽象

举个例子,我们在 Spark 中使用 textFile(“hdfs://path/to/my_data.txt”) 读取时,RDD 会被划分为2 个分区,分别对应:

Partition 1 在 Node A 处理 Block 1 数据
Partition 2 在 Node B 处理 Block 2 数据

RDD的操作

RDD的生成,一个是读取文件,在不同的block中生成分区,还有一个就是对现有的RDD进行转换

JavaRDD<String> rdd = sc.textFile("hdfs://path/to/my_data.txt");
JavaRDD<String> filteredRDD = rdd.filter(line -> line.contains("error"));
JavaPairRDD<String, Integer> counts = filteredRDD.mapToPair(line -> new Tuple2<>(line, 1)).reduceByKey((a, b) -> a + b);
// 触发RDD开始转换,foreach函数也可以触发
counts.saveAsTextFile("hdfs://path/to/output");

以上的代码中的filter,mapToPair,reduceByKey就是一系列动作,类似于响应式编程中的订阅发布,当实际订阅(也就是这里的saveAsTextFile执行时),才会触发发布(RDD的开始转换),即惰性转换

RDD的持久化

spark的特性就是能够保存中间数据在内存默认RDD不会保存到内存中,当我们需要某部分数据时,可以手动将其保存到内存中,方便下一次计算,以下调用cache缓存
![[Pasted image 20250126230342.png]]

当执行RDD转换时,提示已经保存:
![[Pasted image 20250126230428.png]]

当下一次对该RDD重新进行不同的转换时,提示用到了缓存:
![[Pasted image 20250126230507.png]]

DAG和Stage

多个RDD的转换形成一个有向无环图,当一些可以基于本地的RDD的操作进行的转换的执行链,即每个分区的数据只依赖于上游 RDD (在本地)的一个分区的话(如 map(), filter()),我们当然可以在同一个节点中进行这个转换操作,这称为窄依赖

如果当前 RDD 的分区需要依赖多个上游 RDD 分区(如 reduceByKey(), groupBy()),那么会发生 Shuffle,相当于触发了一次reduce操作,这成为宽依赖

而这个DAG会因为出现宽依赖而进行stage的划分,将执行链拆分成不同的stage部分,每一个stage交给一个节点运行

这个很好理解,相当于上游RDD的reduceByKey需要进行一个类似于mapreducer中的shuffle操作,下游RDD的reduceByKey需要进行一个类似于mapreducer中的reduce操作,而reduce的数据非本地的,且对应的所需要的reduce的任务数量也不等同于map阶段的任务数,所以重新分配

![[Pasted image 20250126232041.png|475]]

执行过程

![[Pasted image 20250126224535.png]]

相关文章:

MapReduce,Yarn,Spark理解与执行流程

MapReduce的API理解 Mapper 如果是单词计数&#xff1a;hello&#xff1a;1&#xff0c; hello&#xff1a;1&#xff0c; world&#xff1a;1 public void map(Object key, // 首字符偏移量Text value, // 文件的一行内容Context context) // Mapper端的上下文&#xff0c;…...

elk 安装

创建elk网络 docker network create -d bridge elkelasticsearch 创建目录 mkdir -p /data/elasticsearch/{conf,logs,data,plugins}vim /data/elasticsearch/conf/elasticsearch.ymlcluster.name: "es-cluster" network.host: 0.0.0.0 xpack.security.enabled: tr…...

二十三种设计模式-桥接模式

桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;其核心思想是将抽象与实现解耦&#xff0c;让它们可以独立变化。桥接模式主要用于解决类的继承问题&#xff0c;避免由于继承而带来的类层次结构过于复杂和难以维护的问题。 1. 核心概念 桥接…...

【Validator】字段验证器struct与多层级验证,go案例

标签用法总结表 标签功能代码实例required字段必填Name string \v:“required”alphaunicode验证字段是否只包含字母和 Unicode 字符Name string \v:“alphaunicode”gte验证字段值是否大于等于指定值Age uint8 \v:“gte10”lte验证字段值是否小于等于指定值Age uint8 \v:“lt…...

第19篇:python高级编程进阶:使用Flask进行Web开发

第19篇&#xff1a;python高级编程进阶&#xff1a;使用Flask进行Web开发 内容简介 在第18篇文章中&#xff0c;我们介绍了Web开发的基础知识&#xff0c;并使用Flask框架构建了一个简单的Web应用。本篇文章将深入探讨Flask的高级功能&#xff0c;涵盖模板引擎&#xff08;Ji…...

jEasyUI 创建复杂布局

jEasyUI 创建复杂布局 引言 jEasyUI 是一款基于 jQuery 的开源 UI 框架,它提供了一套丰富的 UI 组件,帮助开发者快速构建美观、易用的 Web 应用。在开发过程中,复杂布局的创建往往是一个挑战。本文将详细介绍如何使用 jEasyUI 创建复杂布局,帮助开发者提升工作效率。 前…...

前端【8】HTML+CSS+javascript实战项目----实现一个简单的待办事项列表 (To-Do List)

目录 一、功能需求 二、 HTML 三、CSS 四、js 1、绑定事件与初始设置 2.、绑定事项 &#xff08;1&#xff09;添加操作&#xff1a; &#xff08;2&#xff09;完成操作 &#xff08;3&#xff09;删除操作 &#xff08;4&#xff09;修改操作 3、完整js代码 总结…...

java爬虫工具Jsoup学习

目录 前言 一、基本使用 二、爬取豆瓣电影的案例 三、Jsoup能做什么&#xff1f; 四、Jsoup相关概念 五、Jsoup获取文档 六、定位选择元素 七、获取数据 八、具体案例 前言 JSoup是一个用于处理HTML的Java库&#xff0c;它提供了一个非常方便类似于使用DOM&#xff0…...

RabbitMQ模块新增消息转换器

文章目录 1.目录结构2.代码1.pom.xml 排除logging2.RabbitMQConfig.java3.RabbitMQAutoConfiguration.java 1.目录结构 2.代码 1.pom.xml 排除logging <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/PO…...

大话特征工程:1.维数灾难与特征轮回

一、维度深渊 公元 2147 年&#xff0c;人类文明进入了数据驱动的超级智能时代。从金融到医疗&#xff0c;从教育到娱乐&#xff0c;所有决策都仰赖“全维计算网络”&#xff08;高维特征空间&#xff09;。这套系统将全球所有信息抽象成数以亿计的多维特征&#xff08…...

学院失物招领 app 的设计与实现

标题:学院失物招领 app 的设计与实现 内容:1.摘要 随着移动互联网的普及和智能手机的广泛应用&#xff0c;越来越多的人开始使用手机应用程序来解决生活中的各种问题。在大学校园中&#xff0c;失物招领是一个常见的问题&#xff0c;每年都有大量的学生丢失或捡到物品。为了解…...

std::function的简易实现

本节我们来实现一个简易的std::function 我们知道std::function是用来包装可调用对象的&#xff0c;在C中&#xff0c;可调用对象包括 普通函数、lambda表达式、重载了()操作符的类对象、类静态函数、类成员函数这几类。 C程序的编译顺序&#xff1a;预处理(xxx.i) 编译(xxx.…...

笔试-二维数组1

应用 快递业务有N个站点&#xff0c;1<N<10000&#xff1b;站点0、站点1可达&#xff0c;记作0-1&#xff1b;如果0-1、1-2&#xff0c;则站点0、站点2可达&#xff0c;记作0-2&#xff1b;s[i][j]1表示i-j可达&#xff0c;反之s[i][j]0表示i-j不可达&#xff1b;s[i][j…...

【Pytest】生成html报告中,中文乱码问题解决方案

import pytestif __name__ "__main__":# 只运行 tests 目录下的测试用例&#xff0c;并生成 HTML 报告pytest.main([-v, -s, --htmlreport.html, tests])可以以上方式生成&#xff0c;也可以在pytest.ini中设置 [pytest] addopts --htmlreport.html --self-contai…...

汽车网络信息安全-ISO/SAE 21434解析(下)

目录 第十二~十四章 - 后开发阶段 1. 十二章节 - 生产 2. 十三章节 - 运营与维护 网络安全事件响应 更新 3. 十四章节 - 结束网络安全支持和停用 结束网络安全支持 报废 第十五章 - TARA分析方法 1. 概述 2. 资产识别 3. 威胁场景识别 4. 影响评级 5. 攻击路径分…...

局域网中 Windows 与 Mac 互相远程连接的最佳方案

由于工作需要&#xff0c;经常需要远程连接或登录到几台不同的工作用机上进行操作。 下面基于免费、高体验等基本诉求&#xff0c;简要记录几种不同场景下的实践方案选择&#xff0c;仅供参考。如您有更简单且更优的方案&#xff0c;欢迎一起探讨。 1 远程桌面连接的几种不同…...

Qt调用ffmpeg库录屏并进行UDP组播推流

基于以下参考链接&#xff0c;采用其界面和程序框架&#xff0c;实现实时推送UDP组播视频流&#xff0c;替换原拉流功能 https://blog.csdn.net/u012532263/article/details/102736700 源码在windows&#xff08;qt-opensource-windows-x86-5.12.9.exe&#xff09;、ubuntu20.…...

机器学习 - 初学者需要弄懂的一些线性代数的概念

一、单位矩阵 在数学中&#xff0c;单位矩阵是一个方阵&#xff0c;其主对角线上的元素全为1&#xff0c;其余元素全为0。单位矩阵在矩阵乘法中起到类似于数字1在数值乘法中的作用&#xff0c;即任何矩阵与单位矩阵相乘&#xff0c;结果仍为原矩阵本身。 单位矩阵的定义&…...

vscode无法格式化go代码的问题

CTRLshiftp 点击Go:Install/Update Tools 点击全选&#xff0c;OK&#xff01;...

实验二 数据库的附加/分离、导入/导出与备份/还原

实验二 数据库的附加/分离、导入/导出与备份/还原 一、实验目的 1、理解备份的基本概念&#xff0c;掌握各种备份数据库的方法。 2、掌握如何从备份中还原数据库。 3、掌握数据库中各种数据的导入/导出。 4、掌握数据库的附加与分离&#xff0c;理解数据库的附加与分离的作用。…...

基于Django的个人博客系统的设计与实现

【Django】基于Django的个人博客系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 系统采用Python作为主要开发语言&#xff0c;结合Django框架构建后端逻辑&#xff0c;并运用J…...

PostgreSQL TRUNCATE TABLE 操作详解

PostgreSQL TRUNCATE TABLE 操作详解 引言 在数据库管理中,经常需要对表进行操作以保持数据的有效性和一致性。TRUNCATE TABLE 是 PostgreSQL 中一种高效删除表内所有记录的方法。本文将详细探讨 PostgreSQL 中 TRUNCATE TABLE 的使用方法、性能优势以及注意事项。 什么是 …...

黑盒/白盒运维监控

运维监控分为黑盒和白盒 黑盒&#xff1a;不深入代码&#xff0c;在系统角度看TPS&#xff0c;延迟等指标 白盒&#xff1a;深入代码分析&#xff0c;通过日志捕捉&#xff0c;以及主动上报告警等来进行监控 黑盒监控&#xff1a; 1. 页面功能&#xff1a;域名是否可访问&…...

日志收集Day007

1.配置ES集群TLS认证: (1)elk101节点生成证书文件 cd /usr/share/elasticsearch ./bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass "" --days 3650 (2)elk101节点为证书文件修改属主和属组 chown elasticsearch:elasticsearch con…...

微信小程序1.1 微信小程序介绍

1.1 微信小程序介绍 内容提要 1.1 什么是微信小程序 1.2 微信小程序的功能 1.3 微信小程序使用场景 1.4 微信小程序能取代App吗 1.5 微信小程序的发展历程 1.6微信小程序带来的机会...

Leetcode 3434. Maximum Frequency After Subarray Operation

Leetcode 3434. Maximum Frequency After Subarray Operation 1. 解题思路2. 代码实现 题目链接&#xff1a;3434. Maximum Frequency After Subarray Operation 1. 解题思路 这一题的话我们只需要考察所有的数 i i i转换为 k k k时所能够形成的最大的值。 而对于这个问题&…...

6. 使用springboot做一个音乐播放器软件项目【1.0版项目完结】附带源码~

#万物OOP 注意&#xff1a; 本项目只实现播放音乐和后台管理系统。 不分享任何音乐歌曲资源。 上一篇文章我们 做了音乐播放器后台的功能。参考地址&#xff1a; https://jsonll.blog.csdn.net/article/details/145214363 这个项目已经好几天也没更新了&#xff0c;因为临近放…...

php twig模板引擎详细使用教程

php twig模板引擎 1. 什么是Twig模板引擎 Twig是一个强大且灵活的PHP模板引擎&#xff0c;它提供了一种更简洁和可扩展的方法来创建PHP应用程序的视图层。Twig模板引擎旨在将设计与业务逻辑分离&#xff0c;并为开发人员提供一种更加清晰和易于维护的方式来构建网页。Twig由S…...

【Java设计模式-7】责任链模式:我是流水线的一员

一、责任链&#xff08;Chain of Responsibility Patten&#xff09;模式是个啥&#xff1f; 想象一下&#xff0c;你要请假。你先把请假申请交给了小组长&#xff0c;小组长一看&#xff0c;这事儿他能决定&#xff0c;就直接批了。要是小组长觉得这事儿得往上汇报&#xff0…...

Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面

目录 一、配置拦截器进行登录校验 1. 在config层设置拦截器 2. 实现LoginInterceptor拦截器 3. 创建JWT工具类 4. 在登录时创建JWT并存入Cookie 二、配置JWT依赖和环境 1. 添加JWT依赖 2. 配置JWT环境 本篇博客将为大家介绍了如何在Spring Boot应用中实现基于JWT的登录…...

【2025年数学建模美赛F题】(顶刊论文绘图)模型代码+论文

全球网络犯罪与网络安全政策的多维度分析及效能评估 摘要1 Introduction1.1 Problem Background1.2Restatement of the Problem1.3 Literature Review1.4 Our Work 2 Assumptions and Justifications数据完整性与可靠性假设&#xff1a;法律政策独立性假设&#xff1a;人口统计…...

计算机网络之链路层

本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记&#xff0c;就不再多余写了&#xff0c;直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…...

随笔十七、eth0单网卡绑定双ip的问题

在调试语音对讲过程中遇到过一个“奇怪”问题&#xff1a;泰山派作为一端&#xff0c;可以收到对方发来的语音&#xff0c;而对方不能收到泰山派发出的语音。 用wireshark抓包UDP发现&#xff0c;泰山派发送的地址是192.168.1.30&#xff0c;而给泰山派实际设置的静态地址是19…...

coffee销售数据集分析:基于时间趋势分析的实操练习

**文章说明&#xff1a;**对coffee销售数据集的简单分析练习&#xff08;时间趋势分析练习&#xff09;&#xff0c;主要是为了强化利用python进行数据分析的实操能力。属于个人的练习文章。 **注&#xff1a;**这是我第一次使用md格式编辑博客文章&#xff0c;排版上还是不是很…...

在 Vue 3 中,怎么管理环境变量

在 Vue 3 中&#xff0c;环境变量管理是通过 .env 文件来进行的&#xff0c;利用这些文件可以让开发者根据不同的环境&#xff08;开发、生产、测试等&#xff09;配置不同的变量。这一机制由 Vite 构建工具支持&#xff0c;它帮助开发者根据不同的环境需求做出相应配置。 1. …...

shallowRef和shallowReactive的用法以及使用场景和ref和reactive的区别

Vue3 浅层响应式 API 1. ref vs shallowRef 1.1 基本概念 ref: 深层响应式&#xff0c;会递归地将对象的所有属性转换为响应式shallowRef: 浅层响应式&#xff0c;只有 .value 的改变会触发更新&#xff0c;不会递归转换对象的属性 1.2 使用对比 // ref 示例 const deepRe…...

mantisbt添加修改用户密码

文章目录 问题当前版本安装流程创建用户修改密码老的方式探索阶段 问题 不太好改密码啊。貌似必须要域名要发邮件。公司太穷&#xff0c;看不见的东西不关心&#xff0c;只能改源码了。 当前版本 当前mantisbt版本 2.27 php版本 7.4.3 安装流程 &#xff08;下面流程不是…...

mysql 学习6 DQL语句,对数据库中的表进行 查询 操作

前期准备数据 重新create 一张表 create table emp(id int comment 编号,workno varchar(10) comment 工号,name varchar(10) comment 姓名,gender char comment 性别,ager tinyint unsigned comment 年龄,idcard char(18) comment 身份证号,workaddress varchar(10) c…...

零售业革命:改变行业的顶级物联网用例

mpro5 产品负责人Ruby Whipp表示&#xff0c;技术进步持续重塑零售业&#xff0c;其中物联网&#xff08;IoT&#xff09;正引领这一变革潮流。 研究表明&#xff0c;零售商们正在采用物联网解决方案&#xff0c;以提升运营效率并改善顾客体验。这些技术能够监控运营的各个方面…...

云计算的概念与特点:开启数字化时代的新篇章

在当今数字化时代,云计算(Cloud Computing)已经成为推动技术创新和业务转型的核心力量。无论是大型企业、中小型企业,还是个人用户,云计算都为其提供了高效、灵活和经济的解决方案。本文将深入探讨云计算的概念及其核心特点,帮助读者全面了解这一革命性技术。 © ivw…...

第二十一周:Mask R-CNN

Mask R-CNN 摘要Abstract文章信息研究动机Mask RCNNRoIPool与RoIAlign 双线性插值Mask Branch(FCN)其他细节Mask RCNN损失Mask分支预测 网络搭建创新点与不足总结 摘要 本篇博客介绍了Mask R-CNN&#xff0c;这是一种用于实例分割的模型&#xff0c;能够在目标检测的基础上实现…...

特朗普政府将开展新网络攻击

近日&#xff0c;特朗普政府已表态&#xff1a;减少物理战争&#xff0c;网络战将代替&#xff0c;以实现美国的全球优势。 特朗普也指示美国网络司令部可以在没有总统批准的情况下开展更广泛行动&#xff0c;尤其是应对一些突发事件&#xff0c;这其实成为了后续美国通过网络…...

Android Studio:视图绑定的岁月变迁(2/100)

一、博文导读 本文是基于Android Studio真实项目&#xff0c;通过解析源码了解真实应用场景&#xff0c;写文的视角和读者是同步的&#xff0c;想到看到写到&#xff0c;没有上帝视角。 前期回顾&#xff0c;本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

【已解决】黑马点评项目Redis版本替换过程的数据迁移

黑马点评项目Redis版本替换过程的数据迁移 【哭哭哭】附近商户中需要用到的GEO功能只在Redis 6.2以上版本生效 如果用的是老版本&#xff0c;美食/KTV的主页能正常返回&#xff0c;但无法显示内容 上次好不容易升到了5.0以上版本&#xff0c;现在又用不了了 Redis 6.2的windo…...

Maven运行任何命令都报错“Internal error: java.lang.ArrayIndexOutOfBoundsException”

今天遇到一个奇怪的问题&#xff0c;在maven工程下运行任何mvn命令都报“Internal error: java.lang.ArrayIndexOutOfBoundsException”错误&#xff0c;具体错误如下&#xff1a; $ mvn install [INFO] Scanning for projects... [ERROR] Internal error: java.lang.ArrayInd…...

电商平台爬虫开发技术分享:多年的实战经验总结

在当今数字化时代&#xff0c;电商平台的数据蕴含着巨大的商业价值。作为一名从事电商平台爬虫开发的工程师&#xff0c;我深知数据抓取的重要性及其技术挑战。经过多年的实践&#xff0c;我积累了一些宝贵的经验&#xff0c;愿意在这里与大家分享&#xff0c;希望能为同行们提…...

大模型训练策略与架构优化实践指南

标题&#xff1a;大模型训练策略与架构优化实践指南 文章信息摘要&#xff1a; 该分析全面探讨了大语言模型训练、架构选择、部署维护等关键环节的优化策略。在训练方面&#xff0c;强调了pre-training、mid-training和post-training的不同定位与目标&#xff1b;在架构选择上…...

DeepSeek-R1 蒸馏模型及如何用 Ollama 在本地运行DeepSeek-R1

在人工智能飞速发展的领域中&#xff0c;大型语言模型&#xff08;LLMs&#xff09;的出现可谓是一项重大变革。在这些模型里&#xff0c;DeepSeek - R1 及其蒸馏模型备受瞩目&#xff0c;它们融合了独特的能力与高可用性。今天我们一起聊一下 DeepSeek - R1 蒸馏模型究竟是什么…...

机器学习 ---逻辑回归

逻辑回归是属于机器学习里面的监督学习&#xff0c;它是以回归的思想来解决分类问题的一种非常经典的二分类分类器。由于其训练后的参数有较强的可解释性&#xff0c;在诸多领域中&#xff0c;逻辑回归通常用作 baseline 模型&#xff0c;以方便后期更好的挖掘业务相关信息或提…...

虚幻浏览器插件 UE与JS通信

温馨提示&#xff1a;本节内容需要结合插件Content下的2_Communication和Resources下的sample.html 一起阅读。 1. UE调用JS 1.1 JS脚本实现 该部分共两步: 导入jstote.js脚本实现响应函数并保存到 ue.interface 中 jsfunc 通过json对象传递参数&#xff0c;仅支持函数名小…...