Hadoop的第二个核心组件:MapReduce框架第二节

news2025/1/13 8:09:09

Hadoop的第二个核心组件:MapReduce框架第二节

  • 六、MapReduce的工作流程原理(简单版本)
  • 七、MapReduce中的序列化机制问题
  • 八、流量统计案例实现(序列化机制的实现)

六、MapReduce的工作流程原理(简单版本)

1、客户端在执行MR程序时,客户端先根据设置的InputFormat实现类去对输入的数据文件进行切片(getSplits),如果没有设置InputFormat实现类,MR程序会使用默认的实现类(TextInputFormat–>FileInputFormat的子类)进行切片规划,生成一个切片规划文件

2、客户端的切片规划文件生成以后,客户端还会把整个MR程序的配置项(Configuration配置),会封装成为一个job.xml文件,同时还会把MR程序的代码包括job.xml文件、切片规划文件提交给资源调度器(YARN/windowsCPU),资源调度器会先分配资源启动MRAPPMaster的进程

3、MRAPPMaster会根据切片规划的切片个数,向资源调度器申请资源启动对应个数的MapTask任务去运行Mapper阶段的计算逻辑

4、MapTask启动成功以后会根据切片规划,借助指定的InputFormat的实现类中createRecoder方法去对应的切片中读取k-v数据,然后交给map方法做处理

5、map方法将切片的k-v数据处理完成,会k-v数据写到一个内存缓冲区中(100M),如果内存缓冲区超过容量的80%,会溢写磁盘,溢写磁盘的时候会根据map输出的key值进行排序,同时还会根据指定的Partitioner分区机制进行分区。溢写文件可能会存在多个,等map阶段执行完成,每一个MapTask对应的多个溢写文件以及缓冲区中还没有溢写的数据整体会进行一次合并,形成一个最终的大文件(分区排序)

6、紧跟着MRAPPMaster会向资源管理器申请资源启动ReduceTask,ReduceTask启动成功会从不同的MapTask的合并的大的溢写文件中去复制对应的分区的数据,ReduceTask会对所有复制过来的数据再进行一次排序。

7、ReduceTask会对排好序的数据按照key进行分组,分好组之后一组相同的key值调用一次reduce方法进行计算,计算完成的数据会借助指定的OutputFormat类(没有指定,默认使用TextOutputFormat类 - FileOutputFormat实现子类)将key-value数据写出到最终的结果文件中part-r-xxxxx

七、MapReduce中的序列化机制问题

MR程序的Map阶段和Reduce阶段都是要求输入的数据和输出的数据必须得是key-value键值对类型的数据,而且key-value必须得是序列化类型的数据。

序列化:将Java中的某种数据类型转成二进制数据

反序列化:将二进制数据转换成某种数据类型

MR程序采用序列化机制的原因:MR程序之所以要求输入和输出的数据是K-V类型的,是因为MR程序是一个分布式计算程序,MR程序可以在多个节点上同时运行的,而且多个计算程序计算出来的结果可能跨节点,跨网络进行数据传输的。如果数据要跨节点跨网络传输,要求数据必须是二进制数据。(MapReduce程序运行中,Mapper阶段和Reducer阶段的输入和输出都是以key-value的格式进行的。同时Mapper和Reducer阶段的任务中需要的数据可能会跨网络或者跨节点传输,因此我们就要求,MR程序运行过程中所有的输入和输出的数据必须都得是可以被序列化的。)

Hadoop在进行Key-Value的序列化的时候,没有采用Java的序列化机制(Serializable、Externalizable),因为Java的序列化机制非常的笨重的,因此Hadoop基于Java的序列化机制方式提供了一种全新的专门适用于MR程序的轻量级的序列化机制。

Hadoop中提供了两个接口:Writable、WritableComparable,Hadoop提供的两个序列化机制。

Writable

  • 只有序列化和反序列化的效果,如果我们自定义的一个数据类型(Java类)要想当MR程序的value使用的话,Java类必须实现Writable接口,重写两个方法(write - 序列化写、readFields - 反序列化读),通过这两个方法规定序列化和反序列化的内容。

  • Writable的使用方式类似于Java中Externalizable序列化机制

