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

Ambari自动部署Hadoop集群实战

一、大数据简介

1、为什么使用大数据技术?

  • 数据量越来越大
  • 数据分析的实时性越来越强
  • 数据结果的应用越来越广泛
结论: 我们需要使用大数据技术。

2、大数据的定义

大数据是收集、整理、处理大容量数据集,并从中获得结果的技术总称。

二、大数据应用领域

1)广告
  • 广告投放
  • 广告策略
2)电信
  • 深度包检测
  • 流失分析
  • 网络质量
3)金融
  • 风险识别
  • 预测
4)能源生物
  • 基因组分析
  • 地质分析
5)安全入侵检测
  • 图像识别
6)社交游戏
  • 流失分析
  • 社交推荐
  • 使用分析
7)电商零售
  • 推荐系统
  • 交易分析

三、大数据技术框架

1、什么是大数据处理框架

处理框架 处理引擎 负责对数据系统中的数据进行计算。
虽然 引擎 框架 之间的区别没有什么权威的定义,但大部分时候可以将前者定义为实际负责处理数据操作的组 件,后者则可定义为承担类似作用的一系列组件。

2、大数据处理框架有哪些

  • 仅批处理框架

用于批量处理大数据集的处理框架,可对整个数据集进行操作。

例如:

Apache Hadoop,一种以MapReduce作为默认处理引擎批处理框架。

  • 仅流处理框架

用于对随时进入系统的数据进行计算,是一种“无数据边界”的操作方式。

例如:

Apache Storm
Apache Samza

  • 混合处理框架

一些大数据处理框架可同时处理批处理和流处理工作负载。

例如:

Apache Spark
Apache Flink

总结:

  • 处理框架 一组组件
  • 处理引擎 具体对数据操作的工具
  • 框架分类

仅批处理框架:apache hadoop MapReduce
仅流处理框架:apache storm apache samza
混合处理框架:apache spark apache flink

四、hadoop生态圈

1、Hadoop历史

雏形开始于2002年的Apache的Nutch,Nutch是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。

随后在2003年Google发表了一篇技术学术论文谷歌文件系统(GFS)。GFS也就是google File System,google公司为了存储海量搜索数据而设计的专用文件系统。

2004年Nutch创始人Doug Cutting基于Google的GFS论文实现了分布式文件存储系统名为NDFS。

2004年Google又发表了一篇技术学术论文MapReduce。MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行分析运算。

2005年Doug Cutting又基于MapReduce,在Nutch搜索引擎实现了该功能。

2006年,Yahoo雇用了Doug Cutting,Doug Cutting将NDFS和MapReduce升级命名为Hadoop,

Yahoo开建了一个独立的团队给Goug Cutting专门研究发展Hadoop。

Google和Yahoo对Hadoop的贡献功不可没。

总结:

  • NDFS--->HDFS
  • MapReduce

2、项目定义

Apache™Hadoop®项目用于可靠,可扩展的分布式计算的开源软件。

Apache Hadoop是一个大数据处理框架,允许使用简单的编程模型跨计算机集群分布式处理大型数据集。

Apache Hadoop可以从单个服务器扩展到数千台计算机。

Apache Hadoop集群中每台计算机都提供本地计算和存储。

Apache Hadoop集群不是依靠硬件来提供高可用性,而是设计了用于检测和处理应用程序层的故障,从而在计算机集群之上提供高可用性服务。

总结:

  • 开源软件
  • 大数据处理架构
  • 单台服务可以,数千台服务器
  • 每台服务器都存自己的数据及运算自己的数据
  • 把硬件故障认为常态,通过软件把控故障

3、核心项目

Hadoop分布式文件系统(HDFS™):一种分布式文件系统,可提供对应用程序数据的高吞吐量访问。

  • Hadoop YARN:作业调度和集群资源管理的框架。
  • Hadoop MapReduce:基于YARN的系统,用于并行处理大型数据集。
  • Hadoop Common:支持其他Hadoop模块的常用实用程序。
  • Hadoop Ozone: Hadoop集群所提供的对象存储。

4、相关项目

Apache的其他Hadoop相关项目包括:

  • Ambari™

基于Web的工具,用于配置,管理和监控Apache Hadoop集群,包括对Hadoop HDFS,Hadoop
MapReduce,Hive,HCatalog,HBase,ZooKeeper,Oozie,Pig和Sqoop的支持。

Ambari还提供了一个用于查看集群运行状况的仪表板,例如热图,以及可视化查看MapReduce,Pig和Hive应用程序的功能,以及以用户友好的方式诊断其性能特征的功能。

  • Avro™

数据序列化系统。

  • Cassandra™

可扩展的多主数据库,没有单点故障。

  • Chukwa™

用于管理大型分布式系统的数据收集系统。

  • HBase™

可扩展的分布式数据库,支持大型表的结构化数据存储。

  • Hive™

一种数据仓库基础架构,提供数据汇总和即时查询。

  • Mahout™

可扩展的机器学习和数据挖掘库。

  • Pig™

用于并行计算的高级数据流语言和执行框架。

  • Spark™:

用于Hadoop数据的快速通用计算引擎。Spark提供了一种简单而富有表现力的编程模型,支持广泛的应用程序,包括ETL,机器学习,流处理和图形计算。

  • Tez™

基于Hadoop YARN构建的通用数据流编程框架,它提供了一个功能强大且灵活的引擎,可以执行任意DAG任务来处理批量和交互式用例的数据。Tez正在被Hadoop生态系统中的Hive™,Pig™和其他框架以及其他商业软件(例如ETL工具)采用,以取代Hadoop™MapReduce作为底层执行引擎。

  • ZooKeeper™

用于分布式应用程序的高性能协调服务。

总结:

  • 核心项目 hdfs mapreduce yarn
  • 相关项目 ambari hbase hive spark zookeeper 

五、Hadoop核心项目Hadoop分布式文件系统(HDFS)介绍

  • Hadoop的基础核心就是HDFS和MapReduce,
  • Hadoop旗下有很多经典子项目,比如HBase、Hive等,这些都是基于HDFS和MapReduce发展出来的。要想了解Hadoop,就必须知道HDFS和MapReduce是什么。

1、hadoop文件系统定义

  • HDFS(Hadoop Distributed File System,Hadoop分布式文件系统)
  • 它是一个高度容错性的系统
  • 它适合部署在廉价的机器上
  • 它能提供高吞吐量的数据访问
  • 它适合那些有着超大数据集(large data set)的应用程序
