mapreduce的原理和简单程序实现

2023-05-16

五个关于mapreduce的简单程序实现

mapreduce的简介

什么是mapreduce?
是一种分布式运算程序
一个mapreduce程序会分成两个阶段,map阶段和reduce阶段
map阶段会有一个实体程序,不用用户自己开发
reduce阶段也会有一个实体程序,不用用户自己开发
用户只需要开发map程序和reduce程序所要调用的数据处理逻辑方法
Map阶段的逻辑方法:xxxMapper.map()
Reduce阶段的逻辑方法:xxxReducer.reduce()

map阶段

框架中的map程序如何调用用户写的map()方法的?
map程序每读取一行数据,就调用一次map()方法,而且会将这一行数据的起始偏移量作为key,这一行的内容作为value,作为参数传给map(key,value,context)方法

reduce阶段

框架中的reduce程序如何调用用户写的reduce()方法的?
reduce程序会收到来自map程序输出的中间结果数据,而且相同key的数据会到达同一个reduce程序实例,比如reduce程序实例0可能会收到这样的一些数据。
A:1 A:1 A:1 C:1 C:1 C:1 X:1 X:1 X:1
reduce程序会将自己收到的程序按照key整理成一组一组,对一组数据调用一次reduce()方法来处理一次,并且会将数据作为参数传给reduce(key,迭代器values,context)方法。

mapreduce的运行机制

mapreduce程序如何运行?
mapreduce程序可以作为单机版程序在本地运行
mapreduce程序更应该作为分布式程序提交给yarn去运行
写一个yarn的客户端类(含main方法)
指定job的jar包所在的路径
指定job所要的mapper类reducer类以及map、reduce阶段输出到key、value的数据类型
指定job要处理的数据所在目录
指定job输出结果所在目录
然后用一个方法:waitForCompletion()向yarn的resourcemanager提交job即可

启动命令

启动客户端类:
用java-cp可以启动,但是需要手动设置大量的jar包和配置文件到classpath,不建议。

建议用hadoop jar pv.jar命令来启动,hadoop命令会自动设置好classpath(将hadoop安装目录中的所有jar包和配置文件加入到classpath中)

准备环境

mr程序运行环境准备----yarn集群配置和启动。
在/usr/hadoop/hadoop-2.7.7/etc/hadoop目录下的yarn-site.xml配置文件中。配置如下:

<configuration>
	<property>
		<name>yarn.resourcemanager.hostname</name>
		<value>hadoop01</value>
	</property>
	<property>
		<name>yarn.nodemanager.aux-services </name>
		<value>mapreduce_shuffle</value>
	</property> 
</configuration>

yarn在启动的时候,也会看slaves中配置的机器,这些机器会作为yarn的nodemanager。
这样的话,nodemanager和datanode正好是相同的机器。
mv mapred-site.xml.template mapred-site.xml
vi mapred-site.xml

<configuration>
	<property>
		<name>mapreduce.framework.name</name>
		<value>yarn</value>
	</property>
</configuration>

mapreduce框架的程序可以以单机模式运行(本地模式),我们要让它分布式运行,就交给yarn,以分布式运行。

scp yarn-site.xml mapred-site.xml hadoop02:$PWD
……

启动yarn集群,start-yarn.sh
jps查看

yarn的启动与hdfs的启动无关,但是mapreduce程序肯定要访问hdfs中的数据,所以开启yarn后再开启hdfs。start-dfs.sh

第一个程序

统计用户的访问量

Map端:
Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
KEYIN是mr框架提供的程序读取到一行数据的起始偏移量
VALUEIN是mr框架提供的程序读取到一行数据的内容

KEYOUT是用户的逻辑处理方法处理完之后返回给框架的数据中的KEY的类型
VALUEOUT是用户的逻辑处理方法处理完之后返回给框架的数据中的VALUE的类型
Long、String、Integer一类的java类型不能再hadoop中直接使用,因为这些数据会被框架在机器和机器之间进行网络传送,也就是说,数据需要频繁的序列化和反序列化,而java原生的序列化和反序列化机制非常的臃肿,所以hadoop开发了一个自己的序列化机制。
Long—LongWritable
String—Text //导包要对,hadoop.io
Integer—IntWritable

