网站采用商家入驻的模式,商家入驻平台提交申请,由平台进行资质审核;审核通过后,商家拥有独立的管理后台录入商品信息,商品经过平台审核后即可发布。
大多电商平台由三部分组成:
网站前台通常由这几部分构成:
运营商后台是运营商的运营人员管理的后台。主要包括商家审核、品牌管理、规格管理、模板管理、商品分类管理、商品审核、广告类型管理、广告管理、订单管理、商家结算等。
入驻的商家进行管理的后台,主要功能是对商品的管理以及订单查询统计、资金结算等功能。
对于企业和行业应用来说,经常会遇到各种数据的处理、迁移,掌握一种etl工具的使用必不可少。kettle现命名为PDI,但习惯上仍称为kettle。
环境要求:安装、配置好JDK
1.下载kettle(版本为pdi-ce-8.2.0.0-342)
2.解压kettle
关于
active.hadoop.configuration=cdh514
的问题: cdh514和hdp几几几不是随意写的,而是看我们自身使用的是那种版本的Hadoop(CDH/Hadoop普通的发行版本),当我们确定了使用的Hadoop的“类型”,我们再去看版本号,在自身kettle提供的几种版本中选择正确类型的且版本号大于等于当前使用的Hadoop的版本号的。
例:kettle版本为8.2 Hadoop版本为hadoop2.7.2 而kettle8.2提供的几个对于cdh/hadoop的支持为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IMIMCYxT-1685508533931)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230130083746206.png)]
我们应该选择大于等于当前版本号最接近的,所以选择hadp30。在没有完全相同的版本时:选择高版本向后兼容是我们的选择依据。
顾名思义:使用Hadoop input作为kettle转化的输入,以其他形式输出。
ps:在操作Hadoop input时,首先配置的是Hadoop input,在获取字段时会有一个弹窗(类似于让你选择获取100条数据,这时候一定要选择ok,而不是直接叉掉),ok后在配置输出时才能正常获取到字段。(弹窗不点ok的话,输入项配置是可与获取到字段的,但是输出项是无法获取到字段的,转换生成的数据文件也是空的)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zz5WJz1Q-1685508533932)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230201162114703.png)]
ps:
/opt/module/hadoop-2.7.2/share/hadoop/common
下的hadoop-common-2.7.2.jar
拷贝。(在common目录下由两个相似名字的jar包,拷贝那个不带test的那个jar包) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f8Doxnsz-1685508533933)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230201165314940.png)]
HiveServer2 / beeline
本人安装的kettle版本是pdi-ce-8.2.0.0-342
,是黑马程序员老师分享的kettle的安装包。本人Hadoop集群中的hive版本是1.2,在将hive-site.xml文件以及hadoop-common....jar
文件都放入指定的文件目录后,在重启kettle测试连接hive后,报错connection confused(连接拒绝),经查阅各位大佬分享的文章以及检查自己的错误后,检查出如下两点需要纠正的地方:
1.开启服务端hive的hiveserver2服务
这个服务是hive提供给第三方软件的连接服务,第三方软件连接的应该是hiveserver2
①[....hive]$ bin/hiveserver2
②[...hive]$ bin/beeline
③beeline> !connect jdbc:hive2://hadoop303:10000
④输入进入hive的用户名和密码,进入hive
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o2ZpCKBF-1685508533933)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230202161540450.png)]
到这里hive服务端需要做的已经全部做完了。
2.将hive的lib目录下的hive-开头的配置文件复制到data-integration/lib以及D:\Download\data-integration\plugins\pentaho-big-data-plugin\hadoop-configurations\hdp30\lib
两个目录下
再次重启kettle后测试连接hive后成功(访问hive的端口号为10000端口)
在使用kettle向hive导入数据并新增加分区时,kettle任务执行成功但是hive表中没有数据,可以使用下面的语句在hive的对应库下修复对应表的分区。
msck repair table databasename.tablename;
动态分区的必要性: 基于查询参数的位置去推断分区的名称,从而建立分区。
通常向hive的分区表insert数据时,会指定插入数据的目标分区,那么此时的分区成为静态分区;
insert overwrite table xxx partition(dt='ddd');
在insert时不指定目标分区,那么会默认select的最后一个字段的值作为分区的名称,即为动态分区,原表中没有当前分区会自动创建分区。
#开启动态分区,默认是false
#开启允许所有分区都是动态的,否则必须要有静态分区才能使用
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
-- c的值作为动态分区的字段值--分区名称
-- 表xxx为仅有一级分区的表(包含二级分区的表的sql应随之改变)
-- 表xxx所包含的字段个数应与被查询表的字段数目相同
insert overwrite table xxx
select a, b, c from vvv;
如果在执行insert overwrite使用动态分区报错,应即使调整修改相应的动态分区配置参数:
① Error: GC overhead limit exceeded
② Fatal error occurred when node tried to create too many dynamic partitions.
解决办法有两种:
-- 默认的最大分区数量值为100;必要的时候可以适量增大
set hive.exec.max.dynamic.partitions.pernode=1000;
Ⅰ.扩大动态分区数量,这样会导致有很多小文件,不利于系统维护
Ⅱ.修改脚本,尽量不要使用动态分区
ps:本次的错误有两个,第一个是reduce为0,第二个是产生了200+的动态分区
-- 开启动态分区,默认值为false
set hive.exec.dynamic.partition=true;
-- 设置动态分区为非严格模式;(严格模式下将不允许使用笛卡儿积 、union all等)
set hive.exec.dynamic.partition.mode=nonstrict;
-- 启动自动排序参数,强制产生reduce任务
set hive.optimize.sort.dynamic.partition =true;
-- 由于产生的动态分区数量大于默认值100,增加最大分区数量
set hive.exec.max.dynamic.partitions.pernode=1000;
-- 下面4个是纯享版
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.optimize.sort.dynamic.partition =true;
set hive.exec.max.dynamic.partitions.pernode=1000;
原因是:
set dfs.namenode.fs-limits.max-component-length=448;
set mapreduce.job.name=dimshops;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBFjHUuw-1685508533934)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230227083634080.png)]
2.spark是有问题的,值为null
在执行insert overwrite时,发现插入表的数据值为null。
但是同样的sql在hive执行却没有这样的问题。
之前在spark的conf目录改了properties文件,改为了WARN
13123132.究其原因,还是找到的线程代码的问题没有找到
在启动kylin时,提示找不到spark/bin/jars。这个问题时由于配置Spark的环境变量时出现马虎导致Kylin去错误的路径找了$SPARK_HOME/jars
安装任何如Hadoop,hive,Hbase等时,在/etc/profile中 export XXX_HOME=/opt/module/SoftwareName,配置完成之后首先source /etc/profile ,然后可以在控制台输入 echo $XXX_HOME来验证环境变量配置成功。
(释放内存,为即将或正在运行的进程腾出更多的资源)
# 查看系统内存使用情况
free -m
# 清理内存
echo 1 >/proc/sys/vm/drop_caches
# 在自己的机器上试过,然并卵
窗口函数必须跟在聚合函数后面—聚合函数统计的行是根据窗口函数指定的大小进行统计的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FYvHfRSm-1685508533934)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230304231421781.png)]
没加
修复分区的使用场景:
使用kettle进行数据的转移,如使用kettle从MySQL向hive的分区表抽取数据。通常来说是在kettle的作业过程中创建分区(分区文件夹),在分区中写入数据。------这个时候是硬创建分区,并不是通过hive的HQL语句主动创建的分区,所以即便使用kettle创建了分区并在分区目录写入了数据,但此时hive并不能识别该分区及分区内的数据。此时需要在hive的客户端修复以下该分区。
-- msck talbe tablename
msck table weblog_origin;
-- 如果上述操作执行完成,但依然查询不到指定数据,且客户端并无报错提示信息,需使用如下命令
-- msck repair talbe tablename
msck repair talbe weblog_origin;
-- 原理相当简单,执行后,Hive会检测如果HDFS目录下存在但表的metastore中不存在的partition元信息,更新到metastore中。
create table weblog_origin (
id int,
name string)
partition by (dt string)
-- row format delimited 分隔符
-- fields terminated by '\t' -- 字段分隔为\t,表示一个字段为一个制表位
row format delimited fields terminited by '/t'
-- STORED AS就是表中的存储格式
-- 如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
-- TBLPROPERTIES是表的一些属性,HIVE内置了一部分属性,使用者也可以在创建表时进行自定义;
STORED AS PARQUET TBLPROPERTIES('parquet.compression'='SNAPPY');
这里需要注意的一个点:在代码处理数据文件、并保存到hive分区的parquet类型文件时,一定注意,写入parquet文件的数据类型一定要与hive能对应的上,如果parquet中的某个字段的类型与hive建表时该字段的类型对应不上,那么将会出现查询不出数据的这么一种情况,如:
Cannot inspect org.[apache](https://so.csdn.net/so/search?q=apache&spm=1001.2101.3001.7020).hadoop.io.LongWritable
-- 这个是因为hive中没有long类型,而parquet的schema中的字段类型是long,在hive中是bigint
。如果出现了查询不出hive中parquet文件中的数据,应做如下处理:
package ServiceToWareHouse
import org.apache.spark.sql.SparkSession
import org.apache.spark.SparkConf
/*
* 1.当前文件是使用Spark的方式读取parquet文件内容
* */
object SparkReadParquet {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder
.appName(this.getClass.getSimpleName)
.master("local[*]")
.getOrCreate()
// spark读取parquet文件
val dz = spark.read.parquet("/user/hive/warehouse/itcast_ods.db/click_pageviews/dt=20191101/part-00000-48464ca9-871f-4ef3-866a-08360109f4be.snappy.parquet")
// 展示读取到文件的20行
dz.show(20)
// 打印出读取的parquet文件的schema信息,字段名以及字段类型
dz.printSchema()
val df = spark.read.parquet("/user/hive/warehouse/itcast_ods.db/click_stream_visit/dt=20191101/part-00000-78ce327c-3924-41b2-97ee-b822a42a34dd.snappy.parquet")
df.show(20)
df.printSchema()
// 在网上的资料中可以实现spark将parquet文件的字段类型进行修改,但是本人并未实现,由于石油.cast时没有找到对应方法
// df=df.withColumn(‘business_mobile’, df[‘business_mobile’].cast(“string”))
// import org.apache.spark.sql.functions._
// df.withColumn("page_staylong",col("page_staylong").cast("string"))
// Thread.sleep(10000000) --->这部分对于查看Spark任务的UI页面中任务的执行情况很有帮助,如果不设置这一句,在Spark任务执行完后Spark的UI页面会自动断开连接,导致无法查看任务执行情况
Thread.sleep(10000000)
}
}
cast函数用于将一种数据类型转换为另一种数据类型,用法为 cast (col_name as Type)
Unable to get value 'BigNumber(16)' from database resultset, index 0
需要用 cast对字段进行转换,将bigint转换成string。
SELECT
cast(id as string)
, cast(is_deleted as boolean) -- 若无报错,则无需转换数据类型
, createtime
, company_name
, cast(last_modified_time as string)
FROM hive.t_test
limit 1000
flume1.7版本是一个分水岭,在1.7以前的版本,flume不支持taildirsource这种source类型及不能实现断点续传。那么TailDirSource这种source类型,会动态的监听这个文件夹及文件夹下每一子文件的变化;同样重要的在1.7以前的版本是不支持断点续传的,在1.7及之后的版本,即便在flume传输的过程中出现了断电的问题,flume本身会在一个json文件中记录文件传输的过程—即偏移量,如果在传输过程中突然断电或者服务区宕机,我们只需要在开机后重新启动flume程序,那么flume程序会自动接着上次采集的位置进行采集-----由此实现断电续传。
# Describe/configure the source
# 这里是设置source的类型为TAILDIR
a1.sources.r1.type = TAILDIR
# 这里是设置用于存放偏移量(断点续传)的json文件的位置,如果不设置会存放到默认的位置
a1.sources.r1.positionFile = /var/log/flume/taildir_position.json
[rose@Hadoop303 flume]$ bin/flume-ng agent --conf-file job/flume-TailDirSrc-hdfssink.conf -name a1 -Dflume.root.logger=INFO,console
执行完上述的命令后,控制台并未打印creating /…tmp文件,在hdfs文件系统上也并未有相应的文件夹创建。
原因:默认情况下当脚本和配置文件在hdfs的根目录创建文件夹时(未切换到root用户时),需要使用root用户权限才可以创建。
且为保证断点续传,需要在启动agent前在对应位置创建好.json文件,这样position位置才能正常的保存到json文件中。
PS:在使用su -root 时,提示无效选项,这时候就不用使用su -root这种方式了,而是直接使用su,su回车后会提示你输入root用户密码 (在由root用户切换到普通用户时,使用su user即可)【su robot(从普通用户切换到root后再切换到普通用户)】
目前来看的话呢,这个json文件如果每次使用都用同一个文件名,那么这个json文件在每次运行之前都清空,否则任务将执行失败
declare final
在不考虑自定义分区器的情况下,通常Spark中RDD的分区器有HashPartitioner和RangePartitioner两种。两种分区器都是针对于key-value类型的RDD。
HashPartitioner: 根据key的Hash值与分区数取模,根据取模后的值存入对应分区。从HashPartitioner分区的实现原理可以看出,其结果可能导致每个分区中数据量的不均匀。
RangePartitioner:从HashPartitioner的原理中我们能发现两个问题,首先:在不考虑存在重复key的情况下,会出现每个分区中的数据不均匀。而另一种情况:当RDD中存在key相同的数据,如果有大量数据有一个相同的key,那么这些相同的key的数据会落在同一个分区中,在数据的分析计算中会导致数据倾斜,从而影响计算分析。
这种情况下,使用rangpartitioner成为了解决这类问题的比较好的选择,rangparitioner在鱼塘抽样后计算出原始分区中每个分区数据的权重,原始分区中的数据都是根据key值大小升序排序的。计算出所有分区中每条数据权重的和,用权重和除以预分区的数量a,得出一个整数值n。通过累加原始第一个分区中的权重值,当权重值的和小于等于n时,得出预分区的第一个分区的最大key的值;再由第一条数据继续累加权重值,当权重值的和≤2n时,得到预分区的第二个分区的最大key值,以此类推可以计算出每个预分区中最大key的值,从而可以讲不通key值的数据存入不通的分区中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0askfoX2-1685508533934)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230309231118134.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u3dMTetv-1685508533935)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230309231152237.png)]
启动Spark程序,让程序一直运行,until当在Spark的UI页面发现有一个Task卡住。
(ps: 判断任务是不是属于卡住的状态,根据任务的Duration,这个时间一直在增加,但是后面的任务过程却一直没有进行,这基本就可以判断任务属于卡死了。而卡死的原因是不唯一的,而较多的可能是锁或者死循环的原因导致,具体原因还是要仔细排查)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DlwfZk7-1685508533935)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230314113537594.png)]
使用cmd或者git bash,输入 jps -ml 查看正在运行的Java进程以及main class信息。通过main class信息找到我们的目标进程pid。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zz2Yxm2y-1685508533936)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230314114242203.png)]
ps : 这里使用 pslist 也可以查看正在运行的进程,不过会显示出当前主机运行的所有进程而不只是Java进程。
找到了对应的进程,我们要根据进程的pid去查看该进程中的线程信息,找到占用CPU最多的线程的Tid,注意该线程的Tid为十进制数字。
pslist -dmx PID
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6jfWSrAS-1685508533936)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230314114734906.png)]
将10进制的Tid转化为16进制,目的是方便对照。
在命令行中输入 jstack PID,将进程堆栈打印,并将16进制转换后的Tid在jstack文件中查询,定位到该线程。
定位到该线程后,在找到该线程的位置查看对应的Java日志信息,定位代码的问题。
在这台电脑的集群中,应使用如下配置跑Spark集群模式下的作业
com.itheima.main.ELTApp是跑的程序的类的主方法。可右键该class并copy refrence
bin/spark-submit \
--class com.itheima.main.ETLApp \
--conf spark.dynamicAllocation.enabled=false \
--driver-memory 800M \
--master spark://Hadoop303:7077 \
--executor-memory 800M \
--total-executor-cores 6 \
--num-executors 12 \
click_log_etl_16-1.0-SNAPSHOT.jar \
jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的Java进程ID、core file、远程调试服务的Java堆栈信息。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maFanRHO-1685508533936)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230324103011359.png)]
预采集的HDFS上的文件大小有200M多不到300M ,这样的情况下谁也不会想是自己电脑的资源不够导致的任务卡死。
首先实施锁的排查或者是说是排查死锁:
其实在Spark的UI页面,我们在excutor的程序详细信息中,我们就可以看到,正常如果是死锁的情况,那么必定有一个线程的状态是BLOCKED,但是我们在Spark的UI页面中没找到BLOCKED的线程,其实这里就已经证明了不是锁的问题了。但是,由于对于锁的不了解和自己的蠢,还是使用Jstack对锁进行了排查。
# 1. 使用jps查看正在运行的Java进程
> jps
12343 jps
22345 ithiema.AppTest.main
33333 laucher
# 2. 找到进行中与我们正在运行的程序名相同的进程的PID --->22345
> jstask -l PID
# 这时候控制台会打印出这个进程中的所有线程的状态以及它们的持有锁以及 等待锁的情况
# 排查后并未发现 有某个线程持有的锁 而另一个线程拥有这个锁的情况
# 这个时候就单纯的认为是RUNABLE这个状态的线程正在执行的代码出了问题,但是当前运行的代码是写入的代码,代码是没问题的
# 或者说这个代码不会影响到程序到卡死的状态
# 就总结到这吧,详细的还是见那个链接
最后就在我快羽化成仙的时候,我把原始数据的一半删掉了,原始数据共有17万行左右,我将数据只保留到8万行左右.然后代码不变重新跑了以下程序,您猜怎么着,嘿,那叫一个地道,踏马的程序运行成功了,由此总结为因系统资源不足导致程序出现卡死。
hadoop303:7070/kylin
需要启动Hadoop集群,zookeeper集群,Hbase集群,并启动hive的metastore服务以及hiveserver2服务,以及Yarn的history server。
# 启动Hadoop集群
# 相关进程有 namenode seconderynamenode datanode nodemanager
Hadoop304[opt/module/hadoop-2.7.2]$ sbin/start-dfs.sh
Hadoop305[opt/module/hadoop-2.7.2]$ sbin/start-yarn.sh
# 启动zk
# 相关进程 Qour...Mean
Hadoop304[opt/module/zookeeper]$ bin/zkServer.sh start
Hadoop305[opt/module/zookeeper]$ bin/zkServer.sh start
Hadoop306[opt/module/zookeeper]$ bin/zkServer.sh start
# 启动Hbase集群
# 相关进程 HregionServer HMaster
Hadoop304[opt/module/hbase]$ bin/start-hbase.sh
# 启动 metastore
Hadoop304[opt/module/hive/bin]$ nohup hive --service metastore &
# 启动 hiverserver2
Hadoop304[opt/module/hive/bin]$ nohup hive --service hiveserver2 &
# 启动Yarn history server
Hadoop304[opt/module/hadoop-2.7.2/sbin]$ mr-jobhistory-daemon.sh start historyserver
# 启动kylin
Hadoop304[opt/module/apache-kylin/bin]$./kylin.sh start
启动spark history server【可选】
kylin自身的组件只有两个,JobServer 和 QueryServer 。Kylin的JobServer 主要负责将数据源(hive, kafka)的数据通过计算引擎(Mapreduce,Spark)生成Cube存储到存储引擎(hbase)中;QueryServer主要负责SQL的解析,逻辑计划的生成和优化,向Hbase的多个Region发起请求,并对多个Region的结果进行汇总,生成最终的结果集。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E1OoQJYs-1685508533937)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230524194118001.png)]
ln是Linux中比较重要的一个命令,当我们需要在不同目录用到同一个文件时,我们不需要将同一个文件保存到不同的位置,只需要将目标文件保存在一个固定的目录即可,如果某个目录要用到这个文件,我们只需要在这个目录创建目标文件的链接即可,这个可以节省磁盘资源。ln的功能是为某一个文件在另外一个位置建立一个同步的链接。
用法:
# 如果是在当前目录,可以使用 ln -s /文件原路径 这样即可
# 使用ln -s即为创建软连接(Symbolic Link)、又称符号链接 --- 使用ln 即为创建硬链接(Hard Link)
# 当删除软链接的源文件时,会导致所有的软链接变为死链接;而当删除硬链接的源文件时,硬链接不受影响,当原始文件及所有硬链接被删除时,硬链接才会失效
# 无论软硬连接,文件都会同步变化
# 创建软连接
ln -s /文件全路径 /目标路径
# 显示软链接的link的路径
ls -l
# 注意!!! 很多时候创建完软链接后链接后面会有红色路径闪烁,这时候考虑两点: 1。原始文件已失效或被删除 2.使用文件完整路径创建链接(而不是使用变量,类似ln -s $SPARK_HOME/conf/spark-defaults.xml)-----原因不详
在build麒麟的cube时,cube的build非常慢,而且总会中断,从而ERROR。查看服务器上的服务运行情况,发现有个节点上的HMaster和kylin已经停掉了。这个时候也给知道了为什么cube构建出错的原因。通过查阅别人的分享,知道可能会因为HBase集群的各节点时间不同步导致单个节点的HMaster挂掉。检查后发现—还真是^^
启动ntpd服务,目的是让集群间的各个服务器的时间同步
# 切换到root用户
su root
# 查看ntpd服务的状态
service ntpd status
# 启动ntpd服务
service ntpd start
# chkconfig ntpd on ## 这个语句用来设置开机自启动,但是机器本身资源有限,就不这么设置了
在其他的从节点上,设置定时任务,通过定时任务定时同步宿主机的时间(下面的操作只是记录一下。做过一次之后就再也不用做了)
在所有的从节点:
是使用变量,类似ln -s $SPARK_HOME/conf/spark-defaults.xml)-----原因不详
## 开机必启动
> 在build麒麟的cube时,cube的build非常慢,而且总会中断,从而ERROR。查看服务器上的服务运行情况,发现有个节点上的HMaster和kylin已经停掉了。这个时候也给知道了为什么cube构建出错的原因。通过查阅别人的分享,知道可能会因为HBase集群的各节点时间不同步导致单个节点的HMaster挂掉。检查后发现---还真是^^
启动ntpd服务,目的是让集群间的各个服务器的时间同步
```shell
# 切换到root用户
su root
# 查看ntpd服务的状态
service ntpd status
# 启动ntpd服务
service ntpd start
# chkconfig ntpd on ## 这个语句用来设置开机自启动,但是机器本身资源有限,就不这么设置了
在其他的从节点上,设置定时任务,通过定时任务定时同步宿主机的时间(下面的操作只是记录一下。做过一次之后就再也不用做了)
在所有的从节点: