跳转至

环境搭建

国内使用UV的代理设置

原文地址:https://www.yangyanxing.com/article/uv-proxy-setting

1. 安装第三方包时的镜像设置

在使用 uv add 命令安装第三方包时,有两种方法可以设置国内加速镜像:

1.1 命令行中指定镜像

使用 --index 或者 --default-index 参数指定镜像地址,例如:

1
2
3
uv add fastapi --index https://mirrors.aliyun.com/pypi/simple/

uv add fastapi --default-index https://mirrors.aliyun.com/pypi/simple/

简单说明下两者的区别:

参数 环境变量 描述
--index UV_INDEX 可以设置多个索引源,多个索引源之间以空格分开,适用于同时使用多个索引源
--default-index UV_DEFAULT_INDEX 只设置一个索引源,用于替换默认的 PyPI 源

一般情况下,我们只需配置 UV_DEFAULT_INDEX 即可,常用的镜像源有:

1.2 设置环境变量

可以在 .bashrc 文件中添加环境变量 UV_INDEXUV_DEFAULT_INDEX,然后执行 source .bashrc 使其生效。

2. 安装 Python 时的镜像设置

UV 提供了通过 GitHub Releases 下载 Python 的功能,可以通过以下 --mirror--pypy-mirror 两个参数和环境变量来设置镜像:

  • --mirror: 用于设置 CPython 的安装包镜像,可以通过设置环境变量 UV_PYTHON_INSTALL_MIRROR 来指定下载镜像。
  • --pypy-mirror: 用于设置 PyPy 的安装包镜像,可以通过设置环境变量 UV_PYPY_INSTALL_MIRROR 来指定下载镜像。
维度 CPython PyPy
实现语言 C 语言编写,官方标准解释器 RPython 编写,基于 JIT 编译技术
性能表现 解释执行字节码,性能较低 JIT 编译热点代码为机器码,性能提升 3-4 倍
内存管理 引用计数 + GIL,存在内存碎片问题 增量垃圾回收 + 分代回收,无 GIL 限制
并发支持 单线程并发(GIL 限制多线程性能) 支持微线程(Stackless 模型),适合高并发场景
生态系统兼容性 完整支持所有 Python 库 兼容大部分纯 Python 库,对 C 扩展库支持有限
典型应用场景 Web 服务、自动化脚本、科学计算 数值计算、长时间运行的服务、高并发 API 服务器
启动时间 快速启动 需 JIT 预热期

目前国内还没有一个完全同步的下载镜像,所以使用 uv python install 下载非常慢,南京大学的镜像站提供了 UV 的最新下载:https://mirror.nju.edu.cn/github-release/indygreg/python-build-standalone

3. 总结

  • UV_PYTHON_INSTALL_MIRROR:用于设置使用 uv python install 命令下载安装 Python 时的镜像。
  • UV_DEFAULT_INDEX:用于设置使用 uv add 命令安装第三方包时的镜像。
  • UV_INDEX:用于设置额外的安装镜像,如公司内部的包索引地址。

建议:如果你的网络环境可以正常访问 GitHub,则无需设置镜像。如果访问不了,可以设置南京大学的下载镜像,并配置 UV_DEFAULT_INDEX 为阿里源或清华源来加速 uv add(等同于 pip install)的安装过程。

通过合理设置镜像源,可以显著提升在国内使用 UV 进行软件包管理和 Python 安装的效率。

最简单的大数据开发环境搭建

作为一名程序员,很多时候我们希望在本地能搭建一套大数据环境作为测试开发环境,以便快速地开发一些库和接口服务,能无缝地切换到生产环境上去。本篇文章主介绍如何通过 Docker 镜像快速高效地创建一个大数据开发环境。

1. Apache Impala

gethue 介绍了如何集成一个 Kudu Impala 服务,我们按照文档介绍来创建一个容器。

docker run -d --name kudu-impala -p 0.0.0.0:21000:21000 -p 0.0.0.0:21050:21050 -p 0.0.0.0:25000:25000 -p 0.0.0.0:25010:25010 -p 0.0.0.0:25020:25020 --memory=4096m apache/kudu:impala-latest impala

