kafka+spark streaming+hbase 倒排索引 实现实时流搜索引擎

集群说明

集群ip

集群配置

172.17.11.63(master)

Hadoop-2.7.6(Namenode)

spark-2.4.0

Hbase-1.2.4

Kafka_2.11-2.1.0

Zookeeper-3.4.10

172.17.11.37

Hadoop-2.7.6(Datanode)

spark-2.4.0

扫描二维码关注公众号,回复: 4907938 查看本文章

Hbase-1.2.4

Kafka_2.11-2.1.0

Zookeeper-3.4.10

172.17.11.64

Hadoop-2.7.6(Datanode)

spark-2.4.0

Hbase-1.2.4

Kafka_2.11-2.1.0

Zookeeper-3.4.10

集群架构图

算法说明

倒排索引:

使用spark streaming实现

  1. 首先url这个变量传入两个参数(网页链接,网页内容分词后的结果)
  2. 对网页内容分词后的结果使用flatmap,按分词的空格分割后变成流,再使用map对每个词进行处理,使他们变成 url+分号+词的形式,变成一个新的Dstream。

例如,原始数据为(url,”A B C A”)

A B C为分词处理后的一个个词

使用flatmap分词后得到(“url;A”),(”url;B”),(”url;C”), (”url;A”)

  • 对得到的结果使用map映射,得到

(“url;A”,1), (“url;B”,1), (“url;C”,1), (“url;A”,1)

  • 使用reduceByKey对相同键值的结果进行合并,得到

(“url;A”,2), (“url;B”,1), (“url;C”,1)

  • 使用foreachRdd和foreachPartition并连接Hbase,将得到的结果存储到Hbase中,

存储方式如下:

表名

行索引

列族名

列名

值(该网页的词数)

sea

A

web

网页链接1

2

sea

A

web

网页链接2

4

sea

B

web

网页链接

1

sea

C

web

网页链接

1

倒排索引完成。

每次搜索时,比如需要搜索A词,从Hbase中取出行索引为A的一行,这一行中每一列都是一个网页的链接,该列的值就是该网页词语出现次数,因此可以取出,网页链接1中A词出现2词,网页链接2中A词出现4次,然后在JAVA的后端进行处理后打印到前端界面。

 

以下是Spark Streaming倒排索引的scala代码

var url = kafkamessage.flatMap(x=>{

  var link = x._1

  x._2.split(" ").map(x=>link.concat(";").concat(x))

}).map(x=>(x,1)).reduceByKey(_+_).foreachRDD(rdd=>rdd.foreachPartition(partition=>{

  try{

    val conf = HBaseConfiguration.create()

    conf.set("hbase.zookeeper.quorum", "172.17.11.63,172.17.11.37,172.17.11.64")

    conf.set("hbase.zookeeper.property.clientPort", "2181")

    val hbaseConn = ConnectionFactory.createConnection(conf)

    val table = hbaseConn.getTable(TableName.valueOf("sea"))

    partition.foreach(x=>{

      var put = new Put(Bytes.toBytes(x._1.split(";")(1)))

      put.addColumn(Bytes.toBytes("web"), Bytes.toBytes(x._1.split(";")(0)), Bytes.toBytes(x._2.toString))

      table.put(put)

    })

  } catch {

    case e: Exception => print("error")

  }

}))

 

词语关联分析:

  • 根据网上搜集到的和python库中的synonyms包建立一个中文近义词词林的文件。

处理后的结果如下:

A B C D

N W Q

P O L

每一行的所有词都是近义词。

  • 将词林导入hbase中,数据库构造方式如下

行索引:A    列名1:B  列名2:C  列名3:D

行索引:B    列名1:A  列名2:C  列名3:D

行索引:C    列名1:B  列名2:A  列名3:D

行索引:D    列名1:B  列名2:C  列名3:A

  • 当用户搜索一个词时,直接从Hbase取出相应的行索引的词

比如查询A词的时候,取出BCD3列,就能获得BCD这3个关联词,处理后打印到前端。

 

程序结构:

程序用途

程序名

程序语言

程序运行位置

爬虫程序 Kafka的生产者

持续运行,每隔3秒爬取一个新浪新闻网页

然后通过Kafka生产者发送到集群上

Kafka.py

Python

Win

Kafka的消费者

spark streaming

持续运行,每隔10秒实时处理一次生产者生产的数据

使用Dstream对生产者发送的数据进行倒排索引处理,并使用rdd将处理后的结果存入Hbase中

KafkaStream.scala

Scala

集群上

将关联词的词林输入到Hbase中

LoadAsso.java

Java

Win远程连接Hbase

运行网页程序,调用Hbase中的结果,获取用户输入,实时在Hbase中查询结果,并打印查询结果和相关推荐给用户

Java web项目

Java html

Win上的tomcat

运行说明:

  • 爬虫程序:

使用BeautifulSoup包,实时爬取新浪新闻,

然后调用jieba分词的包,并使用停止词,对数据进行清洗,得到一个相对干净的分词后的结果。

将数据通过kafka的生产者发送到集群上,并设置了等待时间,每3秒发送一个网页的url和对网页内容分词后的结果

 

  • Spark streaming程序:

通过kafka获取爬虫爬到的数据,使用Dstream中的map,flatmap,reduce等对数据进行倒排索引,然后通过rdd将数据持久化到Hbase中。

实时运行,每10秒处理一次收到的数据。

  • 导入关联词库程序:

通过python和网上现有的中文同义词词林,生成一个关联词词库,然后通过java程序远程连接Hbase,将关联词持久化到Hbase中。

  • Java web项目:

Ajax Servlet

用户在Html的输入框中输入要搜索的词,通过Ajax发送请求到后端的Servlet,Servlet接收到消息后,调用写好的Hbase的dao,即数据库连接和查询,返回相应词的网页结果和关联词结果。然后将这些结果进行处理,编码成json,将json通过Ajax发送回html中,然后使用js代码,即时的更新html中的元素,直接显示搜索网页结果和关联词结果。

 

 

数据清洗:将404的网页除外,然后调用jieba分词,使用百度停用词和哈工大停用词对分词结果进行清洗,得到一个干净的网页内容。

 

持久化:倒排索引后的结果持久化到Hbase中;关联词分析后的词林导入到Hbase中

 

 

猜你喜欢

转载自blog.csdn.net/wu13599hao/article/details/85716270