超大数据集指的是:海量数据分析、机器学习等

2、hadoop文件系统特点

  • 支持大数据文件

非常适合上TB级别的大文件或者一堆大数据文件的存储,如果文件只有几个G甚至更小就没啥意思了。

  • 支持文件分块存储

HDFS会将一个完整的大文件平均分块存储到不同计算节点上,它的意义在于读取文件时可以同时从多个计算节点上读取不同区块的文件,多主机读取比单主机读取效率要高得多。

  • 支持一次写入,多次读取,顺序读取(流式数据访问)

这种模式跟传统文件不同,它不支持动态改变文件内容,而是要求让文件一次写入就不做变化,要变化也只能在文件末添加内容。

  • 支持廉价硬件

HDFS可以部署在普通PC机上,这种机制能够让给一些公司用几十台廉价的计算机就可以撑起一个大数据集群。

  • 支持硬件故障

HDFS认为所有计算机都可能会出问题,为了防止某个主机失效读取不到该主机的块文件,它将同一个文件块副本分配到其它某几个主机上,如果其中一台主机失效,可以迅速找另一块副本取文件。

总结:
  • 支持大文件
  • 分块
  • 廉价设备
  • 支持硬件故障

3、hadoop分布式文件系统关键词

  • Block
最基本的存储单位;将文件进行分块处理,通常是 128M/ 块,例如: 256M 文件会被分为 2个 Block
Hadoop 1.x 版本, Block 默认大小为 64M Hadoop 2.x Block 默认大小为 128M
Hadoop集群架构(主从架构):
1)NameNode(主节点)
  • 用于保存整个文件系统的目录信息、文件信息及分块信息,这是由唯一一台主机专门保存,当然这台主机如果 出错,NameNode就失效了。
  • 接收用户的操作请求。
  • 维护文件系统的目录结构。
  • 管理文件和Block之间的映射管理。
  • 管理 block DataNode 之间的映射。
Hadoop2.* 开始支持 activity-standy 模式 , 如果主 NameNode 失效,启动备用主机运行 NameNode
2)DataNode(从节点)
  • 分布在廉价的计算机上,用于存储Block块文件。
  • 文件被分成块存储到 DataNode 的磁盘上。
  • 每个Block(块)可以设置多副本。
总结:
  • block 文件块 128M/
  • namenode 目录 文件 分块 接收用户访问 文件与block blockdatanode
  • datanode block 副本存储

4、hdfs写数据流程

总结:
  • 客户端向namenode发起请求
  • 客户端向dn发起建立连接请求
  • 客户端向dn存储数据

5、hdfs读数据流程 

六、Hadoop核心项目编程模型(MapReduce)介绍

1、MapReduce作用

通过对HDFS分布式文件系统的了解,我们已经可以把海量数据存储在集群中DataNode之上了,但这仅是Hadoop工作的第一步,那么如何从海量的数据中找到我们所需要的数据呢,这就是MapReduce要做的事情了。
下面通过2个例子给予说明:
案例1:

求和:1+5+7+3+4+9+3+5+6=?
答案:
案例2:
一个银行有上亿储户,银行希望找到存储金额最高的金额是多少?
答案:
方法1:按照传统的计算方式,我们会这样(java代码):
Long moneys[] ... 
Long max = 0L; 
for(int i=0;i<moneys.length;i++){ 
if(moneys[i]>max){ 
    max = moneys[i]; 
    } 
}

此种方法存在问题:如果数组元素比较少的话,完全可以胜任,但是如果数组中的元素数量是海量的话,那么这个方法就会浪费非常多的时间。

方法2:
首先数字是分布存储在不同块中的,以某几个块为一个Map,计算出Map中最大的值,然后将每个Map中的最大值做Reduce操作,Reduce再取最大值给用户。
结论:
将大的数据分析分成小块逐个分析,最后再将提取出来的数据汇总分析,最终获得我们想要的内容。
通俗说MapReduce是一套从海量源数据提取、分析元素,最后返回结果集的方法。
当然怎么分块分析,怎么做Reduce操作非常复杂,Hadoop已经提供了数据分析的实现,我们只需要编写简单的需求命令即可达成我们想要的数据。
总结:
  • map 把大数据分成小数据,进行计算 通过洗牌的方式给reduce
  • reduce 对map的结果进行汇总

2、MapReduce工作流程

MapReduce 框架的核心步骤主要分两部分:Map 和Reduce。
当向MapReduce 框架提交一个计算作业时,它会首先把计算作业拆分成若干个Map 任务,然后分配到不同的节点(DataNode)上去执行,每一个Map 任务处理输入数据中的一部分,当Map 任务完成后,它会生成一些中间文件,这些中间文件将会作为Reduce 任务的输入数据。Reduce 任务的主要目标就是把前面若干个Map 的输出汇总到一起并输出。
从高层抽象来看,MapReduce的数据流图如下图所示:

MapReduce工作流程: 

总结:
  • map
  • reduce

七、Hadoop部署区分依据

本地模式、伪分布式、完全分布式区分依据:
主要的区别依据是NameNode、DataNode、ResourceManager、NodeManager等模块运行在几个JVM进程、几个机器。
如下表所示:

八、单机(本地模式)部署 

1、单机部署模式介绍

  • 单机(本地模式)是Hadoop的默认部署模式。
  • 当配置文件为空时,Hadoop完全运行在本地。
  • 不需要与其他节点交互,单机(本地模式)就不使用HDFS,也不加载任何Hadoop的守护进程。
  • 该模式主要用于开发调试MapReduce程序的应用逻辑。

2、部署软件包获取

1. 获取hadoop软件包

2. 获取JDK软件包  

[root@localhost ~]#firefox http://download.oracle.com 1

3、部署

1. jdk部署
[root@localhost ~]#tar xf jdk-8u191-linux-x64.tar.gz -C /usr/local 
[root@localhost ~]# cd /usr/local 
[root@localhost local]# mv jdk1.8.0_191 jdk
解压到指定目录后,请修改目录名。
2. hadoop部署
[root@localhost ~]# tar xf hadoop-2.8.5.tar.gz -C /opt 
[root@localhost ~]# cd /opt 
[root@localhost opt]# mv hadoop-2.8.5 hadoop
解压至指定目录后,请修改目录名称。
3. Linux系统环境变量
[root@localhost ~]#vim /etc/profile 
export JAVA_HOME=/usr/local/jdk 
export HADOOP_HOME=/opt/hadoop 
export PATH=${JAVA_HOME}/bin:${HADOOP_HOME}/bin:$PATH
4. 应用测试
1) 加载环境变量
[root@localhost ~]#source /etc/profile

