如何从外部机器向Hadoop/HDFS集群发送增量系统监控数据?
问题
我需要收集CPU使用率、可用内存、总内存、已用内存、当前时间、系统名称、IP地址等系统数据用于测试需求。在集群节点内通过Ubuntu终端运行以下Python脚本可实现数据发送至HDFS,但无法从集群外的外部机器完成该操作,求可行的实现方法或适用的Python库。
import psutil import platform import socket import time import pytz from datetime import datetime, timezone from hdfs import InsecureClient def collect_system_data(): # 获取CPU使用率百分比 cpu_percent = psutil.cpu_percent(interval=1) # 获取CPU频率 cpu_freq = psutil.cpu_freq() current_cpu_freq = cpu_freq.current # 获取CPU核心数(物理核心) cpu_count = psutil.cpu_count(logical=False) # 设为logical=True可获取总线程数 # 获取内存信息 memory_info = psutil.virtual_memory() available_memory = memory_info.available total_memory = memory_info.total used_memory = memory_info.used # 获取系统名称 system_name = platform.system() # 获取指定时区的当前时间 desired_timezone = 'Asia/Kolkata' timezone = pytz.timezone(desired_timezone) current_time = datetime.now(timezone) # 获取IP地址 ip_address = socket.gethostbyname(socket.gethostname()) # 整理收集到的信息为字符串 collected_info = ( f"CPU使用率百分比: {cpu_percent}%\n" f"当前CPU频率: {current_cpu_freq}\n" f"CPU核心数: {cpu_count}\n" f"可用内存: {available_memory} 字节\n" f"总内存: {total_memory} 字节\n" f"已用内存: {used_memory} 字节\n" f"系统名称: {system_name}\n" f"当前时间(本地): {current_time.strftime('%Y-%m-%d %H:%M:%S')}\n" f"IP地址: {ip_address}\n" "-------------------------------------------\n" ) # 将信息追加写入本地文本文件 with open('system_data.txt', 'a') as file: file.write(collected_info) while True: # 连接HDFS hdfs_client = InsecureClient('http://<host>:<port>', user='your_username') # 本地文件路径 local_file_path = 'file_path' # HDFS文件路径 hdfs_file_path = '/hd_data' # 读取本地文件内容 with open(local_file_path, "r", encoding="utf-8") as local_file: file_content = local_file.read() # 将内容写入HDFS with hdfs_client.write( hdfs_file_path, encoding="utf-8", overwrite=True) as hdfs_writer: hdfs_writer.write(file_content) # 每10秒收集一次数据 collect_system_data() time.sleep(10)
解决方案
集群外无法连接HDFS通常是WebHDFS服务未对外开放、集群防火墙/网络策略限制,或是依赖的客户端库仅支持集群内访问导致的,以下是几种可行的解决方法:
方法1:配置WebHDFS对外开放并调整网络策略
你的脚本使用的InsecureClient依赖WebHDFS服务,需确保该服务允许外部访问:
- 修改HDFS配置文件
hdfs-site.xml,添加/调整以下配置:<property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> <property> <name>dfs.namenode.http-address</name> <value>0.0.0.0:50070</value> <!-- 允许所有IP访问,默认仅localhost --> </property> <property> <name>dfs.datanode.http.address</name> <value>0.0.0.0:50075</value> </property> - 重启HDFS的namenode和datanode服务:
sudo systemctl restart hadoop-namenode sudo systemctl restart hadoop-datanode - 在集群防火墙开放对应端口(默认50070和50075):
sudo ufw allow 50070/tcp sudo ufw allow 50075/tcp sudo ufw reload - 验证外部机器可访问:执行
telnet <namenode-IP> 50070,能连通则配置生效。
方法2:使用支持RPC连接的Python库
若WebHDFS配置受限,可改用直接支持HDFS RPC协议的库(如pyhdfs),无需依赖WebHDFS服务:
- 安装依赖库:
pip install pyhdfs - 修改脚本中的HDFS连接与写入逻辑:
# 替换原有的hdfs导入与连接代码 from pyhdfs import HdfsClient # 连接HDFS(使用namenode的RPC端口,默认8020) hdfs_client = HdfsClient(hosts="<namenode-IP>:8020", user_name="your_username") # 写入内容到HDFS的代码替换为: with hdfs_client.open(hdfs_file_path, 'w', encoding='utf-8') as f: f.write(file_content) - 确保集群的RPC端口(8020)对外开放,且防火墙允许外部访问。
方法3:通过SSH隧道中转(无需修改集群配置)
如果集群不允许直接对外开放端口,可在外部机器建立SSH隧道,将集群的WebHDFS端口映射到本地:
- 在外部机器执行命令建立隧道(需有集群网关/节点的SSH权限):
ssh -L 50070:<namenode-IP>:50070 your_cluster_user@<cluster-gateway-IP> - 修改脚本中的HDFS连接地址为本地映射端口:
hdfs_client = InsecureClient('http://localhost:50070', user='your_username') - 保持SSH隧道开启,即可通过本地端口访问集群HDFS。
额外注意事项
- 外部机器需安装所有依赖库:
pip install psutil pytz hdfs pyhdfs - 脚本中
local_file_path需改为实际的system_data.txt路径(如./system_data.txt),避免文件找不到 - 若集群启用Kerberos认证,需改用
KerberosClient替代InsecureClient,并提前获取Kerberos票据
内容的提问来源于stack exchange,提问作者Raman gupta
相关产品推荐
相关产品推荐