WritableComparable

  • 接口除了具备序列化和反序列化的能力以外,还具备一个比较大小关系的方法

  • 如果自定义的数据类型(Java类),想当MR程序中的key值来使用,必须实现此接口,让自定义数据类型既可以进行序列化反序列化还可以进行大小的比较判断。

  • 如果自定义的数据类型只想当作MR程序中的value来使用,只需要实现Writable接口即可,不需要比较大小。

Hadoop常见的序列化类型(Hadoop把Java中包装类和String类型已经给我们封装好了对应的Hadoop序列化类型) —— 实现了WritableComparable接口

Java类型Hadoop Writable类型
booleanBooleanWritable
byteByteWritable
intIntWritable
floatFloatWritable
longLongWritable
doubleDoubleWritable
stringText
mapMapWritable
arrayArrayWritable

【注意】
1、如果以后MR程序运行没有报错,但是输出目录没有任何的内容,一般可能是因为输入和输出的key-value的自定义类型没有实现序列化。
2、如果自定义的JavaBean充当Reducer阶段输出key-value时,最好把toString方法给重写了,否则Reducer最后输出的结果是JavaBean的地址值。

八、流量统计案例实现(序列化机制的实现)

import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Objects;

/**
 * JavaBean:是Java中一种很干净的类,类当中只具备私有化的属性、构造器、getter   setter方法 hashCode  equals方法 toString方法
 * 实体类:实体类又是一种特殊的JavaBean,当JavaBean是和数据库中数据表对应的类的时候,JavaBean称之为实体类
 *
 * JavaBean可以自己手动的生成,也可以使用Lombok技术基于注解快速创建Java类
 *      Lombok使用慎重,Lombok对代码的侵占性是非常大的
 *
 * 如果自定义的JavaBean要当MR程序的输入和输出的KV值,最好让JavaBean存在一个无参构造器(MR程序底层反射构建这个类的对象)
 * 如果自定义的JavaBean要去充当Reducer阶段KEY和Value,那也就意味着JavaBean的结果要写到最终的结果文件中,JavaBean的数据往结果文件写的格式还是按照JavaBean的toString方法去写的。
 */
public class FlowBean implements Writable {
    private Long upFlow;//上行流量
    private Long downFlow;//下行流量
    private Long sumFlow;//总流量

    public FlowBean() {
    }

    public FlowBean(Long upFlow, Long downFlow, Long sumFlow) {
        this.upFlow = upFlow;
        this.downFlow = downFlow;
        this.sumFlow = sumFlow;
    }

    public Long getUpFlow() {
        return upFlow;
    }

    public void setUpFlow(Long upFlow) {
        this.upFlow = upFlow;
    }

    public Long getDownFlow() {
        return downFlow;
    }

    public void setDownFlow(Long downFlow) {
        this.downFlow = downFlow;
    }

    public Long getSumFlow() {
        return sumFlow;
    }

    public void setSumFlow(Long sumFlow) {
        this.sumFlow = sumFlow;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FlowBean flowBean = (FlowBean) o;
        return Objects.equals(upFlow, flowBean.upFlow) && Objects.equals(downFlow, flowBean.downFlow) && Objects.equals(sumFlow, flowBean.sumFlow);
    }

    @Override
    public int hashCode() {
        return Objects.hash(upFlow, downFlow, sumFlow);
    }

    @Override
    public String toString() {
        return upFlow + "\t" + downFlow + "\t" + sumFlow;
    }

    /**
     * 序列化写的方法
     * @param out <code>DataOuput</code> to serialize this object into.
     * @throws IOException
     */
    @Override
    public void write(DataOutput out) throws IOException {
        out.writeLong(upFlow);
        out.writeLong(downFlow);
        out.writeLong(sumFlow);
    }

