1.Hadoop3.3.5集成Hive4+Tez-0.10.2+iceberg踩坑过程
2.HDFS和Burst都是源码基于POC共识机制,有什么区别?
3.Alluxio 客户端源码分析
4.scribe安装与使用
Hadoop3.3.5集成Hive4+Tez-0.10.2+iceberg踩坑过程
在集成Hadoop 3.3.5、编译Hive 4、源码Tez 0..2以及Iceberg 1.3的编译过程中,我们面对了诸多挑战,源码并在多方寻找资料与测试后成功完成集成。编译led控制器app源码以下为集成步骤的源码详细说明。
首先,编译确保Hadoop版本为3.3.5,源码这是编译Hive运行的前置需求。紧接着,源码安装Tez作为计算引擎。编译由于Tez 0..2的源码依赖版本为3.3.1,与当前的编译Hadoop版本不符,因此,源码我们需手动编译Tez以避免执行SELECT操作时出现的错误。编译前,下载官方发布的Tez源码(release-0..2),并解压以获取编译所需文件。编译过程中,注意更新pom.xml文件中的Hadoop版本号至3.3.5,同时配置protoc.path为解压后的protoc.exe路径,并添加Maven仓库源。gap缺口源码确保只编译tez-0..2-minimal.tar.gz,避免不必要的编译耗时。完成后,将编译好的文件上传至HDFS,并在主节点hadoop配置目录下新增tez-site.xml,同步配置至所有节点后重启集群。
Hive作为基于Hadoop的数据仓库工具,提供SQL查询和数据分析能力,新版本Hive 4集成了Iceberg 1.3,无需额外配置。本次集成步骤包括下载、解压、配置环境变量及初始化元数据。下载最新的Hive 4.0.0-beta-1版本,解压并配置环境变量,删除指定jar文件以避免提示错误。修改配置文件以设置Hive环境变量,并确保连接信息正确。初始化Hive元数据后,可以使用hive执行文件启动Hive服务。编写hive_management.sh脚本以实现Hive服务的管理。
通过beeline命令进行连接,est源码解析执行创建数据库和表的SQL语句,使用Hive进行数据插入和查询。值得注意的是,Hive 4.0.0-beta-1已集成Iceberg 1.3,因此无需额外加载jar包,只需将计算引擎设置为Tez。若需更新Iceberg版本,需下载Hive源码,修改依赖并编译特定包。
为了创建Iceberg分区表,使用熟悉的Hive命令语法,例如创建分区表时使用STORED BY ICEBERG。分区规范的语法也与Spark相似,可在HMS中获取Iceberg分区详细信息,并执行相应的数据转换操作。参考文档提供了从安装至配置的详细指导,确保了集成过程的顺利进行。
HDFS和Burst都是基于POC共识机制,有什么区别?
据我了解,POC(容量证明)共识机制是Burst团队在年研发的,其共识优势是设备成本低、利用空闲资源,oracle项目源码实现了人人皆可锻造的可能性。Burst将项目源代码进行共享。虽然由于经济模型和奖机制的问题,Burst项目并没有获得传统意义上的成功,但其源代码的分享为后来者提供许多启发。
而HDFS则是基于Burst开发的POC共识机制,对POC进行了优化和升级,弥补了POC存在的一些不足之处。至于详细优化了哪些,你可以去看看HDFS的白皮书。
Alluxio 客户端源码分析
Alluxio是一个用于云分析和人工智能的开源数据编排技术,作为分布式文件系统,采用与HDFS相似的主从架构。系统中包含一个或多个Master节点存储集群元数据信息,以及Worker节点管理缓存的数据块。本文将深入分析Alluxio客户端的实现。
创建客户端逻辑在类alluxio.client.file.FileSystem中,简单示例代码如下。
客户端初始化包括调用FileSystem.Context.create创建客户端对象的上下文,在此过程中需要初始化客户端以创建与Master和Worker连接的连接池。若启用了配置alluxio.user.metrics.collection.enabled,将启动后台守护线程定时与Master节点进行心跳传输监控指标信息。dubbo源码扩展同时,客户端初始化时还会创建负责重新初始化的后台线程,定期从Master拉取配置文件的哈希值,若Master节点配置发生变化,则重新初始化客户端,期间阻塞所有请求直到重新初始化完成。
创建具有缓存功能的客户端在客户端初始化后,调用FileSystem.Factory.create进行客户端创建。客户端实现分为BaseFileSystem、MetadataCachingBaseFileSystem和LocalCacheFileSystem三种,其中MetadataCachingBaseFileSystem和LocalCacheFileSystem对BaseFileSystem进行封装,提供元数据和数据缓存功能。BaseFileSystem的调用主要分为三大类:纯元数据操作、读取文件操作和写入文件操作。针对元数据操作,直接调用对应GRPC接口(例如listStatus)。接下来,将介绍客户端如何与Master节点进行通信以及读取和写入的流程。
客户端需要先通过MasterInquireClient接口获取主节点地址,当前有三种实现:PollingMasterInquireClient、SingleMasterInquireClient和ZkMasterInquireClient。其中,PollingMasterInquireClient是针对嵌入式日志模式下选择主节点的实现类,SingleMasterInquireClient用于选择单节点Master节点,ZkMasterInquireClient用于Zookeeper模式下的主节点选择。因为Alluxio中只有主节点启动GRPC服务,其他节点连接客户端会断开,PollingMasterInquireClient会依次轮询所有主节点,直到找到可以连接的节点。之后,客户端记录该主节点,如果无法连接主节点,则重新调用PollingMasterInquireClient过程以连接新的主节点。
数据读取流程始于BaseFileSystem.openFile函数,首先通过getStatus向Master节点获取文件元数据,然后检查文件是否为目录或未写入完成等条件,若出现异常则抛出异常。寻找合适的Worker节点根据getStatus获取的文件信息中包含所有块的信息,通过偏移量计算当前所需读取的块编号,并寻找最接近客户端并持有该块的Worker节点,从该节点读取数据。判断最接近客户端的Worker逻辑位于BlockLocationUtils.nearest,考虑使用domain socket进行短路读取时的Worker节点地址一致性。根据配置项alluxio.worker.data.server.domain.socket.address,判断每个Worker使用的domain socket路径是否一致。如果没有使用域名socket信息寻找到最近的Worker节点,则根据配置项alluxio.user.ufs.block.read.location.policy选择一个Worker节点进行读取。若客户端和数据块在同一节点上,则通过短路读取直接从本地文件系统读取数据,否则通过与Worker节点建立GRPC通信读取文件。
如果无法通过短路读取数据,客户端会回退到使用GRPC连接与选中的Worker节点通信。首先判断是否可以通过domain socket连接Worker节点,优先选择使用domain socket方式。创建基于GRPC的块输入流代码位于BlockInStream.createGrpcBlockInStream。通过GRPC进行连接时,每次读取一个chunk大小并缓存chunk,减少RPC调用次数提高性能,chunk大小由配置alluxio.user.network.reader.chunk.size.bytes决定。
读取数据块完成后或出现异常终止,Worker节点会自动释放针对该块的写入锁。读取异常处理策略是记录失败的Worker节点,尝试从其他Worker节点读取,直到达到重试次数上限或没有可用的Worker节点。
若无法通过本地Worker节点读取数据,则客户端尝试发起异步缓存请求。若启用了配置alluxio.user.file.passive.cache.enabled且存在本地Worker节点,则向本地Worker节点发起异步缓存请求,否则向负责读取该块数据的Worker节点发起请求。
数据写入流程首先向Master节点发送CreateFile请求,Master验证请求合法性并返回新文件的基本信息。根据不同的写入类型,进行不同操作。如果是THROUGH或CACHE_THROUGH等需要直接写入底层文件系统的写入类型,则选择一个Worker节点处理写入到UFS的数据。对于MUST_CACHE、CACHE_THROUGH、ASYNC_THROUGH等需要缓存数据到Worker节点上的写入类型,则打开另一个流负责将每个写入的块缓存到不同的Worker上。写入worker缓存块流程类似于读取流程,若写入的Worker与客户端在同一个主机上,则使用短路写直接将块数据写入Worker本地,无需通过网络发送到Worker上。数据完成写入后,客户端向Master节点发送completeFile请求,表示文件已写入完成。
写入失败时,取消当前流以及所有使用过的输出流,删除所有缓存的块和底层存储中的数据,与读取流程不同,写入失败后不进行重试。
零拷贝实现用于优化写入和读取流程中WriteRequest和ReadResponse消息体积大的问题,通过配置alluxio.user.streaming.zerocopy.enabled开启零拷贝特性。Alluxio通过实现了GRPC的MethodDescriptor.Marshaller和Drainable接口来实现GRPC零拷贝特性。MethodDescriptor.Marshaller负责对消息序列化和反序列化的抽象,用于自定义消息序列化和反序列化行为。Drainable扩展java.io.InputStream,提供将所有内容转移到OutputStream的方法,避免数据拷贝,优化内容直接写入OutputStream的过程。
总结,阅读客户端代码有助于了解Alluxio体系结构,明白读取和写入数据时的数据流向。深入理解Alluxio客户端实现对于后续阅读其他Alluxio代码非常有帮助。
scribe安装与使用
Scribe的安装与使用指南
要安装Thrift依赖,首先确保已安装以下软件:g++, boost, autoconf, libevent, Apache ant, JDK, PHP, 和python。其他脚本语言根据需要自行安装。 安装Thrift的步骤如下:参照扩展阅读~中的说明进行安装流程。
在thrift源代码目录下的tutorial目录中,使用`thrift -r –gen cpp tutorial.thrift`命令生成服务代码,包括对include文件的处理。
生成的代码会存放在gen-cpp目录下,接着切换到tutorial/cpp目录,执行`make`生成CppServer与CppClient。
运行这两个程序,确保它们能成功通信。
如果Hadoop自带的libhdfs不可用,可以按照以下步骤编译:在Hadoop根目录下输入`ant compile-c++-libhdfs -Dislibhdfs=true`,并配置HADOOP_HOME的CLASSPATH。 安装Scribe的步骤包括运行bootstrap脚本(参见扩展阅读)。可能遇到的错误及解决方法如下:当Boost不在默认目录时,配置命令如下:`./configure –with-boost=/usr/local/boost –prefix=/usr/local/scribe`。
如果运行examples时出现`ImportError: No module named scribe`,可能需要添加Python路径,如:`$export PYTHONPATH="/usr/lib/python2.6/site-packages/"`。
遇到`java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration`异常,需将Hadoop的classpath添加到环境变量中,如:`$export CLASSPATH=$HADOOP_HOME/hadoop-core-0..2+.jar[2]`。
安装完成后,可以参考扩展阅读8中的方法验证安装是否成功。