文档章节

分布式文档查重系统实现与思考

o
 osc_a22drz29
发布于 2019/03/27 08:25
字数 1064
阅读 11
收藏 0

前言

为了学习分布式系统,于是做了这个项目来练练手,这篇文章记录了这次实战的思考和踩过的坑。由于刚入门,因而文章可能会有错误,请读者勘误。

简单概述

项目采用 Spark 和 HDFS 做分布式计算和存储,利用 Spring Boot 提供 Web 服务,利用 Redis 存储任务标识符以便于集群扩展。

用户上传包含 Word 文档的压缩文件,Web 服务器所在机器解压压缩文件,接着提取文档内容并分词,然后将结果存储至 HDFS 上,再利用 Spark 进行相似度计算并返回结果。

HDFS 依赖问题

搭建 HDFS 很简单只需做简单配置便可,但问题都出在操作文件的代码编写上。

先是依赖问题,官网及网上都没有具体 Hadoop 依赖说明(也可能自己没找到),导致对需要导入那些依赖包很疑惑,下面是自己测试的操作 HDFS 所需要的最小依赖。

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>${hadoop.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs-client</artifactId>
    <version>${hadoop.version}</version>
</dependency>

HDFS 配置问题

获取 FileSystem 实例前需要创建一个 Configuration 实例,而在这之前必须设置本地 Hadoop 的目录,和设置远程机器的用户名。虽然这样做才能不报错,但一直不明白为什么操作远程机器的 HDFS,还需要本地安装的 Hadoop 目录。不过官方也提供了 HDFS 的 REST API,可以不依赖本地安装 Hadoop。

System.setProperty("HADOOP_USER_NAME", userName);
System.setProperty("hadoop.home.dir", home);
Configuration conf = new Configuration();
FileSystem.get(new URI("hdfs://host:port"), conf);

Spark 序列化问题

利用 Spark 进行计算时,最主要先获取 JavaSparkContext 的实例,以下为创建其实例的流程。

SparkConf conf = new SparkConf();
conf.setMaster("spark://host:port");
conf.setAppName("demo");
JavaSparkContext context = new JavaSparkContext(conf);

看似挺简单的流程,但问题就出在集群模式上。若是本地模式即指定 conf.setMaster("local") 进行调试,进行计算的代码可以完美运行,但是集群模式上就会出现序列化问题。

由于需要将代码分发给 Slave 节点的 Worker 进行计算,所以会产生代码的网络传输,而为了减少网络传输的延迟,Spark 只会分发部分代码,所以分发的代码若是不能进行序列化就会产生问题。

还有集群模式必须指定计算代码的 Jar 包路径,为了减少 Jar 的大小利于传输,采用了重新建立一个项目方案,然后在将该项目作为依赖导入主项目中,下面为利用计算代码中的 ComputingTask 来获取 Jar 包的路径。

String jarFile = ComputingTask.class.
				getProtectionDomain().getCodeSource().getLocation().getFile();
context.addJar(jarFile);

Spark 数据源问题

数据源问题同样也是集群所导致的,本地模式下运行可以使用本地文件,但若是集群模式,由于 Slave 节点的 Woker 获取不到本地文件就会报错。因而数据源必须选择那些能远程使用的,例如分布式文件系统、数据库或者 FTP 服务器上的文件。

context.textFile("hdfs://host:port/test.txt"); // Don't use local file in cluster mode.

分词组件加载问题

项目中需要中文分词,所以选用了 Word 分词组件,但是每次头次加载都会花费很长时间,于是必须进行预加载,解决方案可以在该项目的 issue 中找到。

相似度计算

由于对该方面的算法了解不过,所以对文档的相似度计算,采用了简单地对两个文档进行杰卡德相似系数的计算,其定义为A与B交集的大小与A与B并集的大小的比值,下面为公式:

J(A,B) = |A ^ B| / |A v B|

项目计划

  • 提供多种相似度的计算算法
  • 提供 Dockerfile 方便环境的搭建
  • 改造项目的简陋前端界面
  • 解决无法清理临时文件问题
  • 解决回收任务标识符问题
  • 提供 Word 文档实时预览

项目地址为 https://github.com/linzhehuang/docdetect,觉得不错的话欢迎 Star !

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

git 为项目设置用户名/邮箱/密码

1.找到项目所在目录下的 .git,进入.git文件夹,然后执行如下命令分别设置用户名和邮箱 git config user.name "Affandi" git config user.email "123333333@qq.com" 然后执行命令查看con......

有时很滑稽
44分钟前
0
0
如何从int转换为String? - How do I convert from int to String?

问题: I'm working on a project where all conversions from int to String are done like this: 我正在一个项目中,所有从int到String转换都是这样完成的: int i = 5;String strI = "" ......

javail
55分钟前
10
0
Vue+Spring Data JPA+MySQL 增查改删

视频讲解: https://www.bilibili.com/video/BV16i4y1G7i2/ 工程概述: 前后端分离,进行简单增查改删(CRUD) 前端使用VUE 后端使用Spring Data JPA 数据库使用MySQL #EmployeeController.jav...

潘文海
今天
13
0
我花了一个星期,做出了公司的管理系统,只需几个步骤!

我是企业的管理人员,公司发展到现阶段,感觉进入到了瓶颈期,每个员工的工作都已经饱和,很难再挤出时间做其它的事情,需要一款合适的管理软件来协作我们的工作。本来打算买一套管理软件就行...

科技那些事儿
今天
19
0
如何从Android应用程序获取崩溃数据? - How do I obtain crash-data from my Android application?

问题: How can I get crash data (stack traces at least) from my Android application? 如何从我的Android应用程序获取崩溃数据(至少是堆栈跟踪)? At least when working on my own de......

技术盛宴
今天
16
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部