You need to enable JavaScript to run this app.
导航
PyProton 介绍与使用文档
最近更新时间:2024.10.11 11:30:10首次发布时间:2024.08.16 17:13:25

PyProton 介绍

PyProton 是一个实现了fsspec(fsspec 是一个旨在为本地、远程和嵌入式文件系统以及字节存储提供统一 Python 风格接口的项目。)标准接口的Proton Python Client。PyProton 可以让Python用户以他们习惯的方式轻松地访问Proton所支持的各种后端存储(如TOS、HDFS)的同时自动得获得Proton访问存储的各种优势(如稳定性、性能优化等,详情请参考Proton官方文档)。

前置要求(checklist)

  • 需要预装JDK 1.8(EMR节点与Ray镜像中已内置)
  • 预装Python 3.9+ (以及与之匹配的支持Python 3.9+的PIP)

安装

  • 内置安装:目前新版本的Ray以及Spark的镜像都内置安装了PyProton,具体的版本信息,可参考RaySpark的镜像说明文档。
  • 手动安装:

说明

最新安装包地址:https://proton-pkgs.tos-cn-beijing.volces.com/public/pyproton-2.1.dev0-py3-none-any.whl。

# 可以先通过 pip list 检查是否已预装;
pip list | grep 'pyproton'

# 将下面的包替换为具体的名称;
pip install pyproton-x.whl

使用教程

参数设置

说明

参数设置有两种方式:

  • 通过环境变量。
  • 通过代码初始化设置。

环境变量只能设置部分参数,代码设置支持设置全部参数。如果检测到某个参数在两种环境下都有设置,则代码设置高优于环境变量。

  1. 环境变量:

说明

依次执行如下命令,或将其保存为脚本执行。

# 替换下文中的bucket name, ak, sk为真实值!

cat > setup-pyproton-env.sh << 'EOF'
#!/usr/bin/env bash
set -exv

# 配置 (ak & sk) 或者 assume role的session token 两者二选一
echo "export TOS_ACCESS_KEY_ID='ak'" >> /etc/profile
echo "export TOS_SECRET_ACCESS_KEY='sk'" >> /etc/profile
echo "export TOS_SESSION_TOKEN='sessiontoken'" >> /etc/profile

# 请注意内外网 end point不同
echo "export TOS_ENDPOINT='http://tos-cn-beijing.volces.com'" >> /etc/profile

# 用于配置pyproton 的log level,如果想调试程序,可以配置为“DEBUG”模式,建议非生产环境下开启
echo "export PROTONFS_LOGGING_LEVEL='INFO'" >> /etc/profile

# 显式覆盖 pyproton 内部Proton SDK的JVM -Xmx参数(默认值为2g)
echo "export PYPROTON_JVM_XMX='4g'" >> /etc/profile
EOF

chmod +x setup-pyproton-env.sh

./setup-pyproton-env.sh

source /etc/profile
  1. 编程设置参数(以上的参数都可以通过代码来设置):
    • 精简版参数设置:
from pyproton.protonfs import (
    ProtonFileSystem,
    ProtonError,
)
from pyproton.protonfs import ProtonFile
import string
import os

fs = ProtonFileSystem(
    endpoint_url="http://tos-cn-beijing.volces.com",
    key="",
    secret="",
    session_token="",
)
  • 完整版参数设置:
from pyproton.protonfs import (
    ProtonFileSystem,
    ProtonError,
)
from pyproton.protonfs import ProtonFile
import string
import os

fs = ProtonFileSystem(
    endpoint_url="http://tos-cn-beijing.volces.com",
    key="",
    secret="",
    session_token="",
    # 用户可按需调整JVM参数,默认的使用无需指定,使用PyProton内置的参数即可
    jvm_args = [
        "-Xms64m",
        "-Xmx2g",
        "-XX:+UseG1GC",
        "-XX:+UnlockExperimentalVMOptions",
        "-XX:MaxGCPauseMillis=100",
        "-XX:G1NewSizePercent=5",
        "-XX:InitiatingHeapOccupancyPercent=65",
        "-XX:+ParallelRefProcEnabled",
        "-XX:ConcGCThreads=4",
        "-XX:ParallelGCThreads=16",
        "-XX:MaxTenuringThreshold=1",
        "-XX:G1HeapRegionSize=32m",
        "-XX:G1MixedGCCountTarget=64",
        "-XX:G1OldCSetRegionThresholdPercent=5",
        "-Dfile.encoding=UTF-8",
        "-Duser.timezone=GMT+08",
        "-XX:+HeapDumpOnOutOfMemoryError",
        "-XX:HeapDumpPath=./java_heapdump.hprof",
    ],
    # proton sdk支持的参数设置
    config_dict = {
        # PROTON_CONFIG_KEY_TOS_ENDPOINT: "http://tos-cn-beijing.volces.com",
        # PROTON_CONFIG_KEY_TOS_AK: "",
        # PROTON_CONFIG_KEY_TOS_SK: "",
        # PROTON_CONFIG_KEY_TOS_SESSION_TOKEN: "",
        "fs.tos.credentials.provider": "io.proton.common.object.tos.auth.DefaultCredentialsProviderChain",  # noqa: E501
        "fs.AbstractFileSystem.tos.impl": "io.proton.fs.ProtonFS",
        "fs.tos.impl": "io.proton.fs.ProtonFileSystem",
        "fs.tos.credential.provider.custom.classes": "io.proton.common.object.tos.auth.EmrSidecarCredentialProvider,io.proton.common.object.tos.auth.EnvironmentCredentialsProvider,io.proton.common.object.tos.auth.SimpleCredentialsProvider,io.proton.common.object.tos.auth.IAMInstanceCredentialsProvider",  # noqa: E501
        # "fs.tos.multipart.staging-dir": "",
        # "fs.tos.multipart.size": "8388608",
        # "fs.tos.multipart.thread-pool-size": "96",
        # "fs.tos.multipart.staging-buffer-size": "4096",
        # "fs.tos.multipart.threshold": "10485760",
        # "fs.tos.task.thread-pool-size": "96",
    }
)