    /**
     * 反序列化读取数据的方法
     * @param in <code>DataInput</code> to deseriablize this object from.
     * @throws IOException
     */
    @Override
    public void readFields(DataInput in) throws IOException {
        upFlow = in.readLong();
        downFlow = in.readLong();
        sumFlow = in.readLong();

    }
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * 现在有一个文件 phone_data.txt,文件中记录着手机号消耗的流量信息
 * 文件中每一行数据代表一条手机的流量消耗,每一条数据是以\t制表符分割的多个字段组成的
 * 使用MR程序统计每一个手机号消耗的总的上行流量、总的下行流量、总流量
 */
public class FlowDriver {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://192.168.31.104:9000");

        Job job = Job.getInstance(configuration);

        //设置MR程序默认使用的InputFormat类 —— 负责进行切片  负责读取数据源的数据为key value类型的
//        job.setInputFormatClass(FileInputFormat.class);//默认确实是FileInputFormat   但是是个 抽象类  MR程序默认使用的是这个抽象类的子类
        FileInputFormat.setInputPaths(job,"/phone_data.txt");

        //封装Mapper阶段
        job.setMapperClass(FlowMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(FlowBean.class);

        //封装Reducer阶段
        job.setReducerClass(FlowReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(FlowBean.class);

        //封装输出结果路径
//        job.setOutputFormatClass(FileOutputFormat.class);
        //MR程序要求输出路径不能提前存在 如果提前存在就会报错
        Path path = new Path("/output");
        //是用来解决输出目录如果存在MR程序报错问题的
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.31.104:9000"), configuration, "root");
        if (fileSystem.exists(path)){
            fileSystem.delete(path,true);
        }
        FileOutputFormat.setOutputPath(job,path);

        //最后提交程序运行即可
        boolean b = job.waitForCompletion(true);
        System.out.println(b?0:1);
    }
}
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/**
 * 读取切片数据,一行数据读取一次  而且读取的key(偏移量) value LongWritable Text
 * 输出的key(手机号) value 是 Text FlowBean
 */
public class FlowMapper extends Mapper<LongWritable, Text, Text, FlowBean> {
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, FlowBean>.Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] array = line.split("\t");
        String phoneNumber = array[1];
        Long downFlow = Long.parseLong(array[array.length - 2]);
        Long upFlow = Long.parseLong(array[array.length - 3]);
        FlowBean flowBean = new FlowBean(upFlow,downFlow,upFlow + downFlow);
        //需要将这一条数据以手机号为key,以flowBean为value输出给reduce
        context.write(new Text(phoneNumber),flowBean);
    }
}
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/**
 *
 */
public class FlowReducer extends Reducer<Text, FlowBean, Text, FlowBean> {
    @Override
    protected void reduce(Text key, Iterable<FlowBean> values, Reducer<Text, FlowBean, Text, FlowBean>.Context context) throws IOException, InterruptedException {
        Long upFlowSum = 0L;
        Long downFlowSum = 0L;
        Long sumFlowSum = 0L;
        for (FlowBean value : values) {
            upFlowSum += value.getUpFlow();
            downFlowSum += value.getDownFlow();
            sumFlowSum =+ value.getSumFlow();
            //需要以手机号为key,以flowBean为value将结果输出,flowBean需要将我们计算出来总流量信息封装起来
            FlowBean flowBean = new FlowBean(upFlowSum,downFlowSum,sumFlowSum);
            context.write(key,flowBean);
        }
    }
}

image-20230723154212141

image-20230723154240240

image-20230723154254681

image-20230723154313960

package com.kang.flow02;

import com.kang.flow.FlowDriver;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * 基于以前统计的手机消耗流量信息的结果文件,要求对结果文件进行二次分析,得到以下结果:
 * 1、要求对数据中的手机号按照归属地不同进行分区:
 *       134开头的手机号  0号分区
 *       135开头的手机号  1号分区
 *       136开头的手机号  2号分区
 *       137开头的手机号  3号分区
 *       其余的手机号     4号分区
 * 2、同时还要求每一个分区按照消耗的总流量从高到底进行排序
 */
public class FlowDriver02 {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException {
        Configuration configuration = new Configuration();

        Job job = Job.getInstance(configuration);

        job.setJarByClass(FlowDriver02.class);

