登录

  • 登录
  • 忘记密码?点击找回

注册

  • 获取手机验证码 60
  • 注册

找回密码

  • 获取手机验证码60
  • 找回
毕业论文网 > 毕业论文 > 电子信息类 > 通信工程 > 正文

Hadoop平台的搭建与应用毕业论文

 2022-05-16 20:31:46  

论文总字数:21397字

摘 要

面对互联网上的海量数据,单台主机已无法满足其存储和计算要求,使用分布式存储和分布式计算去分析这些数据,并挖掘其内在价值成为了必然的趋势。其中Hadoop是应用较多的开源分布式存储和计算框架之一。

首先,本文详细介绍了Hadoop的概述、分本市存储系统的架构与设计和Hadoop的核心Map/Reduce的概述。然后,本文搭建了Hadoop的集群环境,并且详细介绍了在linux环境下的搭建过程。并在Hadoop平台下,利用Pig脚本编程语言解决了一个关于区域性人群流动的实际模型问题。

最后,本文成功完成了预期目标,同时总结了本次实验的结果,发现了新的问题用于以后的进一步的研究。

关键词:Hadoop 集群环境 分布式文件系统 Pig

Hadoop platform building and applications

Abstract

In the face of huge amounts of data on the Internet,single host has been unable to meet the requirements of the storage and computing,the use of distributed storage and distributed computing to analyze these data, and explore its intrinsic value has become the inevitable trend. The Hadoop is one of open source distributed storage and computing framework.

First of all,this article introduced the overview of Hadoop,which points the storage system architecture and design in the city and the core of the Hadoop Map/Reduce overview. Then, this paper sets up a Hadoop cluster environment,and introduces in detail the building process in the Linux environment. And in Hadoop platform,use Pig script programming language to solve a question about the actual model of regional population moving.

Finally, we successfully completed the target, while summarizes the results of this experiment, found a further study of new problems for the future.

Key Words: Pig; HDFS; Hadoop cluster environment

目 录

摘 要 II

Abstract III

第一章 引言 6

1.1 Hadoop的发展背景与现状 6

1.2 本文工作介绍 7

第二章 Hadoop系统基础 9

2.1 HDFS的架构与设计 9

2.1.1 HDFS的前提与设计目标 9

2.1.2 Namenode 和 Datanode 10

2.1.3 文件系统的名字空间 (namespace) 11

2.1.4 数据复制 12

2.1.5 文件系统元数据的持久化 13

2.1.6通讯协议 14

2.1.7健壮性 14

2.1.8 数据组织 15

2.1.9可访问性 16

2.1.10 存储空间回收 16

2.2 Hadoop分布式计算 17

2.2.1 Map/Reduce概述 17

第三章 Hadoop平台的搭建过程 19

3.1 Hadoop安装环境准备 19

3.2 Hadoop集群搭建 19

第四章 Hadoop平台基于pig的应用 24

4.1 区域用户流动性分析 24

4.1.1 模型分析 24

4.1.2 建立数学模型 25

4.2利用Pig脚本编程解决数学模型 25

4.2.1 解决过程 26

4.2.2 建模解决结果 30

第五章 结束语 31

5.1 论文工作总结 31

5.2 问题与展望 31

第一章 引言

1.1 Hadoop的发展背景与现状

Hadoop源于Google的分布式存储和分布式计算系统,它主要提供了一套名为HDFS(Hadoop Distributed File System)的分布式文件系统以及支持分布式计算的Map/Reduce计算框架。此外,还提供构建在HDFS和Map/Reduce之上的可扩展的数据仓库Hive、结构化数据库Hbase、数据流高层语言Pig、高性能分布式协同服务ZooKeeper等。

Hadoop类似系统出现的其中一个原因在于:硬盘存储容量快速增加的同时,数据访问速度却未能得到相同程度的提高。十年前的硬盘的读取与写入的能力与现在的能力虽然有了很大的提高,但是在现在磁盘的大多数的读写能力还是属于未被完全利用。

假设有100个磁盘,每个存储百分之一的数据,在这些磁盘并行运行的情况下不到两分钟时间就可以读完所有的数据,但是只使用一个磁盘的百分之一浪费了大部分的存储空间。进一步的解决方案是可以存储100个数据集,每个1TB,并让它们共享磁盘的访问。此类系统使用共享访问可以缩短分析时间,并且,从统计角度来看,这种分析工作会分散到不同的时间点,互相之间不会有太多干扰。