编程设置参数时,PyProton充分考虑了易用性和灵活性,主要体现在两个参数上:

  • jvm_args:用于设置ProtonSDK所依赖的JVM参数,一般使用场景用户可以无需指定,采用PyProton内置的默认参数即可。当有调优需求时,可以参考上文中的示例代码,覆盖一些默认参数(如调整Xmx)。
  • config_dict:用于设置ProtonSDK所需参数,默认情况下,只需设置Key为“PROTON_CONFIG_KEY”前缀的设置,其他参数采用PyProton内置的即可。当有调优需求时,可以参考Proton SDK调优指南,按需设置。

API 调用

获得fs 对象后,用户就可以调用如lsmkdir等fsspec兼容的API来操作或访问Proton支持的后端存储:

fs.mkdir("xxxx")
fs.ls("xxxx")
with fs.open("path", mode="wb") as f:
    f.write("xxx")

说明

  • 尽可能复用fs对象,单fs支持多桶访问,所以访问路径上必须带上桶名。
  • 使用PyProton进行文件读写的时候,尽可能使用with as语句以确保文件能被即时关闭。
  • 高频读写大文件时,建议拆分chunk,可视情况适当调整JVM参数集合中的-Xmx参数。
  • 如果运行节点有多块数据盘,可参考Proton官网对“multipart”相关的参数进行调优,从而获得更好的写性能,根据多轮benchmark的结果分析,PyProton在多盘写场景下性能可以随盘数的增加获得接近线性的性能提升。
  • 日志LogLevel设置:默认情况下PyProton和Proton SDK原生的日志都合二为一输出到console,两者都使用统一LogLevel控制(默认值为“INFO”,使用PROTONFS_LOGGING_LEVEL系统环境变量进行控制 )。

API List

目前PyProton支持的API列表如下:

  • FileSystem operation
    • ls
    • info
    • makedir
    • exists
    • isdir
    • isfile
    • glob
    • touch
    • get_file
    • get
    • put_file
    • put
    • rmdir
    • mv(暂不支持跨 bucket mv)
    • download
    • walk
    • find
    • du
    • cat_file
    • copy
  • File operation
    • seek
    • write
    • read
    • readline
    • readlines
    • info

Limitations

  • 暂不支持跨 bucket 操作,如跨 bucket copy、mv。
  • 不支持随机写。
  • 暂不支持 append 语义(即将支持)。

PyProton on Ray

说明

Ray 镜像对PyProton的集成版本信息,请参考Ray镜像说明文档

PyProton可以以两种方式在Ray引擎上使用:

  • 当做一个纯Python package使用,例如可以在Ray的map function中使用。
  • 结合Ray Data方式使用,Ray Data目前支持指定pyarrow的filesystem,借助于PyArrow的一个文件系统转换的pyarrow.fs.FSSpecHandler,即可让PyProton以fsspec的接口适配到pyarrow.fs,从而可以直接在Ray Data中使用pyproton,示例如下:
from pyproton.protonfs import (
    ProtonFileSystem,
    ProtonError,
    PROTON_CONFIG_KEY_TOS_ENDPOINT,
    PROTON_CONFIG_KEY_TOS_AK,
    PROTON_CONFIG_KEY_TOS_SK
)
from pyproton.protonfs import ProtonFile
from pyarrow import fs
from pyarrow._fs import (  # noqa
    PyFileSystem
)
import ray
import random
import string
import os
from jpype import JClass

proton_fs = ProtonFileSystem(
    # ....
)

pyarrow_fs = PyFileSystem(fs.FSSpecHandler(proton_fs))

dt = ray.data.range(100)
dt.show(5)
dt.write_csv(path = "tos://bucket/path", filesystem = pyarrow_fs)

注意

如果代码中需调用ray.init(),请将其置于初始化ProtonFileSystem之前,否则会报错。