在聊心酸史之前,先铺垫一下问题的由来:
本来就是简单的使用简单操作文件到hdfs中,同样的代码别的同学都好使,而我的不行,代码如下:
#谨记: C:\Windows\System32\drivers\etc\hosts做ip映射,否则连接不上
from hdfs.client import Client
#关于python操作hdfs的API可以查看官网:
#https://hdfscli.readthedocs.io/en/latest/api.html
#读取hdfs文件内容,将每行存入数组返回
def read_hdfs_file(client,filename):
lines = []
with client.read(filename, encoding='utf-8', delimiter='\n') as reader:
for line in reader:
#pass
#print line.strip()
lines.append(line.strip())
return lines
#创建目录
def mkdirs(client,hdfs_path) :
client.makedirs(hdfs_path)
#删除hdfs文件
def delete_hdfs_file(client,hdfs_path):
client.delete(hdfs_path)
#上传文件到hdfs
def put_to_hdfs(client,local_path,hdfs_path):
client.upload(hdfs_path, local_path,cleanup=True)
#从hdfs获取文件到本地
def get_from_hdfs(client,hdfs_path,local_path):
download(hdfs_path, local_path, overwrite=False)
#追加数据到hdfs文件
def append_to_hdfs(client,hdfs_path,data):
client.write(hdfs_path, data,overwrite=False,append=True)
#覆盖数据写到hdfs文件
def write_to_hdfs(client,hdfs_path,data):
client.write(hdfs_path, data,overwrite=True,append=False)
#移动或者修改文件
def move_or_rename(client,hdfs_src_path, hdfs_dst_path):
client.rename(hdfs_src_path, hdfs_dst_path)
#返回目录下的文件
def list(client,hdfs_path):
return client.list(hdfs_path, status=False)
# root:连接的跟目录
client = Client("http://192.168.46.128:50070",root="/",timeout=5*1000,session=False)
put_to_hdfs(client,'s.csv','/') #注意这s.csv是你当前路径要有的文件
# append_to_hdfs(client,'/a.txt','111111111111111'+'\n')
# write_to_hdfs(client,'/a.txt','222222222222'+'\n')
# move_or_rename(client,'/b.txt', '/user/b.txt')
# mkdirs(client,'/input1/python1')
# print(list(client,'/input'))
# read_hdfs_file(client,'/hello/a.txt')
代码我可以保证没有一点点毛病,但是他就是报错:
HDFS报Failed to find datanode, suggest to check cluster health.
找不到datanode,建议检查cluster
然后我们回去输入命令:
start-all.sh
Jps
NameNode
NodeManager
SecondaryNameNode
ResourceManager
发现真的是没有Datanode
而且有些同学也出现了这样的问题,然后有些同学,
方式一通过先停止所有启动,然后再格式化namenode就可以了,代码如下:
stop-all.sh
hadoop namenode -format
然后我也试一下,然后并没有起到效果,它大舅还是它大舅,它二舅还是它二舅。
方式二有的同学在启动所有的状态下单独给datanode启动命令,代码如下:
hadoop-daemon.sh start datanode
他们好了,拥有了他们想要的,但是我还是我,不一样的烟火
方式三怎么办,茫茫人海中多看一眼解决不了,那就多看几眼,
然后我就综合前俩种方式,先停掉所有服务,然后再单独启动datanode,在启动所有,代码如下:
stop-all.sh
hadoop-daemon.sh start datanode
hadoop namenode-format
然后神奇的事情发生了,你想要datanode给你了,但却丢了namenode,就像上帝给了你一扇窗,就关掉了另一扇窗。
结果:
Jps
NodeManager
DataNode
SecondaryNameNode
ResourceManager
对于这种情况我只想说我不服,怎么办,革命的道路上慢慢尝试探索呗!
我把所有服务又都停了,然后单独把nodanode和namenode启动,代码如下:
hadoop-daemon.sh start datanode
hadoop-daemon.sh start namenode
然上帝给了你两扇窗,
结果:
NameNode
DataNode
此时美到是美,但是其他我也得一个一个的去启动,因为我也想到再启动所有,把剩余的再启动起来,可是你可以做,只是结果又回到了解放前,又没有了DataNode.难道我真的要一个个的去启动,这并不是我想要的。
那我们就来分析一下这个问题:
namenode和namenode也并不是撕破脸谁也见不得谁,它俩有同时存在的情况,那么说明它们并不互相排斥,因为单干自己的命令都好使,但是为什么执行所有就不能同时存在呢!仔细对比分析俩次命令,会发现一个是分开执行,一个是同时执行,分开执行,无所谓,井水不犯河水,各自渡船过河,但是同时执行,就不成了,俩人同坐一条船渡河就不行。问题大概找到了,可能是因为它们有一个共同的东西约束着它们,但是现在这个东西可能发生了改变,导致无法像以前一样友好。
那我们再获取看看那条报错,建议检查cluster,对于小白的我哪里知道上面叫cluster,检查个¥%#@
怎么办,—》百度
百度之后才发现确实datanode和namenode都有有一个cluterID
然后我去查看我耳朵cluterID,发现确实不一样。查看方法:
先cd到你的namenode和datanode的路径下,这个路径是你环境配置下时设定的如下:
编辑hdfs-site.xml文件
dfs.data.dir
/opt/bigData/dfs/data
true
dfs.name.dir
/opt/bigData/dfs/name
true
dfs.replication
1
dfs.secondary.http.address
master:50090
按我的路径就是从根目录开始cd /opt/bigData/dfs/data/current
到了这个路径下,你可以ls查看会找到一个VERSION的东西,然后你可以vim VERSION,看到一个clusterID的东西,同样的方法去查看name里的clusterID,发现我的俩个ID果然不一样,
clusterID=CID-c5751e32-15c0-4ef0-90a3-232ea8a0be43
clusterID=CID-c4546e12-23d2-5yy2-64v3-435gh5h2hj45
然后我更改了,name里的clusterID,让它和data里的clusterID保持一致,带着处理后的结果我去满怀希望的去进行最初使的操作,启动所有,然后jbs,查看,万水千山还是它,到此时,越到最后越不能慌,
分析一下
导致我clusterID不同的原因是因为,我格式化namenode了多次,导致了namenode的clusterID发生了改变,而我的datanode它并没有发生改变,因为,我并没有操作它,也就是说,datanode还是最初最初模样,而发生变化是最新状态namedata,所有我们要让他们都处于当下状态,那就格式化namenode,让它变成最新,然后去更改datanode,让datanode的clusterID也变成namenode的样子。
最后一次猜想实验
带着上述的分析,我stop-all.sh停止了所有,然后hadoop namenode-format格式化namenode,让它的clusterID变为最新,然后按前面讲的查询clusterID的方法找namenode的clusteID,得到它的值赋值给datanode的clusterID,然后保存。此时的心情无法描述,被它摧残的只剩下最后一丝希望。
按着这样的方法我做,做到了。成功了。
噔噔噔…
Jps
NameNode
NodeManager
DataNode
SecondaryNameNode
ResourceManager
然后再回到python的执行,就畅通无阻了。好开森。
总结:
在第一次启动namenode时需要格式化,但之后不要再去格式化,否则多次格式化之后,你就会入了我的坑。当然还有一种思路,我觉的可行,就是让所有都回到最初的模样,那就时删除,然后进行操作。也没试过,能爬出这个坑也就很不容易了。其他的不足希望多多指点,小白尽力了。