同时,使用多磁盘并行数据i/o和计算需要考虑以下的问题:

(1) 硬件故障。由于磁盘并不是一个非常稳定的硬件,每当磁盘的数量增加的时候,这个磁盘产生故障的概率也是成倍的增加的。RAID(独立冗余磁盘阵列)是其中一个实现。Hadoop的文件系统HDFS是另外一个例子,它采取的是一种与RAID稍有不同的方法。

(2) 大部分分析任务需要通过某种方式把数据合并起来,即从一个磁盘读取的数据需要和其他磁盘中读取的数据合并起来才能使用。各种不同的分布式系统能够组合多个来源的数据,但是如何保证正确性是比较困难的。Hadoop系统提供了一个数据存储和编程模型,它抽象出上述磁盘读写的问题,将其转化为由键值对组成的数据集的存储和计算过程,为用户屏蔽了下层的数据存取问题。这个数据i/o和计算操作由两个部分来完成:Map和Reduce。其中Map负责数据分发,Reduce负责数据的规约。

Hadoop类似系统出现的另一个原因在于磁盘驱动器的另一个发展趋势:在现在数据传输速度大大提高的同时,寻址的速度缺没有及时跟上前者的脚步。寻址是在硬盘中移动磁头的位置,这是一个物理的过程,这会产生非常大的时延。而硬盘的传输速率只是对应一个磁盘的传输带宽,这个能力却会被前者所牵绊,这样的后果是传输速率产生巨大的浪费。

根据上述原因,Hadoop系统的HDFS上的数据读写方式被设计为对大数据量的顺序读写,这样的顺序磁盘i/o方式不需要很多的磁盘寻址。同时,这样的数据i/o方式也使得Hadoop的应用受到一些限制,因为它不适用于数据的随机存取。

相对HDFS来说,常用的关系型数据库更适合用于数据的随机存取。Hadoop的分布式计算框架Map/Reduce构建于HDFS之上,是一种线性的可伸缩的计算框架。在这个框架中,应用者只需要编写两个函数:Map和Reduce。在使用这两个函数时可以不用过多考虑数据的大小或者这些函数正在使用的集群的特性,可以原封不动地应用到小规模数据集或者更大的数据集上。

存储由HDFS实现,分析由Map/Reduce实现。虽然Hadoop还有其他功能,但这两个功能是Hadoop的核心所在。Map/Reduce似乎采用的是一种蛮力方法,即针对每个查询,所有数据集都会被处理,这个特性限制了Hadoop的应用,使得它无法应对数据的随机存取。但在特定应用场合下,这也正是它的优势所在:Map/Reduce对整个数据集进行批处理和顺序读写,相对于随机读取来说,这种方式大大减少了磁盘i/o耗时。

1.2 本文工作介绍

第一章为引言部分,介绍了Hadoop的发展与现状,在现有硬盘技术瓶颈而hadoop能够有效的解决这个问题,分析hadoop在分析海量数据时的优势。

第二章为hadoop的系统基础,介绍了hadoop的分布式文件系统hdfs的架构与设计,从hdfs的整个架构详细介绍了分布式文件系统。还介绍Map/Reduce这个hadoop工作的核心原理。

第三章为hadoop平台的搭建过程,这一章分别介绍了hadoop的安装环境,在ubuntu的系统中安装java的工作环境,再在这个环境中安装hadoop的完全式分布环境。

第四章为基于hadoop平台的pig脚本编程语言解决实际问题。本文建立了一个实际的人口流动倾向性的问题模型,并建立了一个数学模型,通过pig脚本编程语言解决了这个实际问题。

第二章 Hadoop系统基础

2.1 HDFS的架构与设计

2.1.1 HDFS的前提与设计目标

1.硬件错误。硬件错误的发生率是非常高的。每一个分布式文件系统存储着大量的数据,而这些file system则有成千上万的服务器构成。在现实生活中,我们要遇到数目巨大的系统组件,每当其中的任何一个组件失效的时候,这个组件所映射的HDFS组件是不会正常处理和存储数据的。由这个问题可以看出,HDFS最重要的架构目标是检测错误与快速地纠正和解决这些错误文图。

2. 流式数据访问。由于在HDFS上的应用与大多数的应用有一定的差异性,导致在访问他们的时候需要使用流式的访问方式。在HDFS忽略了用户交互处理的问题之后,它更加强调数据批处理的方式。而数据批处理的好处在于它能够不仅解决数据访问导致的延迟过低的问题,还能够有助于数据访问所产生的高吞吐量。为了进一步的提高数据访问所产生的高吞吐量,设计者将POSIX标准设置中的不必要的硬性约束进行了一些改动。

3. 大规模数据集。由于在HDFS上的许多形形色色的文件的大小都会达到一个很大的数量级,比如GB,更有甚者会达到TB或者PB的大小。这些运行在HDFS上的巨大的数据集导致了一个必然结果就是HDFS必须有大文件的存储能力。整个HDFS不仅能使全部的数据传输的带宽提高,还能将一个集群里的节点扩展到数百个。

4. 简单一致性模型。HDFS的模型是一个“一次写入多次读取”的应用模型。做一个一般假设:一个文件在被创建,写人与关闭之后就不用去改变这个文件了。在这个假设的背景下,数据一致性的问题被简单化了,而且巨大吞吐量的数据访问可以实现了。这个模型可以使用网络爬虫之类的应用程序来实现,设计者们计划在将来完善这个模型使其支持附加写这个操作。

5. 移动计算比移动数据更划算。关于一个应用效率的计算,最需要考虑的是离他操作的那个数据的距离,当这个距离越小,这个效率就会越大。这是因为越短的距离可以使网络阻塞所造成的影响会导致系统中数据吞吐量的提高。显而易见,当我们使用移动计算的时候可以使整个系统的效率提高,同时HDFS也存在为移动数据连接的接口。

6. 异构软硬件平台间的可移植性。在现如今各个平台迅速发展的时代,不同平台之间的移植是非常必要的,所以HDFS作为开源的分布式系统也必须拥有可移植性。这也有助于HDFS的推广。

2.1.2 Namenode 和 Datanode

图2-1 HDFS结构图

HDFS是核心之一就是Namenode 和Datanode。在整个集群之中,Namenode只有一个,而Datanode则是可以拥有许多个。因为Namenode在这个集群之中充当的是一个管理者的角色,而Datanaode则是执行者的角色。在一个节点之中一般只有一个Namenode,就像一艘船只有一个船长一样,只有船长可以发号施令。用户之所以能够在hdfs上存储数据,是因为HDFS将整个文件系统的name空间暴露了出来。存储在Dantanode上的数据往往被分成一个或者几个在内部的数据块。打开、关闭与重命名一个文件或者与这个文件相关的目录依靠Namenode的名字空间操作,同时数据块到具体Datanode节点的映射也需要依靠Namenode来完成。文件系统的客户端读出于写入的请求也是由Datanode负责处理。在商用机器上,Namenode和Datanode被设计成运行GNU/Linux操作系统(OS)。由于HDFS是是使用JAVA语言开发的,因此Namenode和Datanode可以部署到任何支持java的机器上面。为了增强HDFS的可移植性,所以HDFS采用了移植性不错的java语言,从而可以部署到多种类型的机器。在普遍是部署场景中,Namenode通常部署在一台机器上,而Datanode则部署在集群中的其他机器中(一台机器上可以部署多台datanode)。

单一的Namenode的结构可以使系统架构简化,由于Namenode管理着所有hdfs的元数据,namenode中不会存在用户数据。

图2-1 hdfs结构图

2.1.3 文件系统的名字空间 (namespace)

HDFS支持的文件存贮结构是传统型的。在目录中,用户或者app可以创建目录,然

图2-2 namenode与datanode

后再这些目录中保存。在文件系统中:用户可以进行创建与删除。虽然HDFS对于整个磁盘的额度并没有很强的控制,对于整个的系统也没有对于访问权限的控制,但是HDFS的架构不需要在现在的这个使其就实现这些特性。

2.1.4 数据复制

HDFS在设计的时候是成为一个能够跨越一个巨大的集群,在这个集群中,HDFS可以跨越几个机架来读取和存储文件。这些文件为了便于存储和处理,都必须被切割成多个相同大小的数据块。而这些数据块的副本则会被存储到Datanode 之中用来提高整个系统的容错性和稳定性。HDFS严格要求只有一个写入者在同一时刻写入文件,而每个文件只可以一次性写人。

