python操作WebHDFS

python操作WebHDFS

起因

在工作中经常需要使用到hdfs进行文件操作,同时经常有和java做数据交互同时操作hdfs的过程,在这个过程中发现java使用hdfs的方式和python还是有一定差异性的,如路径头部java为hdfs,python为url,于是写下此文档做一个总结备用。

WebHDFS API客户端

class hdfs.client.Client(url,root = None,proxy = None,timeout = None,session = None )
参数:url - HDFS namenode的主机名或IP地址,前缀为protocol,后跟namenode上的WebHDFS端口。您还可以指定由分号分隔的多个URL以获得高可用性支持。
proxy - 代理用户。
root - 根路径,这将作为传递给客户端的所有HDFS路径的前缀。如果根是相对的,则将相对于用户的主目录假定路径。
timeout - 连接超时,转发到请求处理程序。在放弃之前等待服务器发送数据的时间,浮点数或 元组。如果达到超时,将引发适当的异常。有关详细信息,请参阅请求文档(connect_timeout, read_timeout)
session - requests.Sessioninstance,用于发出所有请求。

当我们在项目中实际使用时,我们发现python操作hdfs用的最多的就是数据上传和下载

# 上传
upload(hdfs_path,local_path,n_threads = 1,temp_dir = None,chunk_size = 65536,progress = None,cleanup = True,** kwargs )
将文件或目录上传到HDFS。

参数:	
hdfs_path - 目标HDFS路径。如果它已经存在并且是目录,则文件将被上传到内部。
local_path - 文件或文件夹的本地路径。如果是文件夹,则会上传其中的所有文件(请注意,这意味着不会远程创建文件夹空文件)。
n_threads - 用于并行化的线程数。值 0(或负数)使用与文件一样多的线程。
temp_dir - 当overwrite=True最终远程路径已存在时,首次上载文件的目录。上传成功完成后,它将被交换。
chunk_size - 文件上传的间隔(以字节为单位)。
progress - 用于跟踪进度的回调函数,调用每个 chunk_size字节。它将传递两个参数,即上载文件的路径和到目前为止传输的字节数。完成后,它将-1作为第二个参数调用一次。
清理 - 如果在上载过程中发生错误,请删除所有上传的文件。
** kwargs - 转发给的关键字参数write()。特别是,设置overwrite为覆盖任何现有文件或目录。
成功时,此方法返回远程上载路径。
下载
download(hdfs_path,local_path,overwrite = False,n_threads = 1,temp_dir = None,** kwargs )
从HDFS下载文件或文件夹并将其保存在本地。

参数:	
hdfs_path - 要下载的文件或文件夹的HDFS路径。如果是文件夹,则下载其下的所有文件。
local_path - 本地路径。如果它已经存在并且是目录,则文件将在其中下载。
覆盖 - 覆盖任何现有文件或目录。
n_threads - 用于并行化的线程数。值 0(或负数)使用与文件一样多的线程。
temp_dir - 首次下载文件时的目录overwrite=True,最终目标路径已存在。下载成功完成后,将进行交换。
** kwargs - 转发给的关键字参数read()。如果没有 chunk_size传递参数,将使用默认值64 kB。如果progress传递参数并使用线程,则必须注意确保正确的行为。
成功时,此方法返回本地下载路径。

在项目中为了保证一台设备只有一个hdfs链接我采用了多线程单例模式:

from hdfs.client import Client
import threading


class SingletonClient(object):
    '''
    多线程单例模式,保证一台设备上只有一个hdfs的连接
    '''
    _instance_lock = threading.Lock()

    def __init__(self,client_url,root=None, proxy=None, timeout=None, session=None):
        self.hdfs_client = Client(client_url, root, proxy, timeout, session)

    def __new__(cls, *args, **kwargs):
        if not hasattr(SingletonClient, "_instance"):
            with SingletonClient._instance_lock:
                if not hasattr(SingletonClient, "_instance"):
                    SingletonClient._instance = object.__new__(cls)
        return SingletonClient._instance

然后利用该方法实现文件的上传下载

def put_to_hdfs(client_url,local_path,hdfs_path,root=None,proxy=None,timeout=None,session=None):
    singleton_client = SingletonClient(client_url,root,proxy,timeout,session)
    singleton_client.hdfs_client.upload(hdfs_path, local_path,cleanup=True)

# from hdfs download to local
def download_hdfs(client_url, hdfs_path, local_path,root=None,proxy=None,timeout=None,session=None):
    singleton_client = SingletonClient(client_url,root,proxy,timeout,session)
    return singleton_client.hdfs_client.download(hdfs_path,local_path,overwrite=False,n_threads=1,temp_dir=None)

# create hdfs dir
def mkdirs(client_url,hdfs_path,root=None,proxy=None,timeout=None,session=None) :
    singleton_client = SingletonClient(client_url,root,proxy,timeout,session)
    singleton_client.hdfs_client.makedirs(hdfs_path)

该方法所需连接hdfs的参数可以由java通过命令行的方式传入,也可以由python写入配置文件读取,也可以通过数据库存储的方式读取,各有优劣不赘述,建议写入python配置文件(java大神有时候不太了解python,有时候沟通起来不太方便最好分离开发,达到高内聚低耦合,在这里我要说一句java才是世界上最好的语言哈哈)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值