public class PvMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
	
	/**
	 * MR框架提供的程序每读一行数据就调用一次我们写的这个map方法
	 */
	@Override
	protected void map(LongWritable key, Text value, Context context)
			throws IOException, InterruptedException {
		//拿到一行
		String line = value.toString();
		String[] split = line.split(" ");
		//切出ip地址
		String ip = split[0];
		
		//通过context返回结果
		context.write(new Text(ip), new IntWritable(1));
	}
}

Reduce端:
KEYIN和VALUEIN 对应的是map阶段输出的数据的key和value的类型
KEYOUT和VALUEOUT是用户的reduce阶段的逻辑处理结果中的key和value的类型

public class PvReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
	/**
	 * MR框架提供的reduce端在整理好一组相同key的数据后,调用reduce方法
	 */
	@Override
	protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
		 int count = 0;
		 for(IntWritable value:values){
			 count += value.get();
		 }
		 context.write(key, new IntWritable(count));
	}
}

Job端:
JobSubmitter类其实是一个yarn的客户端。功能就是:将我们的mapreduce程序jar包提交给yarn,让yarn再去将jar包分发到很多的nodemanager上去执行

public class JobSubmitter {
	public static void main(String[] args) throws Exception {
		
		//新建一个job,封装任务的信息
		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf);
		
		job.setJar("/root/pv.jar");
		
		job.setMapperClass(PvMapper.class);
		job.setReducerClass(PvReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
			
		//用一个什么样的组件去读,导包lib.input
		job.setInputFormatClass(TextInputFormat.class);
		//告诉组件去哪读
		FileInputFormat.setInputPaths(job, new Path(""));
		
		job.setOutputFormatClass(TextOutputFormat.class);
		//告诉组件结果写到哪
		FileOutputFormat.setOutputPath(job, new Path(""));
		
		//向yarn提交job,提交到nodemaneger中去执行任务
		//传true,会在客户端打印集群运行的进度信息
		boolean res = job.waitForCompletion(true);
		System.exit(res?0:1);
	}
}

第二个程序

统计单词的个数。

Map端:

public class WcMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
	@Override
	protected void map(LongWritable key, Text value, Context context)
			throws IOException, InterruptedException {
		String line = value.toString();
		String[] words = line.split(" ");
		for (String word : words) {
			context.write(new Text(word), new IntWritable(1));
		}
	}
}

Reduce端:

public class WcReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
	@Override
	protected void reduce(Text key, Iterable<IntWritable> values,
			Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
		int count = 0;
		for (IntWritable value : values) {
			count += value.get();
		}
		context.write(key, new IntWritable(count));
		
	}
}

Job端:

public class WcJobSubmitter {
	public static void main(String[] args) throws Exception {
		
		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf);
		
		job.setJar("/root/pv.jar");
		
		job.setMapperClass(WcMapper.class);
		job.setReducerClass(WcReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
			
		job.setInputFormatClass(TextInputFormat.class);
		FileInputFormat.setInputPaths(job, new Path("/wc/input"));
		
		job.setOutputFormatClass(TextOutputFormat.class);
		FileOutputFormat.setOutputPath(job, new Path("/wc/output"));
		
		boolean res = job.waitForCompletion(true);
		System.exit(res?0:1);
	}
}

1、 将工程打包成jar,上传到hadoop主机上。
2、 在hdfs上创建文件存放的目录。hadoop fs -mkdir -p /wc/input。
3、hadoop fs -put qingshu.txt /wc/input 将要统计的文件上传到hdfs指定的目录上。
4、执行job。hadoop jar pv.jar cn.jixiang.mr.wc.WcJobSubmitter
5、查看结果。hadoop fs -ls /wc/output hadoop fs -cat /wc/output/part-r-00000

补充:
//设置reduce的个数

job.setNumReduceTasks(4);

第三个程序

hadoop中的数据会频繁的实现序列化和反序列化
所以自定义的类型:FlowBean必须要实现hadoop序列化接口

Map端:

public class FlowSumMapper extends Mapper<LongWritable, Text, Text, FlowBean>{
	@Override
	protected void map(LongWritable key, Text value, Context context)
			throws IOException, InterruptedException {
		String line = value.toString();
		String[] split = line.split("\t");
		String phone = split[1].trim();
		long upflow = Long.parseLong(split[split.length-3]);
		long downflow = Long.parseLong(split[split.length-2]);
		
		FlowBean flowBean = new FlowBean(upflow, downflow);
		context.write(new Text(phone), flowBean);
	}
}

Reduce端:

public class FlowSumReducer 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 = 0;
		long downfolwSum = 0;
		for (FlowBean flowBean : values) {
			upflowSum += flowBean.getUpflow();
			downfolwSum += flowBean.getDownflow();
		}
		context.write(key, new FlowBean(upflowSum,downfolwSum));
	}
}

Bean端:

public class FlowBean implements Writable{
	private long upflow;
	private long downflow;
	private long sumflow;
	
	//注意显示定义一个空参构造函数
	public FlowBean() {
		super();
	}
	public FlowBean(long upflow, long downflow) {
		super();
		this.upflow = upflow;
		this.downflow = downflow;
		this.sumflow = upflow+downflow;
	}
	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;
	}
	/**
	 * hadoop序列化框架在 反序列化时调用的方法
	 * @throws IOException 
	 */
	public void readFields(DataInput in) throws IOException {
		this.upflow = in.readLong();
		this.downflow = in.readLong();
		this.sumflow = in.readLong();
	}	
	/**
	 * hadoop序列化框架在序列化时调用的方法
	 * @throws IOException 
	 */
	public void write(DataOutput out) throws IOException {
		out.writeLong(upflow);
		out.writeLong(downflow);
		out.writeLong(sumflow);
	}

	@Override
	public String toString() {
		return upflow+"\t"+downflow+"\t"+sumflow;
	}
}

Job端:

public class FlowSumJobSubmit {
	public static void main(String[] args) throws Exception {
		//新建一个job,封装任务的信息
		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf);
		
		//job.setJar("/root/pv.jar");
		job.setJarByClass(FlowSumJobSubmit.class);
		
		job.setMapperClass(FlowSumMapper.class);
		job.setReducerClass(FlowSumReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
			
		//用一个什么样的组件去读,导包lib.input
		job.setInputFormatClass(TextInputFormat.class);
		//告诉组件去哪读
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		
		job.setOutputFormatClass(TextOutputFormat.class);
		//告诉组件结果写到哪
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		//向yarn提交job,提交到nodemaneger中去执行任务
		//传true,会在客户端打印集群运行的进度信息
		boolean res = job.waitForCompletion(true);
		System.exit(res?0:1);
	}
}

第四个程序

(在第三个程序的基础上改进,实现分省流量统计)
将相同省的数据放到同一个reduce中。之前分数据的方法是key的hashcode%reducetasknum,所以改变它的规则。

public class ProvincePartitioner extends Partitioner<Text, FlowBean>{

	private static HashMap<String,Integer> provinceCode = new HashMap<>();
	static{
		provinceCode.put("135", 0);
		provinceCode.put("136", 1);
		provinceCode.put("137", 2);
		provinceCode.put("138", 3);
	}
	
	@Override
	public int getPartition(Text key, FlowBean value, int numPartitions) {
		Integer code = provinceCode.get(key.toString().substring(0,3));
		return code==null?4:code;
	}
}

重写job方法

public class JobSubmitter {
	public static void main(String[] args) throws Exception {
		
		//新建一个job,封装任务的信息
		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf);
		
		job.setJar("/root/pv.jar");
		
		job.setMapperClass(PvMapper.class);
		job.setReducerClass(PvReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
			
		//用一个什么样的组件去读,导包lib.input
		job.setInputFormatClass(TextInputFormat.class);
		//告诉组件去哪读
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		
		job.setOutputFormatClass(TextOutputFormat.class);
		//告诉组件结果写到哪
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		job.setPartitionerClass(ProvincePartitioner.class);
		job.setNumReduceTasks(Integer.parseInt(args[2]));
		
		//向yarn提交job,提交到nodemaneger中去执行任务
		//传true,会在客户端打印集群运行的进度信息
		boolean res = job.waitForCompletion(true);
		System.exit(res?0:1);
	}
}