在HDFS的管理中,Namenode通过定期从集群中的每一个Datanode中获得每一个节点检测信号和快状态报告。检测Datanode 是否能正常工作的的指标是Namenode能否接收到Datanode的心跳信号。一个Datanode上所有的数据块列表都被包含在Blockreport中。

1. 副本存放: 最最开始的一个步骤。HDFS由于最需要考虑的因素是整个系统的稳定性,而这个稳定性最重要的控制因素就是每一个文件的副本。而HDFS相对于其他大数据存储系统的不同之处也是这些副本的处理。HDFS将每一个文件复制多个副本,副本是数量与位置是这个系统最大的特点。

HDFS的运作环境往往需要不只一个机器,所以在现实往往需要搭建一个拥有多个计算机的集群,而在这个集群之中用户则需要配备交换机来使两个节点之间相互通信。如果两个机器在同一个机架上,那么他们之间的带宽会相比之下比较大一些。

由于在不同的机架上的不同节点上有许多个相同文件的副本,所以当一个机架发生不可挽回的故障或者错误的时候,别的机架上的文件的副本就成了这个文件的backup。这样的方式既提高了整个系统对故障发生应对机制,也能在很大程度上保证整个HDFS系统的稳定运行。虽然这样的方式会在短时间内发生同一个节点传输数量级别较高的数据,但是这还

2. 副本选择。因为HDFS中的文件副本是存储在位置不同的机架与节点上面,在hdfs需要读取一个文件的时候,整个系统会优先读取最靠近应用程序的那个副本。

2.1.5 文件系统元数据的持久化

Namenode上保存着一个HDFS的name space。Namenode会将每一个对于文件系统数据造成修改的操作用Editlog的事物日志进行记录。例如,Namenode会记录下HDFS创建一个文件或者HDFS修改文件的副本系数的过程。Editlog则是存储在本地操作系统的文件系统中。而在本地文件系统中还有一个叫做Fsimage的文件,这里存储数据块到文件的映射与文件属性等内容。

2.1.6通讯协议

TCP/IP协议是所有HDFS通讯协议的基础。客户端通过ClientProtocol协议与Namenode交互,通过一个可设置的TCP端口连接到Namenode。而Datanode使用DatanodeProtocol协议与Namenode交互。

2.1.7健壮性

HDFS能够在出错的情况下保证存储在HDFS上面的数据是完整性与可靠性。而出现最多的三种出错情况是 :Namenode出错, Datanode出错和网络割裂(network partitions)。

1. 磁盘数据错误,心跳检测和重新复制。Namenode会通过检测是否与Namenode是否失去联系来检测网络是否割裂的情况,而这个检测则是依靠心跳信号来检测。Namenode如果发现一些机器不再发送周期性的检测信号,则不再发送新的串口请求给他们。Datanode上存储的数据是否有效则取决于是否发生了宕机的情况。而这个Datanode会有一些修正机制来纠正这个宕机的操作,Namenode会不断地检测一些副本系数低于正常值的数据部分,如果这些数据部分被发现了,那么这些部分的数据就会被复制,而如果更有甚者发生了datanode节点失效的情况,或者硬盘发生了无法解决的错误,那么需要重新复制数据来解决这些错误。

2. 集群均衡。HDFS需要平衡各个节点的数据请求,因为如果在同一时间有过多的数据请求,那么系统也会增加产生错误的概率,这个时候这个控制集群平衡的系统则会将这些大量请求的数据送到其他未工作的datanode中,同时这个系统也会为这些文件创建一个新的副本来解决这些问题。

3.数据完整性。由于在数据的传输过程中,任何人都无法保证每一个数据的完整性,而产生这个问题的原意多种多样,可能是网络问题,也可能是设计问题。但是HDFS设计了一套检查来避免这个问题的发生。这个检查是通过一个校验来完成,每一个新创建的HDFS文件都会被计算这个数据块的校验和,并被作为一个单独的隐藏文件保存在一个HDFS的Name Space中。而这个校验和的作用则是每当这个文件传输完成之后都会在接收端来计算接收到数据的校验和来和接收到的隐藏文件的这个校验和比较,以检查传输过程数据是否文完整。如果不完整,则可以再另一个节点再次申请传输同样的文件。