2)测试hadoop可用性

[root@localhost ~]#mkdir /home/input 
[root@localhost ~]#cp /opt/hadoop/etc/hadoop/*.xml /home/input 
[root@localhost ~]#hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce- examples-2.8.5.jar wordcount /home/input/ /home/output/00 
[root@localhost ~]#cat /home/output/00/*
输出目录中有_SUCCESS文件说明JOB运行成功,part-r-00000是输出结果文件。

九、伪分布式部署

1、伪分布式部署模式介绍

  • Hadoop守护进程运行在本地机器上,模拟一个小规模的的集群。
  • 该模式在单机模式之上增加了代码调试功能,允许你检查内存使用情况,HDFS输入/输出,以及其他的守护进 程交互。

2、修改配置文件

主要涉及的配置文件有: hadoop-env.sh mapred-env.sh yarn-env.sh core-site.xml。
1 )修改 hadoop-env.sh mapred-env.sh yarn-env.sh 文件中 JAVA_HOME 参数
[root@localhost ~]#vim ${HADOOP_HOME}/etc/hadoop/hadoop-env.sh
修改JAVA_HOME参数为: 
export JAVA_HOME="/usr/local/jdk" 12
2) 修改 core-site.xml
[root@localhost ~]#vim ${HADOOP_HOME}/etc/hadoop/core-site.xml
(1)配置fs.defaultFS 
<property> 
    <name>fs.defaultFS</name> 
    <value>hdfs://hd1:8020</value> 
</property> 
(2)配置hadoop临时目录 
<property> 
    <name>hadoop.tmp.dir</name> 
    <value>/opt/data/tmp</value> 
</property>

配置临时目录前,请先创建此目录,不创建也可以。

HDFS的NameNode数据默认都存放这个目录下,查看 *-default.xml 等默认配置文件,就可以看到很多依赖${hadoop.tmp.dir} 的配置。

默认的 hadoop.tmp.dir 是 /tmp/hadoop-${user.name} ,此时有个问题就是NameNode会将HDFS的元数据存储在这个/tmp目录下,如果操作系统重启了,系统会清空/tmp目录下的东西,导致NameNode元数据丢失,是个非常严重的问题,所有我们应该修改这个路径。

3)配置hdfs-site.xml
[root@localhost ~]#vim ${HADOOP_HOME}/etc/hadoop/hdfs-site.xml
<property> 
    <name>dfs.replication</name> 
    <value>1</value> 
</property>
dfs.replication 配置的是 HDFS存储时的备份数量,因为这里是伪分布式环境只有一个节点,所以这里设置为1。
4)格式化hdfs
[root@localhost ~]#hdfs namenode –format
格式化是对 HDFS 这个分布式文件系统中的 DataNode 进行分块,统计所有分块后的初始元数据的存储在 NameNode中。
格式化后,查看 core-site.xml hadoop.tmp.dir (本例是 /opt/data 目录)指定的目录下是否有了 dfs 目录,如果有,说明格式化成功。
5) 查看 hdfs 临时目录
[root@localhost ~]#ls /opt/data/tmp/dfs/name/current
  • fsimageNameNode元数据在内存满了后,持久化保存到的文件。
  • fsimage*.md5 是校验文件,用于校验fsimage的完整性。
  • seen_txid hadoop的版本。
vession文件里保存:
  • namespaceIDNameNode的唯一ID
  • clusterID:集群IDNameNodeDataNode的集群ID应该一致,表明是一个集群。

3、启动角色

请把hadoop安装目录中的sbin目录中的命令添加到/etc/profifile环境变量中,不然无法使用hadoop
daemon.sh。
1 )启动 namenode
[root@localhost ~]#hadoop-daemon.sh start namenode
2 )启动 datanode
[root@localhost ~]#hadoop-daemon.sh start datanode 1
3) 验证
JPS命令查看是否已经启动成功,有结果就是启动成功了。
[root@localhost ~]#jps

4、HDFS上测试创建目录、上传、下载文件

1) 创建目录
[root@localhost ~]#hdfs dfs -mkdir /test
2) 上传文件
[root@localhost ~]#hdfs dfs -put ${HADOOP_HOME}/etc/hadoop/core-site.xml /test

3)读取内容

[root@localhost ~]#hdfs dfs -cat /test/core-site.xml

4)下载文件到本地

[root@localhost ~]#hdfs dfs -get /test/core-site.xml

5、配置yarn

1)Yarn介绍

  • A framework for job scheduling and cluster resource management.
功能:任务调度 和 集群资源管理。
  • YARN (Yet An other Resouce Negotiator) 另一种资源协调者
是 Hadoop 2.0新增加的一个子项目,弥补了Hadoop 1.0(MRv1)扩展性差、可靠性资源利用率低以及无法支持 其他计算框架等不足。
  • Hadoop的下一代计算框架MRv2将资源管理功能抽象成一个通用系统YARN。
  • MRv1的 jobtracker和tasktrack也不复存在,计算框架 (MR, storm, spark)同时运行在之上,使得hadoop进入 了多计算框架的弹性平台时代。
总结:
  • yarn是一种资源协调者
  • mapreduce拆分而来
  • 带来的好处:让hadoop平台性能及扩展性得到更好发挥

2)使用Yarn好处

  • 在某些时间,有些资源计算框架的集群紧张,而另外一些集群资源空闲。 那么这框架共享使用一个则可以大提高利率些集群资源空闲。
  • 维护成本低。
  • 数据共享。 避免了集群之间移动数据。
YARN主从架构:
  • ResourceManager 资源管理
  • NodeManager 节点管理
  • ResourceManager

负责对各个NodeManager 上的资源进行统一管理和任务调度。

  • NodeManager

在各个计算节点运行,用于接收RM中ApplicationsManager 的计算任务、启动/停止任务、和RM中
Scheduler 汇报并协商资源、监控并汇报本节点的情况。

3)配置mapred-site.xml

默认没有 mapred-site.xml 文件,但是有个 mapred-site.xml.template 配置模板文件。复制模板生成 mapred-site.xml。
[root@localhost ~]#cp /opt/hadoop/etc/hadoop/mapred-site.xml.template /opt/hadoop/etc/hadoop/mapred-site.xml

<property> 
    <name>mapreduce.framework.name</name> 
    <value>yarn</value> 
</property>
指定mapreduce运行在yarn框架上。

4)配置yarn-site.xml

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

yarn.nodemanager.aux-services配置yarn的默认混洗方式,选择为mapreduce的默认混洗算法。

yarn.resourcemanager.hostname指定了Resourcemanager运行在哪个节点上。

5) 启动 yarn
[root@localhost ~]#yarn-daemon.sh start resourcemanager 1

[root@localhost ~]#yarn-daemon.sh start nodemanager 1

[root@localhost ~]#jps

6)YARN的Web页面

YARN的Web客户端端口号是8088,通过http://hd1:8088/可以查看。

7)测试

在Hadoop的share目录里,自带了一些jar包,里面带有一些mapreduce实例小例子,位置在
share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.5.jar,可以运行这些例子体验刚搭建好的Hadoop平台,我们这里来运行最经典的WordCount实例。

① 创建目录

[root@localhost ~]#hdfs dfs -mkdir -p /test/input

创建原始文件,在本地/opt/data目录创建一个文件wc.input,内容如下:

tom jime
hadoop hive
hbase hadoop tom

② 上传文件

将wc.input文件上传到HDFS的/test/input目录中:

[root@localhost ~]#hdfs dfs -put /opt/data/wc.input /test/input

③ ​​​​​​​运行实例

[root@localhost ~]#yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples- 2.8.5.jar wordcount /test/input /test/output

④ 查看输出结果

[root@localhost ~]#hdfs dfs -ls /test/output

output目录中有两个文件,_SUCCESS文件是空文件,有这个文件说明Job执行成功。

part-r-00000文件是结果文件,其中-r-说明这个文件是Reduce阶段产生的结果,mapreduce程序执行时,可以没有reduce阶段,但是肯定会有map阶段,如果没有reduce阶段这个地方有是-m-。

一个reduce会产生一个part-r-开头的文件。

6、停止hadoop

[root@localhost ~]#hadoop-daemon.sh stop namenode 
[root@localhost ~]#hadoop-daemon.sh stop datanode 
[root@localhost ~]#yarn-daemon.sh stop resourcemanager 
[root@localhost ~]#yarn-daemon.sh stop nodemanager

7、开启历史服务及查看

Hadoop开启历史服务可以在web页面上查看Yarn上执行job情况的详细信息。可以通过历史服务器查看已经运行完的Mapreduce作业记录,比如用了多少个Map、用了多少个Reduce、作业提交时间、作业启动时间、作业完成时间等信息。

[root@localhost ~]#mr-jobhistory-daemon.sh start historyserver

开启后,可以通过Web页面查看历史服务器:

http://localhost:19888

8、开启日志聚集

MapReduce是在各个机器上运行的,在运行过程中产生的日志存在于各个机器上,为了能够统一查看各个机器的运行日志,将日志集中存放在HDFS上,这个过程就是日志聚集。
Hadoop默认是不启用日志聚集的。在yarn-site.xml文件里配置启用日志聚集。
<property> 
    <name>yarn.log-aggregation-enable</name> 
    <value>true</value> 
</property> 
<property> 
    <name>yarn.log-aggregation.retain-seconds</name> 
    <value>106800</value> 
</property>

yarn.log-aggregation-enable:是否启用日志聚集功能。

yarn.log-aggregation.retain-seconds:设置日志保留时间,单位是秒。

以上内容要复制给集群所有主机。

1)重启yarn
[root@localhost ~]#stop-yarn.sh 
[root@localhost ~]#start-yarn.sh 12
2)重启历史服务
[root@localhost ~]#mr-jobhistory-daemon.sh stop historyserver 
[root@localhost ~]#mr-jobhistory-daemon.sh start historyserver

十、NameNode HA+完全分布式部署

完全分部式是真正利用多台Linux主机来进行部署Hadoop,对Linux机器集群进行规划,使得Hadoop各个模块分别部署在不同的多台机器上。

1、HA简介

HA的意思是High Availability高可用,指当当前工作中的机器宕机后,会自动处理这个异常,并将工作无缝地转移到其他备用机器上去,以来保证服务的高可用。
HA方式安装部署才是最常见的生产环境上的安装部署方式。Hadoop HA是Hadoop 2.x中新添加的特性,包括NameNode HA 和 ResourceManager HA。因为DataNode和NodeManager本身就是被设计为高可用的,所以不用对他们进行特殊的高可用处理。

2、NameNode HA切换实现方法

Hadoop2.X对NameNode进行一个抽象:NameService 一个NameService下面有两个NameNode,分别处于Active和Standby状态。
通过Zookeeper进行协调选举,确保只有一个活跃的NameNode。
一旦主(Active)宕掉,standby会切换成Active。

 

作为一个ZK集群的客户端,用来监控NN的状态信息。每个运行NN的节点必须要运行一个zkfc。
zkfc提供以下功能:
Health monitoring
zkfc定期对本地的NN发起health-check的命令,如果NN正确返回,那么这个NN被认为是OK的。否则被认为是失效节点。
ZooKeeper session management
当本地NN是健康的时候,zkfc将会在zk中持有一个session。如果本地NN又正好是active的,那么zkfc还有持有一个"ephemeral"的节点作为锁,一旦本地NN失效了,那么这个节点将会被自动删除。
ZooKeeper-based election
如果本地NN是健康的,并且zkfc发现没有其他的NN持有那个独占锁。那么他将试图去获取该锁,一旦成功,那么它就需要执行Failover,然后成为active的NN节点。
Failover的过程是:
第一步,对之前的NN执行fence,如果需要的话。
第二步,将本地NN转换到active状态。

3、NameNode HA数据共享方法

Namenode主要维护两个文件,一个是fsimage,一个是editlog。
fsimage保存了最新的元数据检查点,包含了整个HDFS文件系统的所有目录和文件的信息。对于文件来说包括了数据块描述信息、修改时间、访问时间等;对于目录来说包括修改时间、访问权限控制信息(目录所属用户,所在组)等。
editlog主要是在NameNode已经启动情况下对HDFS进行的各种更新操作进行记录,HDFS客户端执行所有的写操作都会被记录到editlog中。
上面在Active Namenode与StandBy Namenode之间的绿色区域就是JournalNode,当然数量不一定只有1个,作用相当于NFS共享文件系统,Active Namenode往里写editlog数据,StandBy再从里面读取数据进行同步。
两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当active状态的NameNode的命名空间有任何修改时,会告知大部分的JournalNodes进程。standby状态的NameNode有能力读取JNs中的变更信息,并且一直监控edit log的变化,把变化应用于自己的命名空间。standby可以确保在集群出错时,命名空间状态已经完全同步了。
集群启动时,可以同时启动2个NameNode。这些NameNode只有一个是active的,另一个属于standby状态。
active状态意味着提供服务,standby状态意味着处于休眠状态,只进行数据同步,时刻准备着提供服务。