进入容器内 /opt 目录下,你会发现该镜像已经集成了 Hadoop 和 Hive 服务。如果后续你会使用到 WebHDFS 和 Hive 接口服务,这里建议将这些端口 8020、9000、9870、9864、10000 也先暴露出来,后面我们配置会用到相关接口,建议看完全部文档后再操作。

1.1 Windows宿主机对外开放接口

这里我们使用闲置的 Windows 电脑作为容器的宿主机,开启服务后在局域网内可供其他机器访问。实践过程中有时间会出现这样的一个问题,通过 Python 连接 localhost 是正常的,但换成 127.0.0.1 或者实际 IP4 地址,都无法正确连接(尤其是在配置其他服务后重启服务的时候)。网上有一些解决办法是采用端口的转发的操作,但验证下来此方法无效,且对删除容器重新创建也会有影响,非常不建议这么操作。

Window端口转发与重置
netsh interface portproxy add v4tov4 listenport=21050 listenaddress=0.0.0.0 connectport=21050 connectaddress=localhost
netsh interface portproxy show all
netsh interface portproxy reset

2. Apache Hadoop

进入 kudu-impala 容器内你会发现 /opt 目录下已经有 hadoop 和 hive 的目录,但是直接运行 hadoop version 命令会提示错误信息,告诉我们 JAVA_HOME 环境变量没有设置:

WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete.
ERROR: JAVA_HOME is not set and could not be found.

使用 java -version 能看到当前容器中已经安装了 JDK 服务,下面先找一下 JDK 的安装目录:

$ which java
/usr/bin/java

$ ls -la /usr/bin |grep java
lrwxrwxrwx root root    22 B  Fri May  1 18:19:05 2020 java  /etc/alternatives/java
lrwxrwxrwx root root    23 B  Fri May  1 18:19:06 2020 javac  /etc/alternatives/javac
lrwxrwxrwx root root    25 B  Fri May  1 18:19:06 2020 javadoc  /etc/alternatives/javadoc
lrwxrwxrwx root root    23 B  Fri May  1 18:19:06 2020 javah  /etc/alternatives/javah
lrwxrwxrwx root root    23 B  Fri May  1 18:19:06 2020 javap  /etc/alternatives/javap

$ ls -la /etc/alternatives |grep java
lrwxrwxrwx root root  46 B Fri May  1 18:19:05 2020 java  /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
lrwxrwxrwx root root  56 B Fri May  1 18:19:05 2020 java.1.gz  /usr/lib/jvm/java-8-openjdk-amd64/jre/man/man1/java.1.gz
lrwxrwxrwx root root  43 B Fri May  1 18:19:06 2020 javac  /usr/lib/jvm/java-8-openjdk-amd64/bin/javac
lrwxrwxrwx root root  53 B Fri May  1 18:19:06 2020 javac.1.gz  /usr/lib/jvm/java-8-openjdk-amd64/man/man1/javac.1.gz
lrwxrwxrwx root root  45 B Fri May  1 18:19:06 2020 javadoc  /usr/lib/jvm/java-8-openjdk-amd64/bin/javadoc
配置环境变量(无效)

HADOOP_CONF_DIR 目录比较简单,通常是 Hadoop 安装目录下的 etc/hadoop 目录,接下来需要设置相关环境变量:

export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/jre"
export HADOOP_CONF_DIR="/opt/hadoop/etc/hadoop"
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_CONF_DIR

尝试此操作后,发现在 /etc/profile~/.bashrc~/.zshrc 这些文件中加入上述内容,配置都没有生效,此方法不适用

这里我们先删除容器,通过如下命令重新创建一个容器(区别在于通过 --env 直接设置了环境变量),容器内再次执行 hadoop version 命令就正常了。

docker run -d --name kudu-impala -p 0.0.0.0:21000:21000 -p 0.0.0.0:21050:21050 -p 0.0.0.0:25000:25000 -p 0.0.0.0:25010:25010 -p 0.0.0.0:25020:25020 --env "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre" --env "HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop" --memory=4096m apache/kudu:impala-latest impala

