尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

CentOS 7下Hadoop 3.1.4源码编译集成Snappy压缩库实战指南

CentOS 7下Hadoop 3.1.4源码编译集成Snappy压缩库实战指南 1. 项目概述与核心价值最近在给一个数据平台做技术栈升级涉及到Hadoop 3.1.4的部署。在测试数据压缩性能时发现原生的Gzip和BZip2虽然稳定但在处理海量日志和中间数据时CPU开销和压缩/解压速度成了瓶颈。团队讨论后决定引入Snappy压缩算法这玩意儿在Google内部用了很久主打的就是一个“快”字特别适合Hadoop这种对I/O吞吐量要求极高的场景。但官方提供的Hadoop二进制包默认是不包含Snappy本地库支持的这就意味着你需要自己动手从源码开始编译把Snappy“缝”进Hadoop里。这个“缝”的过程就是标题所说的“hadoop3.1.4的centos7-snappy编译”。听起来好像就是几条命令的事但实际踩进去才发现从环境准备、依赖解决、源码修改到最终编译成功每一步都可能藏着坑。特别是CentOS 7这个经典又略显“年迈”的系统其自带的软件库版本和Hadoop 3.x所需的新工具链之间存在不少需要手动调和的地方。这次编译不仅仅是为了启用一个压缩选项更深层次的是它关乎到整个大数据流水线的效率。启用Snappy后MapReduce的Shuffle阶段、HDFS的数据块存储、乃至HBase的底层存储其I/O性能都可能获得显著提升这对于降低集群负载、缩短作业时间有直接好处。所以这篇内容我会详细拆解在CentOS 7.9系统上为Hadoop 3.1.4源码编译并集成Snappy 1.1.8本地库的完整过程。我会重点分享我趟过的坑、验证过的配置以及如何确保编译出的Hadoop分发版真正可用。无论你是正在搭建生产环境还是出于学习目的想深入理解Hadoop的构建机制这份从实战中总结的指南应该都能帮到你。2. 编译环境深度剖析与准备编译Hadoop绝非./configure make那么简单它是一套复杂的Java和C/C混合工程。在CentOS 7上我们需要搭建一个“全能”的编译环境涵盖从系统工具链到Java生态再到特定的压缩库开发包。2.1 系统基础环境确认与调优首先找一台干净的CentOS 7.9机器物理机或虚拟机均可。内存建议至少4GB硬盘空间预留20GB以上因为源码、依赖包和编译中间产物会占用不少空间。我习惯先做一次全面的系统更新和基础工具安装这能避免很多因缺失基础命令导致的问题。# 更新系统并安装基础开发工具 sudo yum update -y sudo yum groupinstall -y Development Tools sudo yum install -y wget curl which tar gzip bzip2接下来是关键一步升级系统自带的autoconf、automake和libtool。CentOS 7默认的版本太旧无法满足Hadoop 3.x源码构建的要求直接编译会报错。我们必须手动编译安装较新的版本。# 安装高版本autoconf (需要2.65) wget https://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz tar -xzf autoconf-2.69.tar.gz cd autoconf-2.69 ./configure --prefix/usr/local make -j$(nproc) sudo make install cd .. # 安装高版本automake (需要1.13) wget https://ftp.gnu.org/gnu/automake/automake-1.16.5.tar.gz tar -xzf automake-1.16.5.tar.gz cd automake-1.16.5 ./configure --prefix/usr/local make -j$(nproc) sudo make install cd .. # 安装高版本libtool wget https://ftp.gnu.org/gnu/libtool/libtool-2.4.7.tar.gz tar -xzf libtool-2.4.7.tar.gz cd libtool-2.4.7 ./configure --prefix/usr/local make -j$(nproc) sudo make install cd .. # 将新安装的工具路径加入环境变量确保优先使用 echo export PATH/usr/local/bin:$PATH ~/.bashrc source ~/.bashrc # 验证版本 autoconf --version | head -1 automake --version | head -1 libtool --version | head -1注意这里选择手动安装到/usr/local是为了避免覆盖系统自带的旧版本防止其他系统服务出现兼容性问题。make -j$(nproc)是利用所有CPU核心并行编译能大幅缩短时间。2.2 Java与协议缓冲区等核心依赖部署Hadoop是Java写的但它的高性能组件比如Snappy本地库集成和RPC框架Protocol Buffers又依赖C环境。因此我们需要同时配置好Java和C的构建链。安装JDK 8Hadoop 3.1.4官方推荐JDK 8。虽然更高版本也可能工作但为了最大兼容性建议使用JDK 8。# 下载Oracle JDK 8 (请从Oracle官网获取最新链接或使用OpenJDK) # 这里示例使用OpenJDK 8 sudo yum install -y java-1.8.0-openjdk-devel # 设置JAVA_HOME echo export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk ~/.bashrc echo export PATH$JAVA_HOME/bin:$PATH ~/.bashrc source ~/.bashrc java -version安装Apache MavenHadoop使用Maven进行项目管理和依赖构建。CentOS 7默认仓库的Maven版本旧需要手动安装3.6.0以上版本。wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz tar -xzf apache-maven-3.6.3-bin.tar.gz -C /opt/ sudo ln -s /opt/apache-maven-3.6.3 /opt/maven echo export MAVEN_HOME/opt/maven ~/.bashrc echo export PATH$MAVEN_HOME/bin:$PATH ~/.bashrc source ~/.bashrc mvn -v安装Protocol Buffers (protobuf)Hadoop的RPC通信依赖于protobuf。必须安装指定版本Hadoop 3.1.4需要protobuf 2.5.0版本不匹配会导致编译失败。# 安装编译protobuf所需的依赖 sudo yum install -y unzip # 下载并编译protobuf 2.5.0 wget https://github.com/protocolbuffers/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz tar -xzf protobuf-2.5.0.tar.gz cd protobuf-2.5.0 ./configure --prefix/usr/local/protobuf-2.5.0 make -j$(nproc) sudo make install cd .. # 设置环境变量 echo export PATH/usr/local/protobuf-2.5.0/bin:$PATH ~/.bashrc echo export LD_LIBRARY_PATH/usr/local/protobuf-2.5.0/lib:$LD_LIBRARY_PATH ~/.bashrc source ~/.bashrc protoc --version实操心得LD_LIBRARY_PATH的设置至关重要它告诉系统运行时去哪里找protobuf的动态链接库.so文件。没有这个后续编译Hadoop本地代码时会链接失败。安装CMake和OpenSSL开发包编译Snappy和一些其他本地库需要CMake而Hadoop的网络安全特性需要OpenSSL。sudo yum install -y cmake3 openssl-devel sudo ln -s /usr/bin/cmake3 /usr/local/bin/cmake # 让cmake命令指向cmake3 cmake --version2.3 Snappy库的编译与安装这是本次编译的核心目标之一。我们需要先准备好Snappy的本地库这样Hadoop在编译时才能找到并链接它。# 下载Snappy源码 (这里使用1.1.8一个稳定且兼容性好的版本) wget https://github.com/google/snappy/archive/refs/tags/1.1.8.tar.gz tar -xzf 1.1.8.tar.gz cd snappy-1.1.8 # 创建构建目录并编译安装 mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX/usr/local/snappy-1.1.8 .. make -j$(nproc) sudo make install cd ../..安装完成后需要让系统知道Snappy库的位置echo export LD_LIBRARY_PATH/usr/local/snappy-1.1.8/lib64:$LD_LIBRARY_PATH ~/.bashrc echo export SNAPPY_HOME/usr/local/snappy-1.1.8 ~/.bashrc # 可选便于管理 source ~/.bashrc验证Snappy安装# 检查头文件和库文件是否存在 ls /usr/local/snappy-1.1.8/include/snappy.h ls /usr/local/snappy-1.1.8/lib64/libsnappy.*3. Hadoop源码获取与编译前关键配置环境准备好了现在轮到主角Hadoop上场。编译的成败一半取决于环境另一半则取决于对源码构建配置的精准把控。3.1 获取Hadoop 3.1.4源码从Apache官方镜像下载源码包这是最稳妥的方式。wget https://archive.apache.org/dist/hadoop/common/hadoop-3.1.4/hadoop-3.1.4-src.tar.gz tar -xzf hadoop-3.1.4-src.tar.gz cd hadoop-3.1.4-src解压后你会看到一个非常庞大的源码目录。我们的编译操作主要将在根目录下进行。3.2 配置Maven加速与编译参数国内的网络环境直接使用Maven中央仓库可能会非常慢甚至超时。我强烈建议配置阿里云的Maven镜像。编辑Maven的全局配置文件~/.m2/settings.xml如果不存在就创建settings mirrors mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors /settings接下来是决定编译成败的关键一步配置Hadoop的编译选项。我们需要通过修改源码树中的配置文件明确告诉构建系统我们要启用Snappy并且告诉它我们自定义的Snappy库路径在哪里。编辑文件hadoop-3.1.4-src/hadoop-project-dist/pom.xml。在这个文件里我们需要找到关于Snappy的配置部分。通常它会被profile配置文件管理。我们需要确保激活Snappy支持的profile并检查其参数。更直接有效的方法是在编译时通过Maven命令行参数来指定。但是经过多次实践我发现最可靠的方式是直接设置环境变量因为Hadoop的start-build-env.sh脚本和Maven的nativeprofile会读取这些变量。在开始编译前设置以下环境变量# 在hadoop-3.1.4-src目录下执行 export SNAPPY_HOME/usr/local/snappy-1.1.8 export SNAPPY_LIBRARY$SNAPPY_HOME/lib64 export SNAPPY_INCLUDE$SNAPPY_HOME/include此外还需要确保系统能够找到我们安装的protobufexport PROTOC_PATH/usr/local/protobuf-2.5.0/bin/protoc export PROTOC_VERSION2.5.0踩坑记录我第一次编译时忽略了PROTOC_PATH的设置导致Maven在编译protobuf生成的Java文件时错误地使用了系统可能存在的其他版本protoc命令造成了版本不匹配编译过程在hadoop-common模块报出奇怪的语法错误。明确指定PROTOC_PATH可以根治此问题。3.3 解决潜在的依赖缺失问题CentOS 7的默认仓库可能缺少一些开发库需要额外安装# 安装编译所需的额外开发包 sudo yum install -y zlib-devel openssl-devel cmake3 gcc-c make pkgconfig # 安装JNIJava Native Interface头文件这是Java调用本地C库的桥梁 sudo yum install -y java-1.8.0-openjdk-devel4. 执行编译与生成分发版万事俱备只欠编译。Hadoop的编译命令相对统一但选项很重要。4.1 编译命令与目标选择在hadoop-3.1.4-src目录下执行以下命令进行编译# 关键命令-P指定激活的profile-D指定属性-T设置线程数加速编译 mvn clean package -Pdist,native -DskipTests -Dtar -Dmaven.javadoc.skiptrue -Drequire.snappy -Dsnappy.lib$SNAPPY_LIBRARY -Dsnappy.include$SNAPPY_INCLUDE -T 1C让我们拆解这个命令clean package清理旧的构建结果并打包。-Pdist,native激活dist生成分发版和native编译本地代码两个profile。nativeprofile是启用Snappy等本地压缩库的关键。-DskipTests跳过单元测试大幅加速编译。首次编译建议跳过确保二进制包生成后再单独跑测试。-Dtar最终生成一个.tar.gz格式的分发包。-Dmaven.javadoc.skiptrue跳过Javadoc生成节省时间。-Drequire.snappy明确要求构建系统包含Snappy支持。-Dsnappy.lib$SNAPPY_LIBRARY -Dsnappy.include$SNAPPY_INCLUDE这是最关键的参数它直接告诉Maven构建插件我们的Snappy库文件和头文件的具体路径避免它去系统默认路径寻找可能找不到或找到错误版本。-T 1C让Maven使用与CPU核心数相同的线程进行并行构建充分利用多核性能。编译过程会持续较长时间取决于机器性能可能在30分钟到2小时不等。Maven会从网络下载大量依赖项配置了阿里云镜像会快很多然后依次编译上百个模块。4.2 编译输出与结果验证编译成功后你会在hadoop-dist/target/目录下找到生成的分发包ls hadoop-dist/target/hadoop-3.1.4.tar.gz这个hadoop-3.1.4.tar.gz就是我们最终需要的、集成了Snappy本地支持的Hadoop二进制发行版。如何验证Snappy是否真的被编译进去了呢有两种方法检查发布包内的本地库tar -tzf hadoop-dist/target/hadoop-3.1.4.tar.gz | grep snappy你应该能看到类似lib/native/libsnappy.so.1或lib/native/libhadoopsnappy.so这样的文件。这表明Snappy的动态库已经被打包进去了。解压后使用Hadoop命令检查更可靠tar -xzf hadoop-dist/target/hadoop-3.1.4.tar.gz -C /tmp/ cd /tmp/hadoop-3.1.4 # 运行checknative命令这个命令是Hadoop自带的用于检查本地库的支持情况 bin/hadoop checknative如果一切顺利你会在输出中看到关于snappy的一行显示为true。例如Native library checking: hadoop: true /tmp/hadoop-3.1.4/lib/native/libhadoop.so.1.0.0 zlib: true /usr/lib64/libz.so.1 snappy: true /usr/local/snappy-1.1.8/lib64/libsnappy.so.1 ...看到snappy: true并且后面指向了你自定义的库路径就大功告成了5. 疑难杂症排查与解决方案实录编译过程很少一帆风顺尤其是在CentOS 7这样的环境中。下面是我遇到过的几个典型问题及解决方法。5.1 编译错误Could not find protoc错误信息[ERROR] Failed to execute goal org.apache.hadoop:hadoop-maven-plugins:3.1.4:protoc (compile-protoc) on project hadoop-common: Could not find protoc: /usr/local/protobuf-2.5.0/bin/protoc原因分析Maven的hadoop-maven-plugins插件在调用protoc命令时没有从我们设置的环境变量PROTOC_PATH中读取或者插件配置的路径不对。解决方案首先确认/usr/local/protobuf-2.5.0/bin/protoc文件是否存在且可执行 (ls -la查看)。最根本的解决方法是在编译命令中通过-D参数强制指定mvn clean package ... -Dprotoc.path/usr/local/protobuf-2.5.0/bin/protoc ...也可以尝试创建一个软链接到/usr/bin目录下但这可能影响系统其他软件sudo ln -s /usr/local/protobuf-2.5.0/bin/protoc /usr/bin/protoc5.2 编译错误snappy.h: No such file or directory错误信息fatal error: snappy.h: No such file or directory #include snappy.h原因分析编译器在预处理阶段找不到Snappy的头文件。虽然我们设置了SNAPPY_INCLUDE环境变量但Maven的native-maven-plugin可能没有正确传递这个路径给gcc。解决方案确保编译命令中明确指定了-Dsnappy.include参数并且路径绝对正确。可以尝试手动将Snappy头文件链接到系统标准包含路径临时方案sudo ln -s /usr/local/snappy-1.1.8/include/snappy* /usr/local/include/检查hadoop-common模块的pom.xml看其中关于native编译的配置是否写死了其他路径。5.3 编译成功但checknative显示snappy为false现象编译过程没有报错生成的分发包也很大但运行hadoop checknative时snappy一项显示为false。原因分析库文件未正确打包编译生成的libhadoopsnappy.so可能没有被复制到最终的lib/native目录。运行时链接失败系统在运行时找不到libsnappy.so.1这个文件。我们的编译链接可能通过了因为指定了-L路径但运行时动态链接器ld的搜索路径LD_LIBRARY_PATH没有包含Snappy库的路径。解决方案解压分发包检查lib/native/目录下是否有libhadoopsnappy.so或libsnappy.so相关的文件。最关键的一步在运行Hadoop命令如checknative之前必须将Snappy的库路径加入到LD_LIBRARY_PATH环境变量中并且要放在Hadoop自己的native库路径之前。export LD_LIBRARY_PATH/usr/local/snappy-1.1.8/lib64:$HADOOP_HOME/lib/native:$LD_LIBRARY_PATH bin/hadoop checknative如果加上这个路径后就显示true了那么你就需要在所有Hadoop集群节点的启动环境例如hadoop-env.sh中都配置这个变量。5.4 编译过程卡在下载依赖或内存不足现象Maven编译卡住长时间不动或者报出java.lang.OutOfMemoryError。解决方案网络问题确认settings.xml镜像配置正确。可以尝试在编译命令后添加-o参数使用离线模式前提是本地仓库已缓存所有依赖。内存不足调整Maven的JVM内存参数。可以设置环境变量export MAVEN_OPTS-Xmx2048m -XX:MaxPermSize512m磁盘空间不足清理Maven本地仓库~/.m2/repository中旧的、不完整的依赖或增加磁盘空间。5.5 编译问题速查表问题现象可能原因排查步骤与解决方案protoc命令未找到1. protobuf未安装或安装路径不对。2. 环境变量未生效。1.which protoc检查。2. 编译命令添加-Dprotoc.path/path/to/protoc。snappy.h找不到Snappy头文件路径未传递给编译器。1. 确认-Dsnappy.include参数。2. 检查SNAPPY_HOME/include下是否有snappy.h。链接失败找不到-lsnappySnappy库文件路径未传递给链接器。1. 确认-Dsnappy.lib参数。2. 检查SNAPPY_HOME/lib64下是否有libsnappy.so。checknative显示snappy为false1. 本地库未正确编译打包。2. 运行时缺少libsnappy.so.1。1. 检查分发包内lib/native目录。2.设置运行时LD_LIBRARY_PATH。Maven下载依赖极慢默认中央仓库网络连接差。配置阿里云Maven镜像 (settings.xml)。编译报gcc错误开发工具链不完整或版本过低。安装gcc-c、make、cmake3并升级autoconf/automake/libtool。6. 编译后部署与性能验证建议成功编译出集成Snappy的Hadoop分发包后工作只完成了一半。如何部署和验证其效果才是最终目的。6.1 替换现有Hadoop部署如果你已经有一个Hadoop集群替换时需要谨慎将新编译的hadoop-3.1.4.tar.gz分发到所有集群节点。在每个节点上设置好LD_LIBRARY_PATH确保包含Snappy库路径。最好将其写入$HADOOP_HOME/etc/hadoop/hadoop-env.sh文件中export LD_LIBRARY_PATH/usr/local/snappy-1.1.8/lib64:$HADOOP_HOME/lib/native:$LD_LIBRARY_PATH停止集群服务备份旧的Hadoop目录解压新版本并替换。启动集群并逐一检查各服务的日志确保没有出现关于本地库加载的错误。6.2 配置Hadoop使用Snappy压缩仅仅编译了支持库还不够需要在Hadoop配置文件中显式启用Snappy压缩。核心配置 (core-site.xml)可以设置默认的压缩编解码器但通常更推荐在具体作业或输出格式中指定。property nameio.compression.codecs/name valueorg.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec/value /propertyMapReduce作业中启用在提交MapReduce作业时通过配置参数指定。hadoop jar your-job.jar YourDriverClass \ -D mapreduce.map.output.compresstrue \ -D mapreduce.map.output.compress.codecorg.apache.hadoop.io.compress.SnappyCodec \ -D mapreduce.output.fileoutputformat.compresstrue \ -D mapreduce.output.fileoutputformat.compress.codecorg.apache.hadoop.io.compress.SnappyCodec \ input_path output_pathHDFS写入时压缩在写入HDFS文件时例如通过Hive、Spark或直接使用hdfs dfs -put可以指定压缩格式。6.3 性能验证简易方法如何知道Snappy是否真的起了作用一个简单的测试是准备一个较大的文本文件例如几百MB的日志文件。使用未压缩和Snappy压缩两种方式将其存入HDFS对比写入时间、文件大小和读取时间。# 上传未压缩文件 time hdfs dfs -put largefile.log /test/uncompressed.log # 上传时启用Snappy压缩 time hdfs dfs -D dfs.output.compresstrue -D dfs.output.compression.codecorg.apache.hadoop.io.compress.SnappyCodec -put largefile.log /test/compressed.snappy # 检查文件大小 hdfs dfs -du -h /test # 比较读取时间 time hdfs dfs -cat /test/uncompressed.log /dev/null time hdfs dfs -cat /test/compressed.snappy /dev/null通常你会发现压缩后的文件体积显著减小但不如Gzip/BZip2压缩得狠而压缩和解压读取的速度非常快CPU占用也更低。这种“空间换时间”的平衡正是Snappy在大数据场景下的价值所在。整个编译过程虽然步骤繁多但每一步都有其明确的目的。从解决陈旧的系统工具链到精心配置每一个依赖库的路径再到最后那行决定性的Maven命令本质上是在为Hadoop打造一个量身定制的、高性能的运行时基础。当你看到hadoop checknative输出那一行snappy: true时那种对系统底层细节的掌控感以及为后续数据处理任务扫清性能障碍的踏实感可能就是技术人独有的乐趣吧。记住在分布式系统里I/O往往是最大的瓶颈之一而一个合适的压缩算法可能就是撬动瓶颈的那根最有效的杠杆。
返回列表