循化网站建设公司网络营销相关的岗位有哪些
循化网站建设公司,网络营销相关的岗位有哪些,用数据库做网站,如何开自己的网站1. 环境准备#xff1a;搭建你的第一个Hadoop“游乐场”
很多朋友一听到Hadoop、MapReduce这些词#xff0c;就觉得头大#xff0c;感觉是只有大公司才能玩转的“重型武器”。其实不然#xff0c;我第一次接触的时候也是这么想的#xff0c;但后来发现#xff0c;只要环境…1. 环境准备搭建你的第一个Hadoop“游乐场”很多朋友一听到Hadoop、MapReduce这些词就觉得头大感觉是只有大公司才能玩转的“重型武器”。其实不然我第一次接触的时候也是这么想的但后来发现只要环境搭对了入门比想象中简单得多。今天我就带你从零开始在本地电脑上搭建一个伪分布式的Hadoop环境并完成经典的WordCount词频统计程序。这个过程就像是为你准备了一个专属的“大数据游乐场”让你可以安全、自由地尝试各种操作不用担心搞坏生产环境。所谓“伪分布式”就是在一台机器上模拟出一个小型的Hadoop集群。这台机器既是“领导”NameNode也是“员工”DataNode既是“调度员”ResourceManager也是“工人”NodeManager。听起来有点精分但对于学习和测试来说这绝对是最佳选择。你不需要准备好几台服务器用你自己的笔记本电脑或者一台云主机就能搞定。我当年就是用一台内存8G的旧笔记本开始的跑起来完全没问题。那么具体需要准备些什么呢首先你需要一个Linux环境。我强烈推荐使用Ubuntu因为它对新手最友好社区资源也最丰富。如果你用的是Windows别急着装双系统更简单的方法是安装一个虚拟机软件比如VirtualBox然后在里面装一个Ubuntu系统。这一步网上教程非常多我就不赘述了。准备好Linux系统后我们主要安装三样东西Java、Hadoop和SSH。Java是Hadoop的运行基础Hadoop是我们的主角而SSH是为了让Hadoop的各个进程之间能够无密码通信这是它分布式工作的前提。安装Java很简单用包管理器就行。在Ubuntu的终端里输入sudo apt update更新软件列表然后输入sudo apt install openjdk-8-jdk安装Java 8。为什么是8因为Hadoop 2.x和3.x的主流版本对Java 8的支持最稳定兼容性问题最少。安装完成后用java -version命令验证一下能看到版本号就说明成功了。接下来是配置SSH免密登录。先在终端输入ssh localhost如果提示需要密码说明SSH服务已安装但需要配置。我们执行ssh-keygen -t rsa生成密钥对一路回车就行然后把公钥追加到授权文件cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys。最后修改一下授权文件的权限chmod 600 ~/.ssh/authorized_keys。再试一次ssh localhost如果能直接登录而不需要密码这一步就搞定了。最后是安装Hadoop。我建议直接从Apache官网下载稳定版本比如Hadoop 3.3.6。下载完成后把它解压到你喜欢的目录我习惯放在/usr/local下。然后就是最关键的环节——配置Hadoop。你需要修改几个核心配置文件它们都位于Hadoop解压目录下的etc/hadoop/文件夹里。这个过程有点像给新买的乐高玩具拼装说明书一步都不能错。主要配置四个文件core-site.xml、hdfs-site.xml、mapred-site.xml和yarn-site.xml。我会在下一节详细拆解每一个文件的配置项和含义这里你只需要知道这些文件告诉了Hadoop你的文件系统在哪里HDFS计算任务怎么调度YARN以及各个组件之间如何通信。2. Hadoop核心配置详解给机器“注入灵魂”环境装好了就像电脑有了硬件。但想让Hadoop这个“分布式大脑”运转起来还得给它注入“灵魂”——也就是正确的配置。很多新手卡在这一步看到一堆XML文件就发怵。别担心我们一个一个来我保证把每个参数都讲得明明白白。首先我们进入Hadoop的配置目录比如我的在/usr/local/hadoop-3.3.6/etc/hadoop/。用你喜欢的文本编辑器如vim或nano打开core-site.xml。这个文件是Hadoop最核心的配置它定义了整个集群的“根”在哪里。我们需要在里面添加以下内容configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/usr/local/hadoop_data/tmp/value /property /configuration第一个属性fs.defaultFS指定了默认的文件系统。这里我们设置为hdfs://localhost:9000意思是HDFS的地址在本机的9000端口。第二个属性hadoop.tmp.dir指定了Hadoop临时文件的存放目录Hadoop运行时会生成很多中间数据必须给它指定一个路径否则可能会报错。记得手动创建这个目录并赋予权限sudo mkdir -p /usr/local/hadoop_data/tmp。接下来是hdfs-site.xml它专门配置HDFS分布式文件系统。伪分布式环境下我们通常只保留一个数据副本因为只有一台机器嘛。配置如下configuration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name value/usr/local/hadoop_data/namenode/value /property property namedfs.datanode.data.dir/name value/usr/local/hadoop_data/datanode/value /property /configurationdfs.replication是数据块的副本数生产环境通常是3我们测试设为1。dfs.namenode.name.dir和dfs.datanode.data.dir分别指定了NameNode管理文件元数据和DataNode存储实际数据块的数据存放目录。同样需要提前创建这些目录。然后是mapred-site.xml它告诉Hadoop我们使用哪种计算框架。在Hadoop 2.x之后我们通常使用YARN来管理资源。所以配置是configuration property namemapreduce.framework.name/name valueyarn/value /property /configuration最后是yarn-site.xml配置YARN资源管理器。关键配置是指定资源管理器ResourceManager的地址和NodeManager上运行的辅助服务configuration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.resourcemanager.hostname/name valuelocalhost/value /property /configurationyarn.nodemanager.aux-services这个配置很关键它指定了NodeManager上运行的附加服务是mapreduce_shuffle这是MapReduce任务在Reduce阶段进行数据混洗Shuffle所必需的。yarn.resourcemanager.hostname则指定了ResourceManager运行在本地。配置完成后还有最后一步把Hadoop的bin和sbin目录添加到系统的PATH环境变量中。这样你可以在任何位置直接运行hdfs、yarn等命令。编辑你的~/.bashrc文件在末尾加上export HADOOP_HOME/usr/local/hadoop-3.3.6 export PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin保存后执行source ~/.bashrc让配置生效。至此Hadoop的“灵魂”就注入完毕了。接下来我们就要启动这个集群看看它能不能活过来。3. 启动集群与HDFS初体验让数据“住”进来配置写完了是不是有点小激动接下来就是见证奇迹的时刻——启动Hadoop集群。这个过程其实很简单但第一次操作时你可能会被刷屏的日志信息吓到。别慌我们一步步来我会告诉你哪些信息是正常的哪些可能意味着出了问题。首先我们需要格式化HDFS的NameNode。这相当于为你的分布式文件系统做一次“硬盘分区和格式化”是第一次启动前必须做的。注意这个操作只需要做一次重复格式化会导致之前存储的数据全部丢失命令是hdfs namenode -format。执行后如果看到类似 “Storage directory /usr/local/hadoop_data/namenode has been successfully formatted” 的提示就说明成功了。格式化完成后就可以启动集群了。Hadoop提供了方便的启动脚本。进入Hadoop的sbin目录执行./start-dfs.sh。这个脚本会依次启动NameNode、DataNode和SecondaryNameNode。你会看到一连串的启动日志。接着再打开一个终端执行./start-yarn.sh来启动YARN相关的ResourceManager和NodeManager。怎么确认所有服务都正常启动了呢用jps命令。这个命令会列出当前Java进程。正常情况下你应该能看到至少五个进程NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager。如果少了哪个就去对应的日志文件里找原因。日志文件通常在$HADOOP_HOME/logs目录下文件名就包含了进程名和主机名很容易定位。集群跑起来了现在我们试试HDFS这个“分布式硬盘”好不好用。首先我们在HDFS上创建一个目录用来存放待处理的数据。命令是hdfs dfs -mkdir /input。hdfs dfs是一套类似Linux文件操作的命令集-mkdir就是创建目录。创建成功后我们准备一个本地文本文件。比如在/home/yourname目录下创建一个hello.txt里面随便写几行英文句子比如hello world hello hadoop hello mapreduce world is big然后把这个文件上传到HDFS的/input目录hdfs dfs -put /home/yourname/hello.txt /input。上传完成后可以用hdfs dfs -ls /input查看文件是否在用hdfs dfs -cat /input/hello.txt查看文件内容。如果这些命令都能成功执行恭喜你你的Hadoop集群已经成功运转并且数据已经“住”进了分布式文件系统这感觉就像是你在一片广袤的虚拟土地上成功建立了第一个据点。接下来我们就要在这片土地上运行我们的第一个“魔法”——WordCount程序。4. WordCount代码实战手写第一个MapReduce程序终于到了最核心的环节——写代码。WordCount被称为大数据界的“Hello World”因为它完美地体现了MapReduce“分而治之”的思想。别被“分布式计算”吓到其实它的逻辑非常直观。想象一下你有一本厚厚的书想要统计每个单词出现的次数。最笨的办法是自己一页页数。而MapReduce的做法是找一群人Mapper每人分几页各自数自己那几页里每个单词的出现次数并写成单词次数的小纸条然后再找一个人Reducer把所有小纸条收上来把相同单词的次数加起来得到最终结果。我们先在本地创建一个普通的Java项目。我习惯用IntelliJ IDEA或Eclipse你用任何一个顺手的IDE都可以。创建一个Maven项目在pom.xml中添加Hadoop客户端的依赖dependency groupIdorg.apache.hadoop/groupId artifactIdhadoop-client/artifactId version3.3.6/version /dependency这样IDE会自动帮你下载和管理相关的Jar包比手动添加省心多了。接下来我们创建三个核心类WordCountMapper、WordCountReducer和WordCountDriver主类。先看Mapper它的任务就是“拆分”和“映射”。我写的Mapper类长这样import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; public class WordCountMapper extends MapperLongWritable, Text, Text, LongWritable { private final static LongWritable ONE new LongWritable(1); private Text word new Text(); Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { // 1. 拿到一行文本 String line value.toString(); // 2. 按空格切分成单词数组 String[] words line.split(\\s); // 3. 遍历每个单词输出 (单词, 1) for (String w : words) { if (!w.trim().isEmpty()) { // 过滤空字符串 word.set(w); context.write(word, ONE); } } } }我来解释一下这里的几个关键点。首先类定义中的泛型LongWritable, Text, Text, LongWritable定义了输入和输出的键值对类型。前两个是输入LongWritable代表行偏移量可以理解为行号Text代表这一行的文本内容。后两个是输出Text是单词本身LongWritable是计数这里固定为1。map方法会为输入文件的每一行调用一次。我们拿到一行文本按空格\\s是正则表示一个或多个空白字符切分成单词然后遍历每个单词通过context.write(word, ONE)输出一个中间键值对比如(hello, 1)、(world, 1)。Mapper做完“分”的工作输出一大堆(单词, 1)的中间结果。Hadoop框架会自动对这些中间结果进行Shuffle洗牌和Sort排序把所有相同的单词分到一组然后交给Reducer。Reducer的职责就是“归约”和“汇总”。下面是Reducer的代码import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; public class WordCountReducer extends ReducerText, LongWritable, Text, LongWritable { private LongWritable result new LongWritable(); Override protected void reduce(Text key, IterableLongWritable values, Context context) throws IOException, InterruptedException { // 1. 对同一个key单词的所有value1进行求和 long sum 0; for (LongWritable val : values) { sum val.get(); } // 2. 输出最终结果 (单词, 总次数) result.set(sum); context.write(key, result); } }Reducer的输入类型必须和Mapper的输出类型对应所以是Text, LongWritable。reduce方法接收一个键单词和这个键对应的所有值的迭代器一堆1。我们只需要遍历这个迭代器把所有的1加起来就得到了这个单词出现的总次数然后通过context.write(key, result)输出最终结果。最后我们需要一个“总指挥”来把Mapper和Reducer组装起来并指定任务的输入输出路径。这就是Driver类import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; 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; public class WordCountDriver { public static void main(String[] args) throws Exception { // 1. 获取配置和Job实例 Configuration conf new Configuration(); Job job Job.getInstance(conf, Word Count); // 2. 指定本程序的Jar包路径本地运行可省略集群运行必须 job.setJarByClass(WordCountDriver.class); // 3. 指定Mapper和Reducer类 job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); // 4. 指定Mapper输出的kv类型 job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(LongWritable.class); // 5. 指定最终输出的kv类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); // 6. 指定输入和输出路径通过命令行参数传入 FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); // 7. 提交作业并等待完成 boolean success job.waitForCompletion(true); System.exit(success ? 0 : 1); } }这个Driver类就是整个MapReduce任务的蓝图。它创建了一个Job对象设置了Mapper和Reducer类定义了输入输出数据的格式并指定了输入输出在HDFS上的路径。注意输入输出路径我们通过命令行参数args[0]和args[1]传入这样更灵活。代码写完了本地运行一下确保没有编译错误。接下来我们就要把这个程序打包送到Hadoop集群上去执行了。5. 打包、提交与结果验证见证分布式计算的魅力代码在本地IDE里跑通只是万里长征第一步。真正的挑战在于把它放到分布式环境里运行。这一步会碰到很多“坑”比如类找不到、路径不对、权限问题等等。别怕我踩过的坑今天都给你填平。首先我们需要把项目打包成一个可执行的JAR文件。如果你用的是Maven在项目根目录下运行mvn clean package命令Maven会自动打包并在target目录下生成一个your-project-name-1.0-SNAPSHOT.jar文件。这里有个关键点我们需要的是包含所有依赖的“胖JAR”Fat JAR或者确保Hadoop集群的每台机器上都有我们程序所依赖的Jar包。对于WordCount这种只依赖Hadoop客户端的情况打一个普通的JAR就行因为Hadoop集群的节点上已经自带了这些库。但如果你用了其他第三方库就必须打“胖JAR”。可以在pom.xml中配置maven-assembly-plugin或maven-shade-plugin插件来实现。打包成功后通过终端将JAR文件上传到你的Hadoop主节点也就是你搭建伪分布式环境的那台机器。假设你的JAR文件叫wordcount.jar上传到了/home/yourname/目录下。同时确保你的输入数据已经在HDFS的/input目录里了就像我们第三节做的那样。现在来到最激动人心的时刻——向集群提交作业。打开终端使用hadoop jar命令hadoop jar /home/yourname/wordcount.jar WordCountDriver /input /output我来拆解一下这个命令hadoop jar是提交MapReduce作业的固定命令后面跟着JAR包的完整路径WordCountDriver是你主类的全限定名如果包名是com.example这里就要写com.example.WordCountDriver最后两个参数/input和/output分别对应你代码中args[0]和args[1]也就是HDFS上的输入目录和输出目录。特别注意输出目录/output必须是不存在的Hadoop会自己创建它如果目录已存在作业会直接失败这是Hadoop的一个保护机制。命令回车后屏幕上会开始滚动大量的日志。你可以通过YARN的Web界面默认地址是http://localhost:8088来实时监控作业的执行情况看到Map任务和Reduce任务的进度、成功或失败的状态。这个过程可能需要几十秒到几分钟取决于你的文件大小和机器性能。作业执行完成后如何查看结果呢回到终端使用HDFS命令查看输出目录hdfs dfs -ls /output你应该会看到两个文件_SUCCESS和part-r-00000。_SUCCESS是一个空标志文件表示作业成功完成。真正的结果在part-r-00000这个文件里。用hdfs dfs -cat /output/part-r-00000查看其内容你会看到类似这样的输出hadoop 1 hello 3 is 1 mapreduce 1 world 2每一行就是一个单词及其出现的总次数中间用制表符分隔。看到这个结果是不是特别有成就感你刚刚完成了一个真正的分布式计算任务Hadoop框架自动把输入文件切分成块Input Split分发给多个Map任务并行处理经过复杂的Shuffle和Sort再由Reduce任务汇总最终把结果写回HDFS。这一切都被你刚刚那一行命令触发了。6. 避坑指南与进阶思考从能跑到跑得好第一次成功运行WordCount的兴奋劲过去后你可能会想如果文件更大、逻辑更复杂怎么办在实际项目中我们肯定会遇到各种问题。这一节我就分享几个最常见的“坑”和进阶优化的思路帮你从“能跑通”进化到“跑得好”。第一个大坑ClassNotFoundException 或 NoClassDefFoundError。这是提交作业时最常见的问题。根本原因就是集群的节点找不到你程序里用到的类。解决方法有三第一确保你打的JAR包是“胖JAR”包含了所有非Hadoop自带的依赖。第二可以通过-libjars参数在提交作业时指定额外的JAR包路径但管理起来比较麻烦。第三也是最推荐生产环境使用的方法将你的依赖JAR包提前上传到HDFS的某个目录然后在Driver类里通过job.addFileToClassPath方法将其添加到分布式缓存中这样所有任务节点就都能访问到了。第二个坑输出目录已存在。前面提过Hadoop不允许输出目录已存在。一种做法是在代码里先判断目录是否存在如果存在就删除。但更优雅的方式是在提交作业的脚本里处理比如hdfs dfs -test -d /output hdfs dfs -rm -r /output然后再提交作业。第三个坑数据倾斜Data Skew。这是性能优化中的核心问题。想象一下如果你的文本里有一个单词“的”出现了几百万次而其他单词只出现几次。那么处理“的”的那个Reduce任务就会成为最慢的“短板”拖慢整个作业。解决数据倾斜需要根据具体业务来设计。对于WordCount一个简单的办法是使用Combiner。Combiner可以看作是一个运行在Map节点本地的“迷你Reducer”它会在Map输出后、数据发送到网络之前先在本地做一次合并。比如一个Map任务输出了100次(hello, 1)Combiner会先在本地把它们合并成(hello, 100)大大减少了网络传输的数据量。启用Combiner非常简单只要你的Combiner逻辑和Reducer逻辑一致满足结合律和交换律直接在Driver里设置job.setCombinerClass(WordCountReducer.class)即可。进阶思考如何提高作业性能除了使用Combiner你还可以调整一些关键参数。比如通过mapreduce.job.maps和mapreduce.job.reduces可以手动设置Map和Reduce的任务数量。通常Map数量由输入文件的总大小和块大小默认128MB决定而Reduce数量需要根据数据量和集群资源仔细权衡太多会增加开销太少则无法充分利用并行能力。另外对于复杂的业务逻辑要善用自定义Writable类型和分区器Partitioner。比如如果你要统计的不是单词而是更复杂的对象就需要自己实现一个Writable类并重写序列化方法。如果你希望某些特定的键被分配到同一个Reducer处理就需要自定义Partitioner。最后别忘了查看日志。Hadoop的日志系统非常完善。作业运行详情可以在YARN的Web UIhttp://localhost:8088上查看。每个任务的详细日志包括标准输出、标准错误和系统日志都可以通过UI点击进去查看。当作业失败时这些日志是你定位问题的唯一依据。我习惯在开发阶段先把作业的Reduce数量设为0job.setNumReduceTasks(0)这样只运行Map阶段可以快速验证数据解析逻辑是否正确输出结果可以通过HDFS直接查看能节省大量调试时间。走完这一整套流程从环境搭建、配置、编码、打包到提交和调优你对Hadoop MapReduce的理解就不再是浮于表面的概念了。你会真正理解“分而治之”是如何在代码和集群中落地的。虽然现在更流行Spark、Flink这些内存计算框架但MapReduce作为经典范式其思想是永恒的。掌握了它你再学习其他分布式计算框架都会有一种“似曾相识”的感觉因为核心的分布式思维是相通的。