关于 Hadoop 接口应用,目前我用到最多的通过 WebHDFS 服务上传下载 HDFS 文件,并结合 Hive 和 Impala 建立外部分区表。这里以 Hadoop 3.x 为例,说明下 WebHDFS 服务开启操作。

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <!-- 替换为你的NameNode主机名或IP,例如我的 kudu-impala 的 IP 为 172.17.0.2 -->
    <value>hdfs://172.17.0.2:9000</value>  
  </property>
  <!-- 不添加的话,会导致无法提交文件到 HDFS 上 -->
  <property>
    <name>dfs.client.use.datanode.hostname</name>
    <value>true</value>
  </property>
  <property>
    <name>hadoop.proxyuser.root.hosts</name>
    <value>*</value>  <!-- 允许所有主机访问 -->
  </property>
  <property>
    <name>hadoop.proxyuser.root.groups</name>
    <value>*</value>  <!-- 允许所有用户组 -->
  </property>
  <property>
    <name>hadoop.proxyuser.impala.hosts</name>
    <value>*</value>  <!-- 允许所有主机访问 -->
  </property>
  <property>
    <name>hadoop.proxyuser.impala.groups</name>
    <value>*</value>  <!-- 允许所有用户组 -->
  </property>
</configuration>
<configuration>
  <property>
    <name>dfs.webhdfs.enabled</name>
    <value>true</value>
  </property>
  <!-- NameNode HTTP 地址(Hadoop 3.x 默认端口:9870) -->
  <property>
    <name>dfs.namenode.http-address</name>
    <value>0.0.0.0:9870</value>
  </property>
  <!-- DataNode HTTP 地址(Hadoop 3.x 默认端口:9864) -->
  <property>
    <name>dfs.datanode.http.address</name>
    <value>0.0.0.0:9864</value>
  </property>
  <!-- 不添加的会导致无法提交文件到 hdfs 上 -->
  <property>
    <name>dfs.datanode.hostname</name> 
    <!-- 填写 Windows 宿主机的 IP 地址 (1) -->
    <value>10.166.99.61</value>
  </property>
</configuration>
  1. 需要设置下 DataNode 的 hostname,否则会报错 Failed to resolve 'f38ea60d2b3a' ([Errno 11001] getaddrinfo failed)"))

接下来,我们需要先使用 hdfs name -format 格式化 NameNode,然后启动 NameNode 和 DataNode 服务后,就可以通过 WebHDFS 服务访问 HDFS 了:

启动 NameNode 和 DataNode
# 关闭将 start 修改为 stop 即可
$ hdfs --daemon start namenode
$ hdfs --daemon start datanode

PyHDFS 无法上传文件

如果使用 PyHDFS 可以创建和删除文件夹,但无法将本地文件上传到 HDFS,报错信息为 HdfsIOException: Failed to find datanode, suggest to check cluster health. excludeDatanodes=null

解决办法:上述问题通常是 HDFS NameNode 多次格式化导致,先删除 /tmp/hadoop-impala/dfs/data 目录所有文件,再重新格式化 NameNode。

该容器默认用户为 impala,如果后面需要使用到 Hue 的话,这里我们先需要先创建对应的 HDFS 目录:

# 以下不操作,会出现 User: impala is not allowed to impersonate root 报错信息
$ hdfs dfs  -mkdir /tmp
$ hdfs dfs  -mkdir -p /user/impala

如果你之前没有将 8020、9000、9870、9864、10000 这些端口暴露出来,那么需要删除容器重新创建,且再走一遍文档的操作:

docker run -d --name kudu-impala -p 0.0.0.0:21000:21000 -p 0.0.0.0:21050:21050 -p 0.0.0.0:25000:25000 -p 0.0.0.0:25010:25010 -p 0.0.0.0:25020:25020 -p 0.0.0.0:8020:8020 -p 0.0.0.0:9000:9000 -p 0.0.0.0:9870:9870 -p 0.0.0.0:9864:9864 -p 0.0.0.0:10000:10000 --env "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre" --env "HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop" --memory=4096m apache/kudu:impala-latest impala