4、部署规划

5、 实施

1)系统时间同步

[root@localhost ~]#ntpdate time1.aliyun.com
2) 设置主机 IP 及名称解析
[root@localhost ~]#vim /etc/hosts 
192.168.208.5 hd1 
192.168.208.10 hd2 
192.168.208.20 hd3 
192.168.208.30 hd4 
192.168.208.40 hd5 
192.168.208.50 hd6
/etc/hosts 文件复制到所有集群主机
3) 关闭防火墙及 Selinux
[root@localhost ~]# systemctl stop firewalld 
[root@localhost ~]# systemctl disable firewalld 
[root@localhost ~]# sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
4) 部署 JDK
[root@localhost ~]#firefox http://download.oracle.com 
[root@localhost ~]#tar xf jdk-8u191-linux-x64.tar.gz -C /usr/local 
[root@localhost ~]#mv /usr/local/jdk1.8 /usr/local/jdk
5)SSH 免密登录
[root@localhost ~]#ssh-keygen -t rsa -f /root/.ssh/id_rsa -P '' 
[root@localhost ~]#cd /root/.ssh 
[root@localhost ~]#cp id_rsa.pub authorized_keys 
[root@localhost ~]#for i in hd2 hd3 hd4 hd5 hd6;do scp -r /root/.ssh $i:/root;done
把密钥复制到所有主机
6)zookeeper部署
① zookeeper作用
ZooKeeper 是为分布式应用程序提供高性能协调服务的工具集合,译名为“动物园管理员”。
分布式应用程序可以基于它实现配置维护、命名服务、分布式同步、组服务等。
是 Hadoop集群管理的一个必不可少的模块,它主要用来解决分布式应用中经常遇到的数据管理问题,如集群管理、统一命名服务、分布式配置管理、分布式消息队列、分布式锁、分布式协调等。
在ZooKeeper集群当中,集群中的服务器角色有两种Leader和Learner,Learner角色又分为Observer和Follower
Zookeeper的核心是原子广播,这个机制保证了各个 Server 之间的同步。实现这个机制的协议叫做 Zab 协议。 Zab 协 议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。
当服务启动或者在领导者崩溃后,Zab 就进入了恢复模式,当领导者被选举出来,且大多数 Follower 完成了和 leader 的状态同步以后,恢复模式就结束了。状态同步保证了leader Follower 具有相同的系统状态。
如下图所示:
该ZooKeeper集群当中一共有5台服务器,有两种角色Leader和Follwer,5台服务器连通在一起,客户端又分别连在不同的ZK服务器上。
如果当数据通过客户端1,在左边第一台Follower服务器上做了一次数据变更,它会把这个数据的变化同步到其他所有的服务器,同步结束之后,那么其他的客户端都会获得这个数据的变化。
Zookeeper是一个由多个server组成的集群,一个leader,多个follower,每个server保存一份数据副本,全局数据一致、分布式读写,更新请求转发,由leader实施。
Leader主要有三个功能:
  1. 恢复数据;
  2. 维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
  3. 3Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理;
Follower主要有四个功能:
  1. Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
  2. 接收Leader消息并进行处理;
  3. 接收Client的请求,如果为写请求,发送给Leader进行投票;
  4. 返回Client结果;
zookeeper部署至hdfs集群的datanode节点,此案例共3台。
② 获取软件包
[root@localhost ~]#wget https://www-eu.apache.org/dist/zookeeper/zookeeper- 3.4.13/zookeeper-3.4.13.tar.gz

③ ​​​​​​​部署软件包

[root@localhost ~]#tar xf zookeeper-3.4.13.tar.gz -C /usr/local 
[root@localhost ~]#mv /usr/local/zookeeper-3.4.13 /usr/local/zookeeper 
[root@localhost ~]#mv /usr/local/zookeeper/conf/zoo.sample.cfg /usr/local/zookeeper/conf/zoo.cfg 
[root@localhost ~]#vim /usr/local/zookeeper/conf/zoo.cfg 
data=/opt/data 

server.1=hd4:2888:3888 
server.2=hd5:2888:3888 
server.3=hd6:2888:3888 

[root@localhost ~]#mkdir /opt/data 
[root@localhost ~]#echo 1 > /opt/data/myid

每台服务器myid不同,需要分别修改,例如server.1对应的myid内容为1,server.2对应的myid内容为2,server.3对应的myid为3。

2888端口:follower连接到leader机器的端口。

3888端口:leader选举端口。

④ 添加环境变量
[root@localhost ~]#vim /etc/profile.d/hadoop.sh 
export JAVA_HOME=/usr/local/jdk 
export ZOOKEEPER_HOME=/usr/local/zookeeper 
export PATH=${JAVA_HOME}/bin:${ZOOKEEPER_HOME}/bin:$PATH 
[root@localhost ~]# source /etc/profile
在3台datanode节点上全部添加。
⑤ 验证zookeeper
[root@localhost ~]#zkServer.sh start 
[root@localhost ~]#zkServer.sh status
需要把以上文件拷贝至3台datanode,然后全部执行开启命令。
[root@localhost ~]#zkServer.sh stop

7)hadoop软件包获取

[root@localhost ~]#wget http://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.8.5/hadoop- 2.8.5.tar.gz 
[root@localhost ~]#tar xf hadoop-2.8.5.tar.gz -C /opt
8 )完全分布式( HA )配置文件修改
① hadoop-env.sh
[root@localhost ~]#vim hadoop-env.sh 
export JAVA_HOME=/usr/local/jdk
修改hadoop-env.sh 25行,mapred-env.sh 16行,yarn-env.sh 23行,针对hadoop-2.8.5版本。
② core-site.xml
[root@localhost ~]#vim core-site.xml 

<!-- 指定hdfs的nameservice为ns1 --> 
<property> 
    <name>fs.defaultFS</name> 
    <value>hdfs://ns1</value> 
</property> 