        job.setInputFormatClass(TextInputFormat.class);
        FileInputFormat.setInputPaths(job,new Path("/output/part-r-00000"));

        job.setMapperClass(FlowMapper02.class);
        job.setMapOutputKeyClass(FlowBean02.class);
        job.setMapOutputValueClass(NullWritable.class);

        job.setPartitionerClass(FlowPartitioner.class);

        job.setReducerClass(FlowReducer02.class);
        job.setOutputKeyClass(FlowBean02.class);
        job.setOutputValueClass(NullWritable.class);
        job.setNumReduceTasks(5);

        Path path =new Path("/output1");
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.31.104:9000"), configuration, "root");
        if (fs.exists(path)){
            fs.delete(path);
        }
        FileOutputFormat.setOutputPath(job,path);

        boolean flag = job.waitForCompletion(true);
        System.exit(flag?0:1);
    }
}

class FlowMapper02 extends Mapper<LongWritable, Text,FlowBean02,NullWritable> {
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, FlowBean02, NullWritable>.Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] message = line.split("\t");
        String phoneNumber = message[0];
        Long upFlow = Long.parseLong(message[1]);
        Long downFlow = Long.parseLong(message[2]);
        Long sumFlow = Long.parseLong(message[3]);
        FlowBean02 flowBean02 = new FlowBean02(phoneNumber,upFlow,downFlow,sumFlow);
        context.write(flowBean02,NullWritable.get());
    }
}

oneNumber.startsWith("137")) {
            return 3;
        }else  {
            return 4;
        }
//        String message = flowBean02.toString();
//        String[] array = message.split("\t");
//        String phoneNumber = array[0];
//        char w1 = phoneNumber.charAt(0);
//        char w2 = phoneNumber.charAt(1);
//        char w3 = phoneNumber.charAt(2);
//        if (w1 == '1' && w2 == '3') {
//            if (w3 == '4') return 0;
//            if (w3 == '5') return 1;
//            if (w3 == '6') return 2;
//            if (w3 == '7') return 3;
//        }
//        return 4;
    }
}

class FlowReducer02 extends Reducer<FlowBean02,NullWritable,FlowBean02, NullWritable>{
    @Override
    protected void reduce(FlowBean02 key, Iterable<NullWritable> values, Reducer<FlowBean02, NullWritable, FlowBean02, NullWritable>.Context context) throws IOException, InterruptedException {
        context.write(key,NullWritable.get());
    }
}

package com.kang.flow02;

import org.apache.hadoop.io.WritableComparable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Objects;

public class FlowBean02 implements WritableComparable<FlowBean02> {
    private String phoneNumber;
    private Long upFlow;
    private Long downFlow;
    private Long sumFlow;

    public FlowBean02() {
    }