4. 元数据磁盘错误。FsImage和Editlog是用来保证整个保存在HDFS上面的文件数据的完整和安全的重要文件。但是这两个文件会在HDFS上面的文件每一次发生变化的时候产生相对应的修改,而这个修改会占用大量的Namenode的处理事务的数量,虽然这个数量并不是一个小数目,而且在多个副本同时工作的时候,这个数量会更大。而HDFS却不得不执行这些操作,因为这些操作能够保证HDFS上面数据我稳定性。在HADOOP一代之中,Namenode的单点故障问题是无法完美解决的,这需要人工在设计上进行一定的干预,不过这个问题会在2.0的版本中完美解决。

2.1.8 数据组织

1. 数据块。因为HDFS是一个处理和存储大文件的分布式存储系统,同时它也被要求数据被存储一次而需要被多次读出。在这个背景之下,这些巨大的数据往往被分割成一个个较小的数据块,这些数据块既有利于存储,也有利于多次读取。而且由于数据块比较小,它也适应在Datanode中副本分布存储在不同节点的方式。整个存储方式都提高了HDFS的稳定性。

2.Staging。在整个客户端创建文件的过程中,Namenode并不会直接创建文件,因为这样对整个系统并不稳定。在现实的情况中,整个HDFS是通过一个临时文件来过渡这个创建文件的过程的,在一开始这个文件会被缓存到一个本地的临时文件中,而且这个临时文件会积累一定的数据,直到这个文件不够满足这个客户端对创建文件的数量时,这个客户端才会将这个临时文件中的数据一个个保存到Namenode的各个机架的各个节点之中。在这个过程中是先由Namenode分配一个数据块,再将Datanode中的标识符与位置给这个客户端让它知道将数据存储到什么地方。而如果在文件存储完毕前关闭了这个客户端,这个临时文件仍会继续上传数据,不过这个过程会保存到操作日志之中。

这个使用临时文件作为缓存的方法是在文件进行流式写人的前提之下的,这个方法能够缓解整个HDFS系统的网络环境,这在一定程度上提高了整个系统的效率。

3. 流水线复制。由于在前文所说的那样,在客户端上传文件的时候是先存储到一个本地的临时文件之中的,而只有当这个临时文件达到无法再继续存储缓存的时候才会向Namenode申请传输数据。而这个传输数据的过程是将临时文件中的数据一部分一部分进行传输的,而且会将每个部分同时传输到不同的节点,在不同的节点进行副本的保存,这样就形成的流水线的数据传输,每一个节点都不断接收临时文件上传的数据。

2.1.9可访问性

由于HDFS是使用JAVA进行编程的分布式文件系统,为了满足HDFS的可移植性,它必须提供多种不同的接口让不同的编程语言来移植HDFS。在HDFS中,用户既可以使用C语言来封装API接口,也可以使用浏览器的方式。

1. DFSShell。HDFS提供了一种普通用户非常熟悉的SHELL语言来让file和目录的形式来存储数据。

2. DFSAdmin。DFSAdmin 只有HDSF的管理员才能使用命令用来管理HDFS集群。

3. 浏览器接口。Hdfs会在安装的时候就提供一个TCP的端口来为以后的WEB服务器再访问HDFS的时候提供一个暴露的端口。

2.1.10 存储空间回收

1. 文件的删除和恢复。在HDFS中对删除的文件有一个保护机制,每一个被执行擅长的命令的文件并不会立刻被删除,而是会被先进行重命名的命令,然后再转移到/trash目录。在这个目录中的文件都能够被保护,每当用户发现删除错了文件就可以立刻从这个目录中恢复文件。不过这个目录中是由一定的上限的,不能无限的保存文件,所以需要为这个目录中的文件设置一个上限的停留时间,当超过这个时间之后,这个文件的空间就会被释放用以存储其他被执行删除命令的文件。不过在这个过程中会有一定的延迟。只要这个文件还在这个目录中用户就可以立即恢复数据,不过在这个目录中只存储最后的一个副本文件。

2. 减少副本系数。每个文件的副本数量都与Namenode设置的副本系数有关,但是每次用户改变这个副本系数的时候,Namenode会将这个多余的副本删除,这个过程会在每一次Namenode与Datanode的心跳检测的时候修正这个副本数量。这样会即使清理集群的存储空间,以防多余的文件副本占用多余的空间。

2.2 Hadoop分布式计算