<!-- 指定hadoop临时目录 -->
<property> 
    <name>hadoop.tmp.dir</name> 
    <value>/opt/data/tmp</value> 
</property> 

<!-- 指定zookeeper地址 --> 
<property> 
    <name>ha.zookeeper.quorum</name> 
    <value>hd4:2181,hd5:2181,hd6:2181</value> 
</property>

③ hdfs-site.xml

[root@localhost ~]#vim hdfs-site.xml 

<!--指定hdfs的nameservice为ns1,需要和core-site.xml中的保持一致 --> 
<property> 
    <name>dfs.nameservices</name> 
    <value>ns1</value> 
</property> 

<!-- ns1下面有两个NameNode,分别是nn1,nn2 --> 
<property> 
    <name>dfs.ha.namenodes.ns1</name> 
    <value>nn1,nn2</value> 
</property> 

<!-- nn1的RPC通信地址 --> 
<property> 
    <name>dfs.namenode.rpc-address.ns1.nn1</name> 
    <value>hd1:9000</value> 
</property> 

<!-- nn1的http通信地址 --> 
<property> 
    <name>dfs.namenode.http-address.ns1.nn1</name> 
    <value>hd1:50070</value> 
</property> 

<!-- nn2的RPC通信地址 --> 
<property> 
    <name>dfs.namenode.rpc-address.ns1.nn2</name> 
    <value>hd2:9000</value> 
</property> 

<!-- nn2的http通信地址 --> 
<property> 
    <name>dfs.namenode.http-address.ns1.nn2</name> 
    <value>hd2:50070</value> 
</property>

<!-- 指定NameNode的元数据在JournalNode上的存放位置 --> 
<property> 
    <name>dfs.namenode.shared.edits.dir</name>     <value>qjournal://hd4:8485;hd5:8485;hd6:8485/ns1</value> 
</property> 

<!-- 指定JournalNode在本地磁盘存放数据的位置 --> 
<property> 
    <name>dfs.journalnode.edits.dir</name> 
    <value>/opt/data/journal</value> 
</property> 

<!-- 开启NameNode失败自动切换 --> 
<property> 
    <name>dfs.ha.automatic-failover.enabled</name> 
    <value>true</value> 
</property> 

<!-- 配置失败自动切换实现方式 --> 
<property> 
    <name>dfs.client.failover.proxy.provider.ns1</name>         
   <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</valu e>
</property> 

<!-- 配置隔离机制 --> 
<property> 
    <name>dfs.ha.fencing.methods</name> 
    <value>sshfence</value> 
</property> 

<!-- 使用隔离机制时需要ssh免登陆 --> 
<property> 
    <name>dfs.ha.fencing.ssh.private-key-files</name> 
    <value>/root/.ssh/id_rsa</value> 
</property>

④ 配置datanode节点记录文件 slaves

[root@localhost ~]#vim slaves 
hd4 
hd5 
hd6

⑤ mapred-site.xml

[root@localhost ~]#cp /opt/hadoop285/etc/hadoop/mapred-site.xml.template /opt/hadoop285/etc/hadoop/mapred-site.xml 

[root@localhost ~]#vim mapred-site.xml 

<!-- 指定mr框架为yarn方式 --> 
<property> 
    <name>mapreduce.framework.name</name> 
    <value>yarn</value> 
</property>

⑥ ​​​​​​​yarn-site.xml

[root@localhost ~]#vim yarn-site.xml 

<!-- 指定resourcemanager地址 --> 
<property> 
    <name>yarn.resourcemanager.hostname</name> 
    <value>hd3</value> 
</property> 

<!-- 指定nodemanager启动时加载server的方式为shuffle server --> 
<property> 
    <name>yarn.nodemanager.aux-services</name> 
    <value>mapreduce_shuffle</value> 
</property>

9)复制修改后的hadoop目录到所有集群节点

[root@localhost ~]#scp -r hadoop hdX:/opt 
[root@localhost ~]#scp /etc/profile.d/hadoop.sh hdX:/etc/profile.d/ 
[root@localhost ~]#source /etc/profile
10) datanode 节点 (3 ) 启动 zookeeper
[root@localhost ~]#zkServer.sh start
11) 启动 journalnode( namenode 上操作,例如 hd1)
[root@localhost ~]#hadoop-daemons.sh start journalnode 
分别到 hd4 hd5 hd6 节点上进行验证:
[root@localhost ~]#jps
12) 格式化 hdfs 文件系统(在 namenode 上操作,例如 hd1
[root@localhost ~]#hdfs namenode -format

格式化完成后,请把/opt/data/tmp目录拷贝至hd2相应的位置,hd2将不再需要格式化,可以直接使用。

13 )格式化 zk namenode 上操作,例如 hd1
[root@localhost ~]#hdfs zkfc -formatZK
14) 启动 hdfs namenode 上操作,例如 hd1
[root@localhost ~]#start-dfs.sh
15 )启动 yarn namenode 上操作,例如想让 hd2 成为 resourcemanager ,需要在 hd2
启动)
[root@localhost ~]#start-yarn.sh

16)访问

NameNode1: http://hd1:50070 查看 NameNode 状态。
NameNode2: http://hd2:50070 查看 NameNode 状态。
NameNode3: http://hd3:8088 查看 yarn 状态。

十一、Ambari自动部署Hadoop

1、Ambari介绍

Apache Ambari项目旨在通过开发用于配置,管理和监控Apache Hadoop集群的软件来简化Hadoop管理。Ambari提供了一个由RESTful API支持的直观,易用的Hadoop管理Web UI。
Ambari使系统管理员能够:
  • 提供Hadoop集群
1. Ambari提供了跨任意数量的主机安装 Hadoop 服务的分步向导。
[root@localhost ~]#hdfs zkfc -formatZK
[root@localhost ~]#start-dfs.sh
[root@localhost ~]#start-yarn.sh

2. Ambari处理群集的Hadoop服务配置。

  • 管理Hadoop集群
Ambari 提供集中管理,用于在整个集群中启动,停止和重新配置 Hadoop 服务。
  • 监控Hadoop集群
Ambari 提供了一个仪表板,用于监控 Hadoop 集群的运行状况和状态。
Ambari 利用 Ambari 指标系统 进行指标收集。
Ambari 利用 Ambari Alert Framework 进行系统警报,并在需要您注意时通知您(例如,节点出现故障, 剩余磁盘空间不足等)。
  • Ambari使应用程序开发人员和系统集成商