    public FlowBean02(String phoneNumber, Long upFlow, Long downFlow, Long sumFlow) {
        this.phoneNumber = phoneNumber;
        this.upFlow = upFlow;
        this.downFlow = downFlow;
        this.sumFlow = sumFlow;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public Long getUpFlow() {
        return upFlow;
    }

    public void setUpFlow(Long upFlow) {
        this.upFlow = upFlow;
    }

    public Long getDownFlow() {
        return downFlow;
    }

    public void setDownFlow(Long downFlow) {
        this.downFlow = downFlow;
    }

    public Long getSumFlow() {
        return sumFlow;
    }

    public void setSumFlow(Long sumFlow) {
        this.sumFlow = sumFlow;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FlowBean02 that = (FlowBean02) o;
        return Objects.equals(phoneNumber, that.phoneNumber) && Objects.equals(upFlow, that.upFlow) && Objects.equals(downFlow, that.downFlow) && Objects.equals(sumFlow, that.sumFlow);
    }

    @Override
    public int hashCode() {
        return Objects.hash(phoneNumber, upFlow, downFlow, sumFlow);
    }

    @Override
    public String toString() {
        return phoneNumber + "\t" + upFlow + "\t" + downFlow + "\t" + sumFlow;
    }

    @Override
    public int compareTo(FlowBean02 o) {
        if (this.sumFlow > o.sumFlow){
            return 1;
        } else if (this.sumFlow < o.sumFlow) {
            return -1;
        }else {
            return 0;
        }
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeUTF(phoneNumber);
        out.writeLong(upFlow);
        out.writeLong(downFlow);
        out.writeLong(sumFlow);

    }

    @Override
    public void readFields(DataInput in) throws IOException {
        phoneNumber = in.readUTF();
        upFlow = in.readLong();
        downFlow = in.readLong();
        sumFlow = in.readLong();

    }
}

image-20230726214325943

image-20230726214343317

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/981142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8s(Kubernetes)学习(四):Controller 控制器:Deployment、StatefulSet、Daemonset、Job

什么是 Controller 以及作用常见的 Controller 控制器Controller 如何管理 PodDeployment 基本操作与应用通过控制器实现 Pod 升级回滚和弹性伸缩StatefulSet 基本操作与应用Daemonset 基本操作与应用Job 基本操作与应用Controller 无法解决问题 1 Controller 控制器 官网: h…

C语言类型占内存大小

C语言类型占内存大小 C语言数据类型sizeof测试基本数据类型所占字符大小运行结果数据模型 C语言数据类型 sizeof测试基本数据类型所占字符大小 #include <stdio.h>int main() {char a;short b;int c;long d;float e;double f;printf("char %d\n", sizeof (a…

Ubuntu18中NVIDIA,cuda,cudnn,pytorch安装

注意&#xff1a;nvidia驱动和cuda,cudnn,pytroch,python的对应关系 linux安装pytorch&#xff08;包括cuda与cudnn&#xff09;_linux清华园按照pytorch1.12_BryceRui的博客-CSDN博客 安装流程&#xff1a;安装cuda&#xff08;包括nvidia驱动&#xff09; cudnn python安装…

Excel VSTO开发7 -可视化界面开发

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 7 可视化界面开发 前面的代码都是基于插件启动或者退出时&#xff0c;以及Excel Application的相关事件&#xff0c;在用户实际操作…

java八股文面试[数据库]——写失效(双写缓冲区)

InnoDB的页和操作系统的页大小不一致&#xff0c;InnoDB页大小一般为16K&#xff0c;操作系统页大小为4K&#xff0c;InnoDB的页写入到磁盘时&#xff0c;一个页需要分4次写。 如果存储引擎正在写入页的数据到磁盘时发生了宕机&#xff0c;可能出现页只写了一部分的情况&#…

移植STM32官方加密库STM32Cryptographic

感谢这位博主&#xff0c;文章具有很高的参考价值&#xff1a; STM32F1做RSA&#xff0c;AES数据加解密&#xff0c;MD5信息摘要处理_我以为我爱了的博客-CSDN博客 概述 ST官方在很多年前就推出了自己的加密库&#xff0c;配合ST芯片用起来非常方便&#xff0c;支持ST的所有…

Pixillion Pro for Mac:将您的图像转换为艺术佳作

Pixillion for Mac有着非常强大的图像转换功能和简单的使用方法&#xff0c;帮助你快速完成大批量图像转换的工作&#xff0c;支持一键转换jpeg、jpg、bmp、png、gif、raf、heic等各种格式的图像文件&#xff0c;同时pixillion mac激活版还提供了图像旋转、添加水印、调整图像大…

多年没有这么花时间解决一个问题了

Ruby 和 PgSQL 并不是我非常熟悉的领域。 多年没有花这么多的时间解决一个问题了&#xff0c;从数据的 Dump 到数据导入&#xff0c;到容器的 SQL 执行。 当你想放弃的时候&#xff0c;发现你有的是一种热爱&#xff0c;喜欢体验到问题被解决的感觉&#xff0c;人还是有需要有…

[管理与领导-74]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 构建自己的个人品牌

前言&#xff1a; 一、什么是信任账户 在职场中受到信任是建立良好声誉和专业形象的基础。以下是一些可以帮助职场人受到信任的方法&#xff1a; 诚实守信&#xff1a;始终保持诚实和可靠的行为。遵守诺言&#xff0c;履行承诺&#xff0c;不轻易背信弃义。 专业素养&#xf…

Excel VSTO开发10 -自定义任务面板

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 10 自定义任务面板 自定义任务面板&#xff08;有些地方称为侧边面板&#xff09;即CustomTaskPane&#xff0c;这个类在Microsoft…

GitHubGiteeGitlab极狐(JihuLab)配置SSH公私钥详细过程

GitHub-微软-github.com Gitee-开源中国- gitee.com Gitlab-乌克兰GitLab 公司-gitlab.com 极狐(JihuLab)-中国代理商运营的Gitlab -gitlab.cn或者jihulab.com 一、生成SSH公钥和私钥 1.1 取消全局设置 $ git config --global user.name "你的名字" $ git confi…

【技术】视频汇聚/视频云存储/视频监控管理平台EasyCVR安全检查相关问题及解决方法2.0

开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多…

简明SQL条件查询指南:掌握WHERE实现数据筛选

条件查询是用于从数据库中根据特定条件筛选数据行的一种方式&#xff0c;它避免了检索整个表中的数据。通常&#xff0c;使用 WHERE 子句来定义过滤条件&#xff0c;只有符合这些条件的数据行才会被返回。 SQL中的运算符有&#xff1a;、!、<、> 等&#xff0c;用于进行…

Python数据分析实战-使用装饰器为函数增加异常处理功能(附源码和实现效果)

实现功能 使用装饰器增加异常处理功能 实现代码 # 假设我有一个函数&#xff08;原函数&#xff09;&#xff0c;可以实现两个数相除 def divide(x, y):return x / yres divide(10, 2) print(res)# 定义一个装饰器&#xff0c;使得原函数能够有处理异常的功能 def handle_e…

【算法】快速排序 详解

快速排序 详解 快速排序1. 挖坑法2. 左右指针法 &#xff08;Hoare 法&#xff09;3. 前后指针法4. 快排非递归 代码优化 排序&#xff1a; 排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&…

链接服务器导致SQL Server停止响应

概要 如果多个实例中同时存在数据源为对方实例的链接服务器&#xff0c;并且开启了“分发服务器”的属性&#xff0c;您可能会遇到这种情况。 现象 14:31时&#xff0c;在SSMS中检查HIS实例是否有复制订阅时&#xff0c;点击了”发布服务器属性“后&#xff0c;SSMS一直无法响…

(二十四)大数据实战——Flume数据流监控之Ganglia的安装与部署

前言 本节内容我们主要介绍一下Flume数据流的监控工具Ganglia。Ganglia是一个开源的分布式系统性能监控工具。它被设计用于监视大规模的计算机群集&#xff08;包括集群、网格和云环境&#xff09;&#xff0c;以便收集和展示系统和应用程序的性能数据。Ganglia 可以轻松地扩展…

Tugraph图学习技术详解

文章目录 TuGraph图学习目录图学习典型工作流程整体学习架构加速稀疏计算GPC编译加速 编译加速编译加速流水线GPCSPMM和SDDMM优化SPMM DSL代码生成SDMM DSL代码生成AutoTune-Cost Model 加速效果一键加速 TuGraph图学习实践目录TuGraph采样TuGraph采样算子全图训练采样算子介绍…

启动hadoop并测试问题合集

首先hadoop和jdk都已经装好了的&#xff0c;如下&#xff1a; 然后相应的这五个配置文件也配好了&#xff1a; 然后格式化了&#xff1a; cd /opt/hadoop/bin/ sudo ./hdfs namenode -format &#xff08;显示这个就为成功&#xff0c;很长的&#xff0c;慢慢找&#xff09; …

[当人工智能遇上安全] 8.基于API序列和机器学习的恶意家族分类实例详解

您或许知道&#xff0c;作者后续分享网络安全的文章会越来越少。但如果您想学习人工智能和安全结合的应用&#xff0c;您就有福利了&#xff0c;作者将重新打造一个《当人工智能遇上安全》系列博客&#xff0c;详细介绍人工智能与安全相关的论文、实践&#xff0c;并分享各种案…