2.2.1 Map/Reduce概述

Hadoop Map/Reduce是一个基于java软件框架,在这个框架上面可以写出可以运行在巨大的集群上面的数据处理程序。与一般的数据处理程序不同的是,在这个平台上用户可以处理TB级别以上的巨大级别的数据。

Map/Reduce在整个运行的过程中最开始的步骤是将用户输入的数据进行一定的切割,因为往往输入的大数据无法一次性操作,转换成小数据块可以便于处理。这个过程可以由Map任务的方式完成,这任务可以将数据进行并行处理。这个Map/Reduce会对整个map的输出首先进行排序,然后将这个结果交给reduce任务。在这个过程中的所有数据都会在分布式文件系统中进行读写。

为了提高整个系统的运行速度,Map/Reduce的框架与HDFS通常会在同一个节点上进行计算操作与读写的操作,这样既节省了带宽,也提高了整个过程的处理过程。节省了大量的数据传输所需要的时间。

Map/Reduce的框架与HDFS类似,master Jobtracker与slave TaskTracker共同组成一个Map/Reduce框架。master Jobtracker只有单独的一个,而slave TaskTracker则是每个节点一个。Master是一个监控者,它控制着所有节点上的每一个TaskTracker上面的任务的执行。Master在监考的同时也可以提高一定的容错性,因为它可以纠正slaves的执行错误,发现错误会命令slaves再次执行。

每个应用程序需要指明input/output的路径,并在整个程序的编写过程中提供给MAP和Reduce函数。这些信息加上其他的一系列参数构成了job configuration。然后这些job client再将这些数据通过接口提供给JobTracker。而这些数据则是通过后者来分发给slaves,再由这个JobTracker来监控他们的执行,并将返回信息提供给job-client。

2.2.2 Map/Reduce概述

Map/Reduce框架是一个基于java软件框架,在这个框架上面可以写出可以运行在巨大的集群上面的数据处理程序,这个程序可以实现大数据处理的自动化和分布式运行。用户在Map/Reduce的过程中首先接收用户自定义的key/value Pair值,然后将这些值的集合放入一个库中,并把所有的key值和value值集合在一起后传递给Reduce函数,它将会合并value的值并将结果放到一个比较小的集合之中。每次Reduce函数调用产生的0或1个输出value值再通过一个迭代器把value的值送给Reduce函数。

第三章 Hadoop平台的搭建过程

3.1 Hadoop安装环境准备

由于Hadoop是以JAVA语言编写的,随意Hadoop需要安装在linux的环境之中。现在linux环境有多种选择,主流的的选择有ubuntu,linux,centOS等等。我在这次毕业设计中选择的是ubuntu,因为ubuntu拥有比较完善的图形界面与非常完整的应用程序商店,许多与Hadoop相关的软件都可以在这个商店中找到并下载,这为我们开发Hadoop提供了很大的便利。

由于我的电脑安装的是windows7操作系统,所以我选择了用虚拟机的方式来安装linux的系统环境。关于虚拟机的选择,我用的是比较主流的是Vmware Workstation,这个虚拟机已经比较完美的契合ubuntu的系统,只需要在ubuntu的官网下载iso的系统镜像文件即可。

在安装完ubuntu的linux环境之后,经过简单的用户注册,首先需要在ubuntu中安装jdk,jdk可以再oracle官网找到并且下载。我下载jdk-8u45-linux-x64.tar.gz,下载到主目录,

  1. 通过终端在/usr/local目录下新建java文件夹,命令行sudo mkdir /usr/local/java。
  2. 然后将下载到压缩包拷贝到java文件夹中,命令行:cp jdk-8u45-linux-x64.tar.gz /usr/local/java。
  3. 然后进入java目录,命令行:cd /usr/local/java。
  4. 解压压缩包,命令行:sudo tar xvf jdk-8u45-linux-x64.tar.gz。
  5. 设置jdk环境变量,这里采用全局设置方法,它是是所有用户的共用的环境变量,$sudo gedit ~/.bashrc,打开之后在末尾添加:

export JAVA_HOME=/usr/local/java/jdk1.8.0_45

export JRE_HOME=${JAVA_HOME}/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib

请支付后下载全文,论文总字数:21397字

您需要先支付 80元 才能查看全部内容!立即支付

企业微信

Copyright © 2010-2022 毕业论文网 站点地图