第五个程序

(统计每个单词,对应的文件和个数)
先以:单词-文件名作为key,以单词的次数作为value
再以:单词作为key,以文件名-次数作为value
步骤一:

public class IndexStepOne {
	public static class IndexStepOneMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
		String fileName;
		/**
		 * 一个map程序运行实例在调用我们的自定义mapper逻辑类时,首先会调用一次setup方法,只会调用一次
		 */
		@Override
		protected void setup(Context context)
				throws IOException, InterruptedException {
			//想生成:     key:单词-文件名      value:1
			FileSplit inputSplit = (FileSplit) context.getInputSplit();
			fileName = inputSplit.getPath().getName();
			
		}		
		@Override
		protected void map(LongWritable key, Text value,Context context)
				throws IOException, InterruptedException {
			String line = value.toString();
			String[] words = line.split(" ");
			for (String word : words) {
				context.write(new Text(word+"-"+fileName), new IntWritable(1));
			}			
		}
		
		/**
		 * 当一个map程序实例在处理完自己负责的整个切片数据后,会调用一次cleanup方法。
		 */
		@Override
		protected void cleanup(Mapper<LongWritable, Text, Text, IntWritable>.Context context)
				throws IOException, InterruptedException {
			
		}
	}
	
	public static class IndexStepOneReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
		@Override
		protected void reduce(Text key, Iterable<IntWritable> values,
				Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
			int count = 0;
			for (IntWritable value : values) {
				count += value.get();
			}
			context.write(key, new IntWritable(count));
		}
	}
	
	public static void main(String[] args) throws Exception {

		
		//新建一个job,封装任务的信息
		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf);
		
		job.setJarByClass(IndexStepOne.class);
		
		job.setMapperClass(IndexStepOneMapper.class);
		job.setReducerClass(IndexStepOneReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
			
		//用一个什么样的组件去读,导包lib.input
		job.setInputFormatClass(TextInputFormat.class);
		//告诉组件去哪读
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		
		job.setOutputFormatClass(TextOutputFormat.class);
		//告诉组件结果写到哪
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		//重置它的分区方式
		//job.setPartitionerClass(ProvincePartitioner.class);
		job.setNumReduceTasks(Integer.parseInt(args[2]));
		
		//向yarn提交job,提交到nodemaneger中去执行任务
		//传true,会在客户端打印集群运行的进度信息
		boolean res = job.waitForCompletion(true);
		System.exit(res?0:1);
	
	}
}

步骤二:

public class IndexStepSecond {
	public static class IndexStepSecondMapper extends Mapper<LongWritable, Text, Text, Text>{
		@Override
		protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context)
				throws IOException, InterruptedException {
			
			String line = value.toString();
			String[] split = line.split("-");
			String word = split[0];
			String[] temp = split[1].split("\t");
			String fileName = temp[0];
			String count = temp[1];
			context.write(new Text(word), new Text(fileName+"-->"+count));
		}
	}
	
	public static class IndexStepSecondReducer extends Reducer<Text, Text, Text, Text>{
		@Override
		protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, Text>.Context context)
				throws IOException, InterruptedException {
			StringBuilder sb = new StringBuilder();
			for (Text value : values) {
				sb.append(value.toString()).append(" ");
			}
			context.write(key, new Text(sb.toString()));
		}
	}
	
	public static void main(String[] args) throws Exception {

		//新建一个job,封装任务的信息
		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf);
		
		job.setJarByClass(IndexStepSecond.class);
		
		job.setMapperClass(IndexStepSecondMapper.class);
		job.setReducerClass(IndexStepSecondReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(Text.class);
		
		//如果map阶段输出的kv类型和reduce阶段输出的kv类型完全一致,上面两行可以不写
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
			
		//用一个什么样的组件去读,导包lib.input
		//job.setInputFormatClass(TextInputFormat.class);
		//告诉组件去哪读
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		
		//job.setOutputFormatClass(TextOutputFormat.class);
		//告诉组件结果写到哪
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		//重置它的分区方式
		//job.setPartitionerClass(ProvincePartitioner.class);
		job.setNumReduceTasks(Integer.parseInt(args[2]));
		
		//向yarn提交job,提交到nodemaneger中去执行任务
		//传true,会在客户端打印集群运行的进度信息
		boolean res = job.waitForCompletion(true);
		System.exit(res?0:1);

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

mapreduce的原理和简单程序实现 的相关文章

  • java获取登陆用户ip方法

    今天和大家分享一下获取登录用户 ip的方法 xff0c 如果你想获取自己的登陆用户 ip xff0c 可以参考以下思路 xff1a 1 可以通过 Java动态链接库的方式获取到 xff0c 方法很简单 xff0c 就是把需要的 ip地址添加
  • npm install 超时/卡住

    第一次使用npm发现什么东西也下不了 xff0c 各种超时 xff0c 更换镜像源 xff0c 删除缓存等方法都无效 xff0c 最后看到一个方法 xff0c 清除了一下代理 xff08 虽然我没有设置过 xff09 xff0c 然后将镜像
  • Docker的网络模式bridge、host、container other、overlay

    docker run创建Docker容器时 xff0c 可以用 net选项指定容器的网络模式 xff0c Docker有以下5种网络模式 xff1a bridge模式 xff1a 使用 net 61 bridge指定 xff0c 默认设置
  • pyqt5 嵌于主界面状态栏的进度条

    写在前面 放在状态栏处的进度条 本想放在主界面 xff0c 但是没找到相关代码 代码 span class token comment coding utf 8 span span class token keyword from span
  • 分布式文件系统-HDFS

    主要内容 xff1a HDFS是什么 xff1f HDFS优点HDFS架构副本机制 1 HDFS是什么 xff1f 是由Hadoop实现的一个分布式的文件系统 xff08 Hadoop Distributed File System xff
  • 让我们来做一个属于自己的浏览器主页吧!

    对于我们程序员来说每天最常用的就是浏览器 因为像google 百度 火狐 必应这些浏览器的主页不太美观壁纸也很少 xff0c 所以我做了一个浏览器主页 xff0c 目前做的功能比较少后续会慢慢完善 xff0c 先给大家展示一下 废话少说我们
  • 卷积的过程

    span class token comment usr bin env python span span class token comment coding utf 8 span span class token comment aut
  • 使用Realsense D435i运行VINS-Fusion并建图

    1 安装VINS 到github xff1a VINS xff0c 按照说明安装依赖和编译vins ceres别装2 0版本 xff0c 装1 4 开始装的2 0遇到错误error integer sequence is not a mem
  • 使用AT命令获取本机号码

    我之前认为手机号码与SIM卡是一一对应的 xff0c 后来想想不对 xff0c 因为有换卡不换号的情况啊 xff0c 所以SIM卡应该只是一个电话号码的储存介质 xff0c 而与SIM卡一一对应的是另一个编码 IMSI xff08 国际移动
  • linux系统中的临时文件

    1 什么是临时文件 下载和安装 39 卸载软件 打开电子邮件和即时消息程序中的文件或传输文件时创建 通常 xff0c 创建临时文件的程序会在完成时将其删除 xff0c 但有时候这些文件会被保留 一段时间后 xff0c 这些废弃的临时文件 x
  • linux中的网络配置之网关

    1 网关 网关 Gateway 又称网间连接器 协议转换器 网关在网络层以上实现网络互连 xff0c 是复杂的网络互连设备 xff0c 仅用于两个高层协议不同的网络互连 网关既可以用于广域网互连 xff0c 也可以用于局域网互连 网关是一种
  • python网络爬虫(爬取bilibili一位up的视频标题,评论数量等基本信息)

    对爬虫还挺有兴趣的 xff0c 但是一直没有尝试过 xff0c 今天看了几篇写得非常好的博客 xff0c 学到了一丢丢 xff0c 自己也写了个简单的爬虫娱乐娱乐 1 分析需求 需求 xff1a 爬取b站up主王老菊所有视频投稿的编号 xf
  • Python面向对象结合第三方库pygame的练习----贪吃蛇小游戏

    今天看到几个关于pygame模块的博客和视频 xff0c 感觉非常有趣 xff0c 这里照猫画虎写了一个贪吃蛇小游戏 xff0c 目前还有待完善 xff0c 但是基本游戏功能已经实现 xff0c 下面是代码 xff1a 导入模块 impor
  • Python实现爬取全国疫情数据和地区疫情查询

    一个小小的爬虫程序 xff0c 练练手 xff0c 没什么实际作用 xff0c 希望疫情赶快过去 1 获取url 以腾讯的疫情动态作为来源 xff0c 寻找包含疫情数据的url xff1a 经过寻找 xff0c 发现包含疫情数据的url为
  • 部署LNMP并利用LNMP搭建wordpress论坛

    1 LNMP是什么 xff1f LNMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写 L指Linux xff0c N指Nginx xff0c M一般指MySQL xff0c 也可以指MariaDB xff0c P一般
  • Redis(一)redis实现主从复制以及sentinel模式部署

    1 什么是redis redis是一个key value存储系统 和Memcached类似 xff0c 它支持存储的value类型相对更多 xff0c 包括string 字符串 list 链表 set 集合 zset sorted set
  • Redis(二)搭建redis集群

    1 为什么需要redis集群 xff1f 单个redis存在不稳定性 当redis服务宕机了 xff0c 就没有可用的服务了 单个redis的读写能力是有限的 2 redis集群概述 redis集群中 xff0c 每一个redis称之为一个
  • 部署Harbor私有镜像仓库

    1 什么是Harbor Harbor的中文意思是港湾 xff0c 在这里它指的是一个用于存储Docker 镜像的企业级Resitry服务 xff0c 它是由VMware公司开源的Docker Registry管理项目 xff0c 包括权限管
  • sumo入门-保姆级教程

    SUMO学习 入门篇 1 安装SUMO 在sumo官网 xff08 https sumo dlr de docs Downloads php xff09 安装即可 xff0c 为省略不必要的困扰 xff0c 推荐安装在C盘 xff0c xf
  • CAS 服务端的搭建

    上文讲了CAS客户端 xff0c 本文记录CAS Server的搭建步骤 CAS Server的版本一定要选好 xff0c 我选的是CAS5 3 xff0c Java版本用的8 xff0c 目前最新的CAS6 5的Java版本最低是11了

随机推荐

  • SUMO 换道设置,靠右行驶

    vType中设置换道参数 xff0c 解决仿真中车辆一直靠右行驶和无脑逮着一个进口道走等情况 lt vType id 61 34 type1 34 accel 61 34 0 8 34 decel 61 34 4 5 34 sigma 61
  • SUMO 设置速度后正常行驶

    先附上traci vehicle setSpeed vehID speed 的使用说明 xff1a setSpeed self vehID speed 在最后一步中为命名车辆设置速度 xff08 以 m s 为单位 xff09 以 spee
  • 【NS3】SUMO安装 (Linux+Windows)

    SUMO安装 xff08 Linux 43 Windows xff09 文章目录 SUMO安装 xff08 Linux 43 Windows xff09 Windows安装OSMWebWizard 与NS3选项设置车辆与需求设置文件生成 L
  • STM32 STlink安装以及安装失败解决方法

    STM32 STlink安装以及安装失败解决方法 1 STM32 STlink下载连接 xff08 可能需要科学上网 xff09 http www bkill com download 185935 html text 61 ST LINK
  • 嵌入式学习之linux系统编程---7 目录IO之mkdir函数

    1 目录IO与文件IO的区别 目录IO文件IOopendir 打开目录open 打开文件mkdir 创建目录 readndir 读目录read 读文件closedir 关闭目录close 关闭文件 区别 xff1a 在之前的博客中提到的文件
  • Ubuntu查看系统内存,硬盘使用情况,指定目录使用情况,GPU。

    内存和硬盘的区别 1 内存是半导体材料制成的 xff0c 硬盘是磁性材料制成的 2 内存中的信息停电会消失 xff0c 硬盘中的信息可以长久保存 3 执行程序首先放入到内存之中 xff0c 然后放入的CPU中处理 主存如内存 xff0c 辅
  • MQ-2烟雾传感器解析

    一 工作原理 可用于家庭和工厂的气体泄漏监测装置 xff0c 适宜于液化气 苯 烷 酒精 氢气 烟雾等的探测 故因此 xff0c MQ 2可以准确来说是一个多种气体探测器 MQ 2的探测范围极其的广泛 它的优点 xff1a 灵敏度高 响应快
  • 软件设计的启发规则---层次图,HIPO图和结构图----画数据流图

    1 软件设计的启发规则有那些 xff1f 答 xff1a 1 改进软件结构提高模块独立性 2 模块规模应该适中 3 深度 宽度 扇出和扇入都应适当 4 模块的作用域应该在控制域之内 5 力争降低模块接口的复杂程度 6 设计单入口单出口的模块
  • 在Linux中安装docker全过程

    目前 xff0c CentOS 仅发行版本中的内核支持 Docker Docker 运行在CentOS 7 64 bit 上 xff0c 要求系统为64位 Linux系统内核版本为 3 8以上 xff0c 这里选用Centos8 x 查看自
  • vue&vant移动端h5底部留白问题

    不知道是 xff0c vue的原因还是vant的原因 xff0c html底部多了一截 每个页面背景不一样也不能给统一的background xff0c 给内容div负margin都盖不住这个html的空白 最后试了很多方法 xff0c 曲
  • Feature Squeezing: Detecting Adversarial Examples in Deep Neural Networks笔记

    Code https github com mzweilin EvadeML Zoo Feature squeezing reducing the color bit depth of each pixel and spatial smoo
  • E: 仓库 “http://ppa.launchpad.net/zarquon42/meshlab/ubuntu bionic Release”没有 Release 文件

    参考 xff1a 添加链接描述 在etc apt sources list d 目录中删除对应的ppa cd span class token operator span etc span class token operator span
  • 移远EC20--1 AT命令初始3

    接上篇 一 xff1a AT指令电话簿命令 AT 43 CNUM xff1a 用户编号 该命令可以从 xff08 U xff09 SIM中获取用户自己的编号 AT 43 CPBF xff1a 查找电话簿条目 该命令可以从用AT 43 CPB
  • ROS学习笔记(一)之 成功安装(melodic版)

    Ubuntu18 04安装ROS Melodic 详情请参考 xff1a https blog csdn net haiyinshushe article details 84256137 1 配置Ubuntu软件库 xff1a 配置Ubu
  • oracle数据库新增用户

    文章目录 前言一 通过PL SQL客户端新增二 通过创建命令进行新增1 创建语句 总结 前言 用的比较少 xff0c 用到时记录一下 一 通过PL SQL客户端新增 1 连接成功后 xff0c 在左侧对象 users右键 新建 xff0c
  • 长度单位&颜色RGB值&十六进制颜色RGB值

    长度单位 amp 颜色RGB值 amp 十六进制颜色RGB值 span class token doctype lt DOCTYPE html gt span span class token tag span class token ta
  • stm32学习之定时器中断时间设置与计算

    嗯 在stm32中经常使用定时器 xff0c 但是一直没有学会怎样计算定时器的时间 xff0c 近期简单学习了一下做一下总结记录 首先我们会在主函数里边定义时钟的最高频率为72Mhz 使用SysTick Init 72 定义 如下方代码所示
  • keil 下载安装 保姆级教程

    一 前言 最近被安排开发一个单片机的项目 xff0c 回头想了一下 xff0c 自己上次弄单片机的时候 xff0c 还都是在大学期间 xff0c 到现在也有三四年没有碰过了 xff0c 大部分的知识点都忘了 xff0c 所以又重新的把以前的
  • ST-Link使用教程

    1 电脑安装软件 2 点击确定 3 下一步 4 下一步 5 下一步 6 下一步 7 下一步 8 等待安装完成 9 等待 10 完成安装 11 打开 ST Visual Programmer 12 选择芯片 13 选择芯片类型 xff08 S
  • mapreduce的原理和简单程序实现

    五个关于mapreduce的简单程序实现 mapreduce的简介 什么是mapreduce xff1f 是一种分布式运算程序 一个mapreduce程序会分成两个阶段 xff0c map阶段和reduce阶段 map阶段会有一个实体程序