HDFS介绍
目录
编辑
一、HDFS基础
1.1 概述
1.2 HDFS的设计目标
1.2.1 硬件故障
1.2.2 流式数据访问
1.2.3 超大数据集
1.2.4 简单的一致性模型
1.2.5 移动计算而不是移动数据
1.2.6 跨异构硬件和软件平台的可移植性
1.3 基础概念
1.3.1 块(Block)
1.3.2 复制(Replica)
1.3.3 名字节点(Namenode)
1.3.4 Datanode
1.3.5 FileSystem
二、 HDFS架构
2.1 总体架构
2.1.1 角色功能
2.1.1.1 NameNode
2.1.1.2 DataNode
2.1.1.3 Client
2.1.2 元数据持久化
2.1.3 安全模式
2.1.4 SNN(SecondaryNameNode)
2.2 主从架构分析
2.2.1 单节点主从架构分析
2.2.1.1 主从分析
2.2.1.2 主从架构问题
2.3 解决方案
2.3.1 单点故障(HA集群方案)
2.3.1.1 总体架构
2.3.1.2 架构说明
2.3.1.3 架构角色说明
2.3.1.3.1 NameNode active
2.3.1.3.2 NameNode standby
2.3.1.3.3 JournalNode
2.3.1.3.4 zkfc(FailoverController)
2.3.1.3.5 ZooKeeper
2.3.2 压力过大,内存受限(联帮机制:Federation)
2.3.2.1 Federation 产生背景
2.3.2.1.1 单组Namenode架构
2.3.2.1.2 单组Namenode局限性
2.3.2.1.3 为什么要引入Federation?
2.3.2.2 Federation 介绍
2.3.2.2.1 Federation架构
2.3.2.3 Federation主要优点
2.3.2.3.1 Namespace的可扩展性
2.3.2.3.2 Performance(性能)
2.3.2.3.3 Isolation(隔离)
2.3.2.4 Federation 主要缺点
1)交叉访问问题
2)管理性问题
2.3.2.5 Federation局限性
三、HDFS读写流程
3.1 写流程
3.2 读流程
一、HDFS基础
1.1 概述
Hadoop分布式文件系统(HDFS)是指被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统(Distributed File System)。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。
1.2 HDFS的设计目标
1.2.1 硬件故障
硬件故障对于HDFS来说应该是常态而非例外。HDFS包含数百或数千台服务器(计算机),每台都存储文件系统的一部分数据。事实上,HDFS存在大量组件并且每个组件具有非平凡的故障概率,这意味着某些组件始终不起作用。因此,检测故障并从中快速自动恢复是HDFS的设计目标。
1.2.2 流式数据访问
在HDFS上运行的应用程序不是通常在通用文件系统上运行的通用应用程序,需要对其数据集进行流式访问。HDFS用于批处理而不用于用户的交互式使用,相对于数据访问的低延迟更注重数据访问的高吞吐量。
可移植操作系统接口(Portable Operating System Interface of UNIX, POSIX)标准设置的一些硬性约束对HDFS来说是不需要的,因此HDFS会调整一些POSIX特性来提高数据吞吐率,事实证明是有效的。
1.2.3 超大数据集
在HDFS上运行的应用程序具有大型数据集。HDFS上的一个文件大小一般在吉字节(GB)到太字节(TB)。因此,HDFS需要设计成支持大文件存储,以提供整体较高的数据传输带宽,能在一个集群里扩展到数百上千个节点。一个HDFS实例需要支撑千万计的文件。
1.2.4 简单的一致性模型
HDFS应用需要“一次写入多次读取”访问模型。假设一个文件经过创建、写入和关闭之后就不会再改变了。这一假设简化了数据一致性问题,并可实现高吞吐量的数据访问。MapReduce应用或网络爬虫应用都非常适合这个模型。将来还需要扩充这个模型,以便支持文件的附加写操作。
1.2.5 移动计算而不是移动数据
当应用程序在其操作的数据附近执行时,计算效率更高。当数据集很大时更是如此,这可以最大限度地减少网络拥塞并提高系统的整体吞吐量。HDFS为应用程序提供了接口,使其自身更靠近数据所在的位置。
1.2.6 跨异构硬件和软件平台的可移植性
HDFS的设计考虑到了异构硬件和软件平台间的可移植性,方便了HDFS作为大规模数据应用平台的推广。
从Hadoop这些年的发展来看,HDFS依靠上述特性,成为不断演进变革的大数据体系的坚实基石。
1.3 基础概念
1.3.1 块(Block)
Block是HDFS文件系统处理的最小单位,一个文件可以按照Block大小划分为多个Block,不同于Linux文件系统中的数据块,HDFS文件通常是超大文件,因此Block大小一般设置得比较大,默认为128MB。
1.3.2 复制(Replica)
HDFS通过冗余存储来保证数据的完整性,即一个Block会存放在N个Datanode中,HDFS客户端向Namenode申请新Block时,Namenode会根据Block分配策略为该Block分配相应的Datanode replica,这些Datanode组成一个流水线(pipeline),数据依次串行写入,直至Block写入完成。
1.3.3 名字节点(Namenode)
Namenode是HDFS文件系统的管理节点,主要负责维护文件系统的命名空间(Namespace)或文件目录树(Tree)和文件数据块映射(BlockMap),以及对外提供文件服务。
HDFS文件系统遵循POXIS协议标准,与Linux文件系统类似,采用基于Tree的数据结构,以INode作为节点,实现一个目录下多个子目录和文件。INode是一个抽象类,表示File/Directory的层次关系,对于一个文件来说,INodeFile除了包含基本的文件属性信息,也包含对应的Block信息。
数据块映射信息则由BlockMap负责管理,在Datanode的心跳上报中,将向Namenode汇报负责存储的Block列表情况,BlockMap负责维护BlockID到Datanode的映射,以方便文件检索时快速找到Block对应的HDFS位置。
HDFS每一步操作都以FSEditLog的信息记录下来,一旦Namenode发生宕机重启,可以从每一个FSEditLog还原出HDFS操作以恢复整个文件目录树,如果HDFS集群发生过很多变更操作,整个过程将相当漫长。
因此HDFS会定期将Namenode的元数据以FSImage的形式写入文件中,这一操作相当于为HDFS元数据打了一个快照,在恢复时,仅恢复FSImage之后的FSEditLog即可。
由于Namenode在内存中需要存放大量的信息,且恢复过程中集群不可用,HDFS提供HA(主/备Namenode实现故障迁移Failover)以及Federation(多组Namenode提供元数据服务,以挂载表的形式对外提供统一的命名空间)特性以提高稳定性和减少元数据压力。
1.3.4 Datanode
Datanode是HDFS文件系统的数据节点,提供基于Block的本地文件读写服务。定期向Namenode发送心跳。Block在本地文件系统中由数据文件及元数据文件组成,前者为数据本身,后者则记录Block长度和校验和(checksum)等信息。扫描或读取数据文件时,HDFS即使运行在廉价的硬件上,也能通过多副本的能力保证数据一致性。
1.3.5 FileSystem
HDFS客户端实现了标准的Hadoop FileSystem接口,向上层应用程序提供了各种各样的文件操作接口,在内部使用了DFSClient等对象并封装了较为复杂的交互逻辑,这些逻辑对客户端都是透明的。
二、 HDFS架构
2.1 总体架构
HDFS是一个典型的主/备(Master/Slave)架构的分布式系统,由一个名字节点Namenode(Master) +多个数据节点Datanode(Slave)组成。其中Namenode提供元数据服务,Datanode提供数据流服务,用户通过HDFS客户端与Namenode和Datanode交互访问文件系统。
如上图所示:HDFS把文件的数据划分为若干个块(Block),每个Block存放在一组Datanode上,Namenode负责维护文件到Block的命名空间映射以及每个Block到Datanode的数据块映射。
2.1.1 角色功能
2.1.1.1 NameNode
1)完全基于内存存储文件元数据、目录结构、文件block的映射
2)需要持久化方案保证数据可靠性
3)提供副本放置策略
2.1.1.2 DataNode
1)基于本地磁盘存储block(文件的形式)
2)并保存block的校验和数据保证block的可靠性
3)与NameNode保持心跳,汇报block列表状态
2.1.1.3 Client
1)和NameNode交互文件元数据和NameNode交互文件元数据
2)和DataNode交互文件block数据
2.1.2 元数据持久化
1)任何对文件系统元数据产生修改的操作,Namenode都会使用一种称为EditLog的事务日志记录下来
2)使用FsImage存储内存所有的元数据状态
3)使用本地磁盘保存EditLog和FsImage
4)EditLog具有完整性,数据丢失少,但恢复速度慢,并有体积膨胀风险
5)FsImage具有恢复速度快,体积与内存数据相当,但不能实时保存,数据丢失多
6)NameNode使用了FsImage+EditLog整合的方案:
滚动将增量的EditLog更新到FsImage,以保证更近时点的FsImage和更小的EditLog体积
2.1.3 安全模式
1)HDFS搭建时会格式化,格式化操作会产生一个空的FsImage
2)当Namenode启动时,它从硬盘中读取Editlog和FsImage
3)将所有Editlog中的事务作用在内存中的FsImage上
4)并将这个新版本的FsImage从内存中保存到本地磁盘上
5)然后删除旧的Editlog,因为这个旧的Editlog的事务都已经作用在FsImage上了
6)Namenode启动后会进入一个称为安全模式的特殊状态。
7)处于安全模式的Namenode是不会进行数据块的复制的。
8)Namenode从所有的 Datanode接收心跳信号和块状态报告。
9)每当Namenode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的。
10)在一定百分比(这个参数可配置)的数据块被Namenode检测确认是安全之后(加上一个额外的30秒等待时间),Namenode将退出安全模式状态。
11)接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他Datanode上。
2.1.4 SNN(SecondaryNameNode)
1)在非Ha模式下,SNN一般是独立的节点,周期完成对NN的EditLog向FsImage合并,减少EditLog大小,减少NN启动时间
2)根据配置文件设置的时间间隔fs.checkpoint.period 默认3600秒
3)根据配置文件设置edits log大小fs.checkpoint.size规定edits文件的最大值默认是64MB
Primary NameNode 和Secondary NameNode的数据合并流程如下图:
2.2 主从架构分析
2.2.1 单节点主从架构分析
2.2.1.1 主从分析
1)主从集群:结构相对简单,主与从协作
2)主:单点,数据一致好掌握
2.2.1.2 主从架构问题
1)单点故障,集群整体不可用
2)压力过大,内存受限
2.3 解决方案
2.3.1 单点故障(HA集群方案)
2.3.1.1 总体架构
2.3.1.2 架构说明
HA使用active NameNode和standbyNameNode两个节点解决单点问题,两个NameNode节点通过JournalNode集群共享状态,通过ZKFC(**FailoverController**)选举active,监控NameNode的状态,实现自动备源,DataNode会同时向两个NameNode节点发送心跳。
2.3.1.3 架构角色说明
2.3.1.3.1 NameNode active
1)接受Client的rpc请求并处理,自己写一份editlog,同时向JournalNode集群发送一份editlog
2)同时接受DataNode的块报告block report, 块位置更新block location updates和心跳heartbeat
2.3.1.3.2 NameNode standby
NameNode standby是NameNode active的一个热备,一旦切换active状态,可以及时对外提供服务
1)同样的会接受JournalNode上面的editlog,并执行更新,与NameNode active的元数据保持同样的状态
2)同时接受DataNode的块报告block report, 块位置更新block location updates和心跳heartbeat
2.3.1.3.3 JournalNode
用于同步active NameNode和standby NameNode之间的数据,本身由一组JournalNode节点组成的集群,一般是奇数,保证高可用。
2.3.1.3.4 zkfc(FailoverController)
主要用来监控NameNode节点的健康状态,zkfc会向zookeper集群发送心跳,让自己被选举,如果自己被选举主时,会通过rpc调用NameNode,让NameNode变成active状态。
2.3.1.3.5 ZooKeeper
ZooKeeper 分布式应用程序服务的组件,接收zkfc心跳和NameNode注册信息,选举出zkfc和NameNode的主。
2.3.2 压力过大,内存受限(联帮机制:Federation)
2.3.2.1 Federation 产生背景
2.3.2.1.1 单组Namenode架构
HDFS主要有两大模块:
1、Namespace(命名空间):由目录、文件和块组成,它支持所有命名空间相关的文件操作,如创建、删除、修改,查看所有文件和目录。
2、Block Storage Service(块存储服务):包括Block管理和存储两部分。
1)Block管理: 通过控制注册以及阶段性的心跳,来保证Datanode的正常运行;处理Block的报告信息和维护块的位置信息;支持Block相关的操作,如创建、删除、修改、获取Block的位置信息;管理Block的冗余信息、创建副本、删除多余的副本等。
2)存储: Datanode提供本地文件系统上Block的存储、读写、访问等。
通常情况下,单组Namenode能够满足集群大部分需求,单点故障问题可以通过启用HA解决,单组Namenode包含一主一备两个Namenode,通过Zookeeper保障及控制Failover,而Zookeeper本身具有高可用特性,好像完全不用担心单点故障造成集群不可用的问题,一切看起来似乎非常完美。然而,随着集群规模不断的增长,似乎又不是那么完美了。
2.3.2.1.2 单组Namenode局限性
单组Namenode只允许整个集群有一个活动的Namenode,管理所有的命名空间。随着集群规模的增长,在1000个节点以上的大型Hadoop集群中,单组Namenode的局限性越发的明显,主要表现在以下几个方面:
1)扩展性:Namenode内存使用和元数据量正相关。180GB堆内存配置下,元数据量红线约为7亿,而随着集群规模和业务的发展,即使经过小文件合并与数据压缩,仍然无法阻止元数据量逐渐接近红线。
2)可用性:随着元数据量越来越接近7亿,CMS GC频率也越来越高,期间也曾发生过一次在CMS GC过程中由于大文件“get Block location”并发过高导致的promotion fail。
3)性能:随着集群规模增长,Namenode响应的RPC QPS也在逐渐提高。越来越高并发的读写,与Namenode的粗粒度元数据锁,使Namenode RPC响应延迟和平均RPC队列长度都在慢慢提高。
4)隔离性:由于Namenode没有隔离性设计,单一对Namenode负载过高的应用,会影响到整个集群的服务能力
既然单组Namenode存在上述局限性,那么为什么要通过Federation的方式横向拓展Namenode,纵向拓展Namenode为什么不行?不选择纵向拓展Namenode的原因主要体现在以下三个方面:
1)启动时间长:Namenode启动需要将元数据加载到内存中,具有128 GB Java Heap的Namenode启动一次大概需要40分钟到1个小时,那512GB呢?
2)调试困难:对大JVM Heap进行调试比较困难,优化Namenode的内存使用性价比比较低。
3)集群易宕机:Namenode在Full GC时,如果发生错误将会导致整个集群宕机。
2.3.2.1.3 为什么要引入Federation?
1)采用Federation的最主要的原因是简单,Federation能够快速的解决大部分单Namenode的问题。
2)Federation是简单鲁棒的设计,由于联邦中各个Namenode之间是相互独立的。Federation整个核心设实现大概用了3.5个月。大部分改变是在Datanode、Config和Tools,而Namenode本身的改动非常少,这样Namenode的原先的鲁棒性不会受到影响。比分布式的Namenode简单,虽然这种事先的扩展性比起真正的分布式的Namenode要小些,但是可以迅速满足需求。
3)Federation良好的向后兼容性,已有的单Namenode的部署配置不需要进行太大的改变就可以继续工作。
2.3.2.2 Federation 介绍
2.3.2.2.1 Federation架构
为了水平扩展名称服务,Federation使用多组独立的Namenodes/Namespaces。所有的Namenodes是联邦的,也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。Datanode被用作通用的数据块存储设备,每个DataNode要向集群中所有的Namenode注册,且周期性的向所有Namenode发送心跳和块报告,并执行来自所有Namenode的命令。
Federation架构与单组Namenode架构相比,主要是Namespace被拆分成了多个独立的部分,分别由独立的Namenode进行管理。
Block Pool(块池)
1)Block Pool允许一个命名空间在不通知其他命名空间的情况下为一个新的block创建Block ID。同时一个Namenode失效不会影响其下Datanode为其他Namenode服务。
2)每个Block Pool内部自治,也就是说各自管理各自的block,不会与其他Block Pool交流。一个Namenode挂掉了,不会影响其他NameNode。
3)当Datanode与Namenode建立联系并开始会话后自动建立Block Pool。每个block都有一个唯一的标识,这个标识我们称之为扩展块ID,在HDFS集群之间都是惟一的,为以后集群归并创造了条件。
4)Datanode中的数据结构都通过块池ID索引,即Datanode中的BlockMap,storage等都通过BPID索引。
5)某个Namenode上的NameSpace和它对应的Block Pool一起被称为NameSpace Volume。它是管理的基本单位。当一个NN/NS被删除后,其所有Datanode上对应的Block Pool也会被删除。当集群升级时,每个NameSpace Volume作为一个基本单元进行升级。
ClusterID
增加一个新的ClusterID来标识在集群中所有的节点。当一个Namenode被格式化的时候,这个标识被指定或自动生成,这个ID会用于格式化集群中的其它Namenode。
2.3.2.3 Federation主要优点
2.3.2.3.1 Namespace的可扩展性
HDFS的水平扩展,但是命名空间不能扩展,通过在集群中增加Namenode来扩展Namespace,以达到大规模部署或者解决有很多小文件的情况。
2.3.2.3.2 Performance(性能)
在之前的框架中,单个Namenode文件系统的吞吐量是有限制的,增加更多的Namenode能增大文件系统读写操作的吞吐量。
2.3.2.3.3 Isolation(隔离)
一个单一的Namenode不能对多用户环境进行隔离,一个实验性的应用程序会加大Namenode的负载,减慢关键的生产应用程序,在多个Namenode情况下,不同类型的程序和用户可以通过不同的Namespace来进行隔离。
2.3.2.4 Federation 主要缺点
1)交叉访问问题
由于Namespace被拆分成多个,且互相独立,一个文件路径只允许存在一个Namespace中。如果应用程序要访问多个文件路径,那么不可避免的会产生交叉访问Namespace的情况。比如MR、Spark任务,都会存在此类问题。
2)管理性问题
启用Federation后,HDFS很多管理命令都会失效,比如“hdfs dfsadmin、hdfs fsck”等,除此之外,“hdfs dfs cp/mv”命令同样失效,如果要在不同Namespace间拷贝或移动数据,需要使用distcp命令,指定绝对路径。
2.3.2.5 Federation局限性
在解决NameNode扩展能力方面,社区虽然提供了Federation,但这个方案有很强的局限性:
1)HDFS路径Scheme需要变为ViewFs,ViewFs路径和其他Scheme路径互不兼容,比如DistributedFileSystem无法处理ViewFs为Scheme的路径,也就是说如果启用,则需要将Hive meta、ETL脚本、MR/Spark作业中的所有HDFS路径均的scheme改为viewfs。
2)如果将fs.defaultFS的配置从hdfs://ns1/变为viewfs://ns/,将导致旧代码异常,通过脚本对用户上万个源码文件的分析,常用的HDFS路径风格多样,包括hdfs:///user、hdfs://ns1/user、/user等,如果fs.defaultFS有所更改,hdfs:///user将会由于缺失nameservice变为非法HDFS路径。
3)ViewFs路径的挂载方式与Linux有所区别:
如果一个路径声明了挂载,那么其同级目录都需要进行挂载,比如/user/path_one挂载到了hdfs://ns1/user/path_one上,那么/user/path_two也需要在配置中声明其挂载到哪个具体的路径上。
如果一个路径声明了挂载,那么其子路径不能再声明挂载,比如/user/path_one挂载到了hdfs://ns1/user/path_one上,那么其子路径也自动并且必须挂载到hdfs://ns1/user/path_one上。
4)一次路径请求不能跨多个挂载点:
由于HDFS客户端原有的机制,一个DFSClient只对应一个nameservice,所以一次路径处理不能转为多个nameservice的多次RPC。
对于跨挂载点的读操作,只根据挂载配置返回假结果。
对于跨挂载点的rename(move路径)操作,会抛出异常。
5)Federation架构中,NameNode相互独立,NameNode元数据、DataNode中块文件都没有进行共享,如果要进行拆分,需要使用DistCp,将数据完整的拷贝一份,存储成本较高;数据先被读出再写入三备份的过程,也导致了拷贝效率的低效。
6)Federation是改造了客户端的解决方案,重度依赖客户端行为。方案中NameNode相互独立,对Federation没有感知。另外HDFS为Scheme的路径,不受Federation挂载点影响,也就是说如果对路径进行了namespace拆分后,如果因为代码中的路径或客户端配置没有及时更新,导致流程数据写入老数据路径,那么请求依然是合法但不符合预期的。
三、HDFS读写流程
3.1 写流程
HDFS客户端通过调用DistributedFileSystem# create来实现远程调用Namenode提供的创建文件操作,Namenode在指定的路径下创建一个空的文件并为该客户端创建一个租约(在续约期内,将只能由这一个客户端写数据至该文件),随后将这个操作记录至EditLog(编辑日志)。NameNode触发副本放置策略,返回一个有序的DataNode列表,客户端将使用这些信息,创建一个标准的Hadoop FSDataOutputStream输出流对象。
HDFS客户端开始向HdfsData-OutputStream写入数据,由于当前没有可写的Block,DFSOutputStream根据副本数向Namenode申请若干Datanode组成一条流水线来完成数据的写入。
客户端的数据以字节(byte)流的形式写入chunk(以chunk为单位计算checksum(校验和))。若干个chunk组成packet,数据以packet的形式从客户端发送到第一个Datanode,再由第一个Datanode发送数据到第二个Datanode并完成本地写入,以此类推,直到最后一个Datanode写入本地成功,可以从缓存中移除数据包(packet)。
客户端执行关闭文件后,HDFS客户端将会在缓存中的数据被发送完成后远程调用Namenode执行文件来关闭操作。
Datanode在定期的心跳上报中,以增量的信息汇报最新完成写入的Block,Namenode则会更新相应的数据块映射以及在新增Block或关闭文件时根据Block映射副本信息判断数据是否可视为完全持久化(满足最小备份因子)。
1)Client和NameNode连接创建文件元数据
2)NameNode判定元数据是否有效
3)NameNode触发副本放置策略,返回一个有序的DataNode列表
4)Client和DataNode建立Pipeline连接
5)Client将块切分成packet(64KB),并使用chunk(512B)+chucksum(4B)填充
6)Client将packet放入发送队列dataqueue中,并向第一个DataNode发送
7)第一个DataNode收到packet后本地保存并发送给第二个DataNode
8)第二个DataNode收到packet后本地保存并发送给第三个DataNode
9)这一个过程中,上游节点同时发送下一个packet
3.2 读流程
HDFS客户端远程调用Namenode,查询元数据信息,获得这个文件的数据块位置列表,返回封装DFSIntputStream的HdfsDataInputStream输入流对象。
客户端选择一台可用Datanode服务器,请求建立输入流。
Datanode向输入流中写原始数据和以packet为单位的checksum。
客户端接收数据。如遇到异常,跳转至步骤2,直到数据全部读出,而后客户端关闭输入流。当客户端读取时,可能遇到Datanode或Block异常,导致当前读取失败。正由于HDFS的多副本保证,DFSIntputStream将会切换至下一个Datanode进行读取。与HDFS写入类似,通过checksum来保证读取数据的完整性和准确性。
1)为了降低整体的带宽消耗和读取延时,HDFS会尽量让读取程序读取离它最近的副本。
2)如果在读取程序的同一个机架上有一个副本,那么就读取该副本。
3)如果一个HDFS集群跨越多个数据中心,那么客户端也将首先读本地数据中心的副本。
好了,今天的HDFS内容就分享到这里!欢约大家点赞+收藏,有疑问也欢迎大家评论留言!
相关文章:

HDFS介绍
目录 编辑 一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块(Block) 1.3.2 复制…...

每日一题——两数之和
题目 给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。 (注:返回的数组下标从1开始算起,保证target一定可以由数组里面2个数字相加得到࿰…...

Maven: ‘mvn‘ is not recognized as an internal or external command
下载并配置好Maven之后,CMD测试安装是否成功:mvn -v 提示: mvn is not recognized as an internal or external command, operable program or batch file. 检查环境变量: MAVEN_HOME: %MAVEN_HOME%\bin: 看上去没问题&#x…...

CubeSLAM: Monocular 3D Object SLAM——论文简述
一、简介 提出一种在动态和静态环境中同时进行3D目标检测和定位建图的方法,并且能够互相提升准确度。具体地,对于3D目标,其位置、方向和尺寸通过slam进行了优化;而3D目标作为slam中的路标,可以提供额外的语义和几何约…...

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 2
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...
linux scp 拷贝文件到目标linux系统
scp -P 8866 -r jsonrpc/ root192.168.6.66:/folder_path...

Oracle-expdp报错ORA-39077、06502(Bug-16928674)
问题: 用户在使用expdp进程导出时,出现队列报错ORA-39077、ORA-06502 ORA-31626: job does not exist ORA-31638: cannot attach to job SYS_EXPORT_SCHEMA_01 for user SYS ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95 ORA-06512: at "SYS.KUPV$…...

Kafka入门,保姆级教学
文章目录 Kafka概念消息中间件对比消息中间件对比-选择建议Kafka常用名词介绍Kafka入门1. Kafka安装配置2.Kafka生产者与消费者关系3.Kafka依赖4.生产者发消息5.消费者接受消息6.Kafka高可用性设计6.1集群Kafka备份机制(Reolication) 7.kafka生产者详解7.1 发送类型7.2参数详解…...
RabbitMQ 过期时间(TTL)
TTL,Time to Live的简称,即过期时间,RabbitMQ可以对消息和队列设置TTL。 RabbitMQ支持设置队列的过期时间和消息的过期时间。如果设置队列的过期时间则队列中所有的消息都有相同的过期时间。如果设置消息的过期时间则每条消息的过期时间则可以不同。如两…...
C 语言练习题、持续更新
文章目录 C语言练习题读懂每个练习题才是学好一门代码的重要经历目录(先不要看答案,首先自己做才能更好的领悟,做不来没关系)题目一:有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数&…...
Android Q以上后台启动Activity初步尝试
在Android Q以后 google不允许在后台service 广播等等启动Activity 具体请看google文档从后台启动 Activity 的限制 | Android 开发者 | Android Developers 文档里有详细的说明,在哪种情况下可以后台启动Activity。 大体分为以下几种情况: 1、应用具有可见窗口,例如前…...
【torchlars】windows下载github中的torchlars包遇到的问题及解决方案
环境 python3.7 windows10 cuda11.1 pytorch1.8.1 虚拟环境miniconda 目的 windows下载github中的torchlars包 遇到的问题 问题一:直接下载好文件夹输入指令:python setup.py install 出现错误:RuntimeError: Error compiling objects f…...
SolidUI社区-通用Prompt技巧
背景 随着文本生成图像的语言模型兴起,SolidUI想帮人们快速构建可视化工具,可视化内容包括2D,3D,3D场景,从而快速构三维数据演示场景。SolidUI 是一个创新的项目,旨在将自然语言处理(NLP)与计算机图形学相…...
C++中类的封装写出一个文件加密的小项目
文件的加密较为简单,当然也可以修改它的加密方式等,供大家参考 #include<string> #include<fstream> class ReaderFile { public:string Read(const string& filename){cout << "读取文件,获取明文"<<…...

【网络编程·传输层】UDP和TCP的报头
目录 一、端口号划分 二、部分指令 1、pidof(用于查看进程id) 2、netstat(查看网络状态) 三、UDP协议 1、UDP协议格式 2、UDP协议如何进行封装、解包、分用 2.1封装、解包 2.2分用 3、UDP协议的特点 3.1UDP协议的特点 …...
C语言编程技巧 全局变量在多个c文件中公用的方法
在使用C语言编写程序时,经常会遇到这样的情况:我们希望在头文件中定义一个全局变量,并将其包含在两个不同的C文件中,以便这个全局变量可以在这两个文件中共享。举个例子,假设项目文件夹"project"下有三个文件…...
【HDFS】NN处理全量块汇报时reportDiff的一些细节
NN处理全量块汇报(FBR)时的一些细节怎么生成的toRemove怎么check 汇报上来的块是不是corrupt的?reportDiff方法里巧妙地引入delimiterBlock这个block的作用前置知识:【HDFS】Block、BlockInfo、BlockInfoContiguous、BlockInfoStriped的分析记录 上面的文章中介绍了关于Bl…...

JVM之类加载与字节码(一)
1.类文件结构 一个简单的HelloWorld.Java package cn.itcast.jvm.t5; // HelloWorld 示例 public class HelloWorld { public static void main(String[] args) { System.out.println("hello world"); } }编译为 HelloWorld.class 后的样子如下所示: […...

【数据结构OJ题】合并两个有序数组
原题链接:https://leetcode.cn/problems/merge-sorted-array/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 看到这道题,我们注意到nums1[ ]和nums2[ ]两个数组都是非递减的。所以我们很容易想到额外开一个数组tmp[ ]&#x…...

数据结构笔记--归并排序及其拓展题(小和问题、逆序对问题)
目录 1--归并排序 2--小和问题 3--逆序对问题 1--归并排序 归并排序的核心思想:将一个无序的序列归并排序为一个有序的系列;通过递归将无序的序列二分,从底层开始将二分的序列归并排序为有序序列; #include <iostream> #…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...