python操作hdfs

原文:https://www.cnblogs.com/Jims2016/p/8047914.html

可以使用python的hdfs庫(資料https://pypi.org/project/hdfs/),pip下載即可

# !coding:utf-8
import sys
from hdfs.client import Client



# 關於python操作hdfs的API可以查看官網:
# https://hdfscli.readthedocs.io/en/latest/api.html


# 讀取hdfs文件內容,將每行存入數組返回
def read_hdfs_file(client, filename):
    # with client.read('samples.csv', encoding='utf-8', delimiter='\n') as reader:
    #  for line in reader:
    # pass
    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):
    client.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, encoding='utf-8')


# 覆蓋數據寫到hdfs文件
def write_to_hdfs(client, hdfs_path, data):
    client.write(hdfs_path, data, overwrite=True, append=False, encoding='utf-8')


# 移動或者修改文件
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)

# client = Client(url, root=None, proxy=None, timeout=None, session=None)
# client = Client("http://hadoop:50070")
client = Client("http://120.78.186.82:50070/",root="/",timeout=10000,session=False)
# client = InsecureClient("http://120.78.186.82:50070", user='ann');

# move_or_rename(client,'/input/2.csv', '/input/emp.csv')
# read_hdfs_file(client,'/input/emp.csv')
put_to_hdfs(client, 'D:\\bbb.txt', '/file')
# append_to_hdfs(client,'/input/emp.csv','我愛你'+'\n')
# write_to_hdfs(client, '/emp.csv', "sadfafdadsf")
# read_hdfs_file(client,'/input/emp.csv')
# move_or_rename(client,'/input/emp.csv', '/input/2.csv')
# mkdirs(client,'/input/python')
# print(list(client, '/'))
# chown(client,'/input/1.csv', 'root')

執行報錯說連接不上,這個問題卡了我很久

urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x0000000003A45F28>: Failed to establish a new connection: [Errno 11004] getaddrinfo failed

網上資料又很少,經過我不斷嘗試,最後發現問題所在

1、服務器上的hadoop的配置文件中,namenode不能設置成127.0.0.1或者localhost,要設置ip映射別名

(1)首先修改centos的/etc/hosts,這裏要寫服務器的ip,不能寫127.0.0.1,不然沒辦法遠程連接過來hdfs

192.168.2.161 hadoop

(2)修改hadoop的配置

即hadoop的core-site.xml文件

<configuration>
<property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop:9000</value>
    </property>
    <!--存放數據的公共目錄 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/local/hadoop/hadoop-2.9.0/tmp</value>
    </property>
</configuration>

fs.defaultFS這裏設置要注意,如果需要通過客戶端遠程連接(非服務器命令行連接,即使是java或者python運行在服務器連接hdfs也要設置下面這種)

hdfs://hadoop:9000

如果只限本地操作設置成這樣即可(或者本地命令行操作),剛開始我就是犯了這個錯誤,因爲網上很多資料單機部署hdfs都是寫localhost

 

hdfs://127.0.0.1:9000或者hdfs://localhost:9000

2、看到某些報錯信息python通過webhdfs發送請求時傳遞參數是hadoop:50070,當時在想,是不是客戶端機器也要配置ip映射。百度了下window修改ip映射的文件位置

C:\Windows\System32\drivers\etc\hosts

修改ip映射

192.168.2.161 hadoop

注:可能本人使用pycharm的原因,配置了window的ip別名映射後,還是提示網絡報錯,後來覺得可能需要重啓電腦,配置才完全生效,結果重啓電腦後,python上傳文件到hdfs運行正常。

3、然後再嘗試python通過hdfs庫上傳文件,提示Name node is in safe mode

這是因爲hadoop處於安全模式,輸命令強制離開安全模式

hadoop dfsadmin -safemode leave

資料:https://blog.csdn.net/xw13106209/article/details/6866072

 

經過上面3步後,python終於可以順利遠程上傳文件到hdfs上。

注:這裏有些地方要注意

1、java通過hdfs遠程連接hdfs,不需要在客戶端機配置ip映射。

2、python利用hdfs庫通過webhdfs操作hdfs,必須在客戶端機配置ip映射

3、阿里雲配置hadoop,/etc/hosts要設置內網ip,namenode才能正常運行。但是java、python通過外網ip訪問hdfs時,總提示連不上。後面我在虛擬機配置hadoop,用java、python連接一切正常。所以如果使用阿里雲配置hadoop,遠程連接hadoop的程序應該運行在同一個服務器,或者另外的阿里內網服務器,然後通過內網連接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章