能够使用 Ambari REST API 轻松将 Hadoop 配置,管理和监控功能集成到自己的应用 程序中

2、Ambari部署

Ambari本身也是一个分布式架构软件,主要由两部分组成:Ambari Server和Ambari Agent。用户通过Ambari Server通知Ambari Agent安装对应的软件,Agent会定时发送各个机器每个软件模块的状态给Server,最终这些状态信息会呈现给Ambari的GUI,方便用户了解到集群中各组件状态,做出相应的维护策略。
Ambari部署介绍:
https://docs.hortonworks.com/HDPDocuments/Ambari-2.6.1.5/bk_ambari-installation/content/hdp_26_repositories.html
1)环境准备
硬件环境:
6台Centos7.5; 
1台做Ambari Server;
5台做Ambari Agent[即可部署hadoop集群];
静态 IP 地址配置及集群主机之间多机互信:
[root@ambariserver ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 

TYPE="Ethernet" 

BOOTPROTO="static" 

NAME="eth0" 

DEVICE="eth0" 
ONBOOT="yes" 
IPADDR="192.168.122.X" #各主机IP地址自行规划 
PREFIX="24" 
GATEWAY="192.168.122.1" 
DNS1="119.29.29.29"
[root@localhost ~]#ssh-keygen -t rsa -f /root/.ssh/id_rsa -P '' 
[root@localhost ~]#cd /root/.ssh 
[root@localhost ~]#cp id_rsa.pub authorized_keys 
[root@localhost ~]#scp -r /root/.ssh 192.168.208.x:/root
集群主机名定义:
[root@localhost ~]#vim /etc/hosts 

192.168.122.10 ambariserver.a.com ambariserver 
192.168.122.20 hd1.a.com hd1 
192.168.122.30 hd2.a.com hd2 
192.168.122.40 hd3.a.com hd3 
192.168.122.50 hd4.a.com hd4 
192.168.122.60 hd5.a.com hd5
完全合格域名格式。
添加 JDK:
[root@localhost ~]#tar xf jdk-8u91-linux-x64.tar.gz -C /usr/local 
[root@localhost ~]#mv /usr/local/jdk1.8_91 /usr/local/jdk
安装 mariadb:
[root@localhost ~]#yum -y install mariadb mariadb-server 
[root@localhost ~]#systemctl start mariadb 
[root@localhost ~]#systemctl enable mariadb 
[root@localhost ~]#mysqladmin -uroot password "abc123"
[root@localhost ~]#mysql -uroot -pabc123 
>create database ambari character set utf8; 
> grant all on ambari.* to 'ambari'@'%' identified by 'abc123'; 
> grant all on ambari.* to 'ambari'@'ambariserver.a.com' identified by 'abc123'; 
> grant all on ambari.* to 'ambari'@'ambariserver' identified by 'abc123';
数据库访问授权要指定访问主机,例如 ambariserver ,不然可能会导致 ambari-server start 失败。
grant all on . to 'root'@'ambari.a.com' identified by "abc123"; 
create database ambari character set utf8; 
create user 'ambari'@'%' identified by "abc123456"; 
grant all on . to 'ambari'@'%'; 
update mysql.user set password=password('abc123456') where user='ambari';
验证:
[root@localhost ~]# mysql -h ambariserver.a.com -uambari -pabc123
安装数据库连接工具:
[root@localhost ~]#yum -y install mysql-connector-java
安装 httpd
[root@localhost ~]# yum -y install httpd 
[root@localhost ~]# systemctl enable httpd
解决已获取软件资源至 /var/www/html /var/www/html:
[root@localhost ~]#tar xf ambari-2.6.1.0-centos7.tar.gz -C /var/www/html/ 
[root@localhost ~]#tar xf HDP-2.6.4.0-centos7-rpm.tar.gz -C /var/www/html 
[root@localhost ~]#tar xf HDP-UTILS-1.1.0.22-centos7.tar.gz -C /var/www/html 
[root@localhost ~]#tar xf HDP-GPL-2.6.4.0-centos7-rpm.tar.gz -C /var/www/html
. 配置本地 YUM
  • ambari
[root@localhost ~]# vim /etc/yum.repos.d/ambari.repo 
[ambari-2.6.1.5] 
name=ambari Version - ambari-2.6.1.5 
baseurl=http://<web-server-ip> or FQDN /ambari/centos7/2.6.1.5-3 
gpgcheck=1 
gpgkey=http://<web-server-ip> or FQDN /ambari/centos7/2.6.1.5-3/RPM-GPG-KEY/RPM-GPG- KEY-Jenkins 
enabled=1 
priority=1
  • hdp
[root@localhost ~]# vim /etc/yum.repos.d/ambari.repo 

#VERSION_NUMBER=2.6.4.0-91 
[HDP-2.6.4.0] 
name=HDP Version - HDP-2.6.4.0 
baseurl=http://<web-server-ip> or FQDN /HDP/centos7/2.6.4.0-91 
gpgcheck=1 
gpgkey=http://<web-server-ip> or FQDN /HDP/centos7/2.6.4.0-91/RPM-GPG-KEY/RPM-GPG-KEY- Jenkins 
enabled=1 
priority=1 

[HDP-UTILS-1.1.0.22] 
name=HDP-UTILS Version - HDP-UTILS-1.1.0.22 
baseurl=http://<web-server-ip> or FQDN /HDP-UTILS/centos7/1.1.0.22 
gpgcheck=1 
gpgkey=http://<web-server-ip> or FQDN /HDP/centos7/2.6.4.0-91/RPM-GPG-KEY/RPM-GPG-KEY- Jenkins 
enabled=1 
priority=1 

[HDP-GPL-2.6.4.0] 
name=HDP-GPL Version - HDP-GPL-2.6.4.0 
baseurl=http://<web-server-ip> or FQDN /HDP-GPL/centos7/2.6.4.0-91 
gpgcheck=1 
gpgkey=http://<web-server-ip> or FQDN /HDP-GPL/centos7/2.6.4.0-91/RPM-GPG-KEY/RPM-GPG- KEY-Jenkins 
enabled=1 
priority=1
Linux 内核参数修改:
[root@localhost ~]#ulimit -Sn 软限制 

[root@localhost ~]#ulimit -Hn 硬限制 

[root@localhost ~]#vim /etc/security/limits.conf 
* soft nofile 10240 
* hard nofile 20480

2)部署Ambari Server

[root@localhost ~]#yum -y intsall ambari-server

3)初始化Ambari Server

初始化前导入数据库:
[root@localhost ~]#mysql -h ambariserver.a.com -uambari -pabc123 
>use ambari; 
>source /var/lib/ambari-server/resources/Ambari-DDL-MySQL-CREATE.sql; 
>show tables;

Ambari Server初始化:

[root@localhost ~]#ambari-server setup 

Customize user account for ambari-server daemon [y/n] (n)?y 
Enter user account for ambari-server daemon (root):root 
Do you want to change Oracle JDK [y/n] (n)? y 
[1] Oracle JDK 1.8 + Java Cryptography Extension (JCE) Policy Files 8 
[2] Oracle JDK 1.7 + Java Cryptography Extension (JCE) Policy Files 7 
[3] Custom JDK ============================================================================== 
Enter choice (1): 3 
Path to JAVA_HOME: /usr/local/jdk 
Enable Ambari Server to download and install GPL Licensed LZO packages [y/n] (n)? n 
Enter advanced database configuration [y/n] (n)? y Configuring database... ============================================================================== 
Choose one of the following options: 
[1] - PostgreSQL (Embedded) 
[2] - Oracle 
[3] - MySQL / MariaDB 
[4] - PostgreSQL 
[5] - Microsoft SQL Server (Tech Preview) 
[6] - SQL Anywhere 
[7] - BDB 
============================================================================== 
Enter choice (3): 3 
Hostname (localhost): ambari.a.com

Port (3306):3306 
Database name (ambari):ambari 
Username (ambari): ambari 
Enter Database Password :abc123456 
WARNING: Before starting Ambari Server, you must run the following DDL against the database to create the schema: /var/lib/ambari-server/resources/Ambari-DDL-MySQL- CREATE.sql 
Proceed with configuring remote database connection properties [y/n] (y)?y

4)启动Ambari Server

[root@localhost ~]#ambari-server start 
[root@localhost ~]#/sbin/chkconfig ambari-server on

出现ERROR时,如果退出码状态为非0或0,并报告没有8080端口启动,请稍等待片刻。

5)访问Ambari Server服务器
http://ambari.a.com:8080 登录用户名和密码均为: admin
6)Ambari Agent 部署
Agent 主动汇报所在节点状态情况。

部署JDK

[root@localhost ~]#for i in hd{1..5};do scp -r /usr/local/jdk $i:/usr/local;done 
Ambari Server 上拷贝到各 Agent 主机
部署 YUM 源:
[root@localhost ~]#for i in hd{1..5};do scp -r /etc/yum.repos.d/ambari.repo /etc/yum.repos.d/hdp.repo $i:/etc/yum.repos.d;done
Ambari Server 上拷贝到各 Agent 主机。
部署 Ambari Agent
[root@localhost ~]#yum -y install ambari-agent 
[root@localhost ~]#systemctl start ambari-agent 
[root@localhost ~]#/sbin/chkconfig ambari-agent on

报错解决方法:

提示:

Connecting to https://amabri_server_host:8440/ca ERROR
解决方法如下:
[root@localhost ~]#rpm -qa | grep openssl
openssl-1.0.2k-12.el7.x86_64 openssl-libs-1.0.2k-12.el7.x86_64

[root@localhost ~]# vi /etc/python/cert-verification.cfg
[https]
verify=disable #修改

[root@localhost ~]#vim /etc/ambari-agent/conf/ambari-agent.ini
[security]
force_https_protocol=PROTOCOL_TLSv1_2 #添加一行

[root@localhost ~]#ambari-agent restart
yum -y install libtirpc-devel #centos7.6 中要安装。
以上问题处理需要在所有 Ambari-agent 主机上操作。
7)Ambari Server Web端操作

 

 

 

 

 

 

 

部署完成。 

十二、Hadoop监控

十三、验证Hadoop集群可用性

在任意一台已安装 client 服务器上均可做如下操作:
[root@hd2 ~]# su - hdfs 
[hdfs@hd2 ~]$ vim test.txt 
tom 
ken 
192.168.1.1 

[hdfs@hd2 ~]$ hdfs dfs -ls / 
[hdfs@hd2 ~]$ hdfs dfs -mkdir /input 
[hdfs@hd2 ~]$ hdfs dfs -put test.txt /input 
[hdfs@hd2 ~]$ hadoop jar /usr/hdp/3.1.0.0-78/hadoop-mapreduce/hadoop-mapreduce- examples.jar wordcount /input /output 
[root@hd2 ~]# hdfs dfs -cat /output/part-r-00000 
192.168.1.1 1 
ken 1 
tom 1

相关文章:

  • 33.0、C语言——C语言预处理(1) - 翻译环境详解
  • java-php-python-springboot网上订餐系统计算机毕业设计
  • 【VUE项目实战】66、上线-通过node创建Web服务器
  • About 9.25 This Week
  • 三、基本命令
  • MySQL中select ... for update会锁表还是锁行?
  • 计算机毕业设计选题 SSM大学生企业推荐系统(含源码+论文)
  • 【Java设计模式 思想原则重构】设计思想、设计原则、重构总结
  • js逆向-逆向基础
  • 【前端】【探究】HTML - input类型为file时如何实现自定义文本以更好的美化
  • 二叉树的dp问题和Morris遍历
  • 重新认识IO以及五种IO模型(理论认识)
  • leetcode: 647. 回文子串
  • SQL语言概述与SQL语言的数据定义
  • NIO知识总结三
  • 【笔记】你不知道的JS读书笔记——Promise
  • HTTP中的ETag在移动客户端的应用
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • ViewService——一种保证客户端与服务端同步的方法
  • vue中实现单选
  • vue总结
  • Web Storage相关
  • WePY 在小程序性能调优上做出的探究
  • yii2权限控制rbac之rule详细讲解
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 回顾2016
  • 利用jquery编写加法运算验证码
  • 前端_面试
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 数组大概知多少
  • 王永庆:技术创新改变教育未来
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 译自由幺半群
  • 用简单代码看卷积组块发展
  • FaaS 的简单实践
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • $.each()与$(selector).each()
  • ( 10 )MySQL中的外键
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (搬运以学习)flask 上下文的实现
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (转载)(官方)UE4--图像编程----着色器开发
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET Core Web APi类库如何内嵌运行?
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET 事件模型教程(二)
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .Net中的设计模式——Factory Method模式
  • .so文件(linux系统)