如果希望容器启动时默认开启 WebHDFS 服务,在 /impala-entrypoint.sh 文件中添加如下内容,其中 start_hive_hs2 为后面开启 Hive 连接端口所用,这里先写上相关内容:

/impala-entrypoint.sh
function start_hive_hs2() {
  hive --service hiveserver2 &
}

function start_hdfs() {
  hdfs --daemon start namenode
  hdfs --daemon start datanode
}

if [[ "$1" == "impala" ]]; then
  mkdir -p $DATA_DIR
  mkdir -p $LOG_DIR
  start_hive_metastore
  start_hdfs
  start_hive_hs2
  start_statestored
  start_catalogd
  start_impalad
  tail -F ${LOG_DIR}/impalad.INFO
elif [[ "$1" == "help" ]]; then
  print_help
  exit 0
fi

3. Apache Hive

开启 Hive Metastore 需要先设置好 JAVA_HOME 以及 HADOOP_CONF_DIR 环境变量。在创建容器时就将 10000 接口暴露出来:

docker run -d --name kudu-impala -p 0.0.0.0:21000:21000 -p 0.0.0.0:21050:21050 -p 0.0.0.0:25000:25000 -p 0.0.0.0:25010:25010 -p 0.0.0.0:25020:25020 -p 0.0.0.0:8020:8020 -p 0.0.0.0:9000:9000 -p 0.0.0.0:9870:9870 -p 0.0.0.0:9864:9864 -p 0.0.0.0:10000:10000 --env "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre" --env "HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop" --memory=4096m apache/kudu:impala-latest impala

接下来执行以下命令开启 HiveServer2 服务,需要注意的是,要求 HDFS 的 NameNode 和 Datanode 服务需要先启动

nohup hive --service hiveserver2 > /dev/null 2>&1 &

当然我们可以直接在 /impala-entrypoint.sh 进行设置,不必每次进入容器手动开启:

/impala-entrypoint.sh
function start_hive_hs2() {
  hive --service hiveserver2 &
}

function start_hdfs() {
  hdfs --daemon start namenode
  hdfs --daemon start datanode
}

if [[ "$1" == "impala" ]]; then
  mkdir -p $DATA_DIR
  mkdir -p $LOG_DIR
  start_hive_metastore
  start_hdfs
  start_hive_hs2
  start_statestored
  start_catalogd
  start_impalad
  tail -F ${LOG_DIR}/impalad.INFO
elif [[ "$1" == "help" ]]; then
  print_help
  exit 0
fi

4. Hue

我们可以通过 Hue 的镜像快速创建容器,

docker run -it -p 8888:8888 gethue/hue:latest

4.1 配置 Impala 服务

/usr/share/hue/desktop/conf/hue.ini
1
2
3
4
5
6
7
[desktop]
default_user=impala
default_hdfs_superuser=impala

[impala]
server_host=<宿主机IP>
server_port=21050

4.2 配置 WebHDFS 服务

/usr/share/hue/desktop/conf/hue.ini
1
2
3
4
5
6
7
8
[desktop]
default_user=impala
default_hdfs_superuser=impala

[hadoop]
[[hdfs_clusters]]
[[[default]]]
webhdfs_url = http://<宿主机IP>:9870/webhdfs/v1

4.3 配置 Hive 服务

Thrift version configured by property thrift_version might be too high. Request failed with "Required field 'client_protocol' is unset! Struct:TOpenSessionReq(client_protocol:null, username:hue, configuration:{hive.server2.proxy.user=yumingmin})" (code OPEN_SESSION): None

打开 Hue 的 Hive Editor,出现如上错误,需要在 hue.ini 文件中修改 thrift_version=7

/usr/share/hue/desktop/conf/hue.ini
1
2
3
4
[beeswax]
hive_server2_host=<宿主机IP>
hive_server_port=10000
thrift_version=7

5. 参考文档