2024年大数据最新【elasticsearch实战】从零开始设计全站搜索引擎(2),2024年最新硬核

   日期:2024-12-27    作者:b1235492 移动:http://3jjewl.riyuangf.com/mobile/quote/65457.html

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导,让我们一起学习成长

热门搜索词

热门搜索词主要来源用户搜索,目前场景比较简单,每天定时任务统计N天前的用户搜词词频,按搜索频次降序排序,存储到MySQL或者redis中。
但这种方法可能存在问题,热搜词没有时间权重衰减, 例如:一个关键词10天前搜索了101次,昨天搜索了100次,10天前的词还能继续排在昨天的热词前面吗? 因此需要设计一个热词衰减权重,搜索时间越长热度权重应该相应的衰减。

联想搜索词

联想搜索需要在用户输入关键词时,联想用户可能想要搜索的词,该功能需要解决2个问题

  1. 关联词来源
  2. 关联词方式

关联词来源可以通过用户搜索关键词记录来提取。

技术选择可以根据业务和当前的系统环境来判断

  1. 尽量不重复造轮子
  2. 使用已有、成熟的、开源的技术栈
  3. 能满足需求,成本低、技术可控。
    搜索存储引擎目前最成熟活跃的方案非 莫属,我们的系统基于腾讯云框架搭建,业务数据存在在腾讯云的中,因此搜索业务全文检索计划使用腾讯云最新版本的。

es配置选择

文档转换工具选择

我们的需求里面需要将不同类型的文档转换为纯文本,这里有几个开源的实现方案

工具优点缺点1. OpenOffice1. 一个开源的,功能强大的办公软件套装。2. 支持多种格式的文档转换。3. 支持多语言。4. 可以运行在多种操作系统上。1. 界面比较陈旧。2. 某些高级功能不如付费的办公软件强大。3. 需要较大的系统资源运行。2. Tika1. Apache Tika是一个开源的文档类型和元数据提取工具。2. 支持大量的文档格式。3. 可以提取文档中的元数据和文本内容。1. 对于一些复杂的文档格式,提取的结果可能不准确。2. 需要Java环境运行。3. Ingest Attachment1. Elasticsearch的一个插件,可以用来提取各种文件的内容。2. 使用Apache Tika进行文档解析。3. 可以直接与Elasticsearch集成,方便进行全文搜索。1. 需要Elasticsearch环境。2. 对于一些复杂的文档格式,提取的结果可能不准确。4. FsCrawler1. FsCrawler是一个简单的文件系统爬虫,可以用来索引文件和文件夹。2. 支持OCR和全文搜索。3. 可以直接与Elasticsearch集成。1. 需要Java环境运行。2. 只能处理文件系统中的文件,不能处理网络上的文件。

我结合自身业务的情况,选了上面4种之外的方法,我们文档存储在,直接调用`腾讯云API转html 或者text文档:文档转 HTML

如果没有使用腾讯云我这边推荐使用`FsCrawler, 可参考我之前的博文。

数据传输选型

同步工具选型

同步工具开源方案目前最活跃的应该是阿里巴巴开源的canal ,可以看官网的原理介绍

  1. MySQL主备复制原理
    • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志- 事件binary log events,可以通过 show binlog events 进行查看)
    • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
    • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
  2. canal 工作原理
    • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
    • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
    • canal 解析 binary log 对象(原始为 byte 流)

#mermaid-svg-CDPtMmuPvv8JTgZj {font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj .error-icon{fill:#552222;}#mermaid-svg-CDPtMmuPvv8JTgZj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CDPtMmuPvv8JTgZj .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-CDPtMmuPvv8JTgZj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CDPtMmuPvv8JTgZj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CDPtMmuPvv8JTgZj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CDPtMmuPvv8JTgZj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CDPtMmuPvv8JTgZj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CDPtMmuPvv8JTgZj .marker.cross{stroke:#333333;}#mermaid-svg-CDPtMmuPvv8JTgZj svg{font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CDPtMmuPvv8JTgZj .label{font-family:“trebuchet ms”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj .cluster-label text{fill:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj .cluster-label span{color:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj .label text,#mermaid-svg-CDPtMmuPvv8JTgZj span{fill:#333;color:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj .node rect,#mermaid-svg-CDPtMmuPvv8JTgZj .node circle,#mermaid-svg-CDPtMmuPvv8JTgZj .node ellipse,#mermaid-svg-CDPtMmuPvv8JTgZj .node polygon,#mermaid-svg-CDPtMmuPvv8JTgZj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CDPtMmuPvv8JTgZj .node .label{text-align:center;}#mermaid-svg-CDPtMmuPvv8JTgZj .node.clickable{cursor:pointer;}#mermaid-svg-CDPtMmuPvv8JTgZj .arrowheadPath{fill:#333333;}#mermaid-svg-CDPtMmuPvv8JTgZj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CDPtMmuPvv8JTgZj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CDPtMmuPvv8JTgZj .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-CDPtMmuPvv8JTgZj .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-CDPtMmuPvv8JTgZj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CDPtMmuPvv8JTgZj .cluster text{fill:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj .cluster span{color:#333;}#mermaid-svg-CDPtMmuPvv8JTgZj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CDPtMmuPvv8JTgZj :root{–mermaid-font-family:“trebuchet ms”,verdana,arial,sans-serif;}

订阅binlog

读取kafka

写入kafka2

input来源于kafka2

输出到kafka1

腾讯云 DTS-kafka1

MySQL

dts适配

kafka2

logstash

Elasticsearch

架构图

搜索混排

注意

  1. 可以配置不同数据源的评分权重(或者评分算法)以便优先要展示的结果
  2. 需要记录不同数据源的偏移量和不同数据的查询结果,以便实现下次查询分页处理
  3. 查询ES和查询私有云数据使用协程并行操作,等待2个结果共同返回处理。

另外你的第三方数据源没有存储在es数据库中,不能直接给出文档评分的,可以考虑以下混排方案

方案原理优点缺点临时建索引做混排将来自不同数据源的数据在中创建一个临时索引,然后在该索引上进行搜索和排序。1. 利用强大的搜索功能。2. 支持复杂的查询和排序。1. 需要创建临时索引,可能影响性能。2. 需要处理索引的创建和删除。3. 可能需要处理数据源之间的数据差异。内存混排将来自不同数据源的数据加载到内存索引中,然后在内存索引上进行搜索和排序。1. 高性能,因为数据存储在内存中。2. 支持复杂的查询和排序。1. 内存占用较高。2. 需要处理内存索引的创建和维护。3. 可能需要处理数据源之间的数据差异。分词词频内存混排根据分词和词频对来自不同数据源的数据进行内存中的排序,然后返回排序后的结果。1. 实现相对简单。2. 内存占用相对较低。1. 只支持基于分词和词频的排序。2. 对于复杂的查询和排序需求,可能不够灵活。3. 可能需要处理数据源之间的数据差异。

翻页方案

由于要对2个数据源进行混排,要支持搜索跳页比较困难,因此在功能实现上目前只能支持上下翻页来实现

翻页计算公式

前端需要保存每一页es 和 api 两个数据源的偏移量:EsOffset 和 ApiOffset,可以使用对象数组保存 , 翻页计算公式如下

  • 当前页码计算公式
  • 上一页:将当前页码减1 , 获取上一页页面缓存的上一页 EsOffset 和 ApiOffset
  • 下一页, 获取下一页的EsOffset 和 ApiOffset

注意:查询到第一页时,可清空页面分页缓存数组对象,重新存储。

翻页举例说明
  1. 查询首页,假设没页显示20条数据

    • 请求参数:EsOffset = 0,ApiOffset=0, PageSize=20
    • 返回结果

前端需要需要页面需要保存当前第一页页面的 和 ,页面缓存数据

  1. 继续查询下一页

    • 请求参数
    • 返回结果
    • 前端继续缓存当前分页数据
  2. 查询上一页

  • 请求参数:当前页码减1
  • 返回结果:与第一页一致
    如果是查询第一数据,清空缓存数组,重新缓存当前分页数据。

权限处理

搜索权限需要满足根据用户权限过滤部分无权限的文档,以下是召回前处理和召回后处理权限的方案对比。

方案实现优点缺点召回前过滤在查询时,根据用户的权限对文档进行过滤,只返回有权限查看的文档。1. 查询结果直接满足权限要求。2. 减少了无关文档的返回,提高了性能。1. 需要在查询时处理权限信息。2. 对于复杂的权限体系,实现可能较为复杂。召回后过滤先查询所有文档,然后根据用户的权限对查询结果进行过滤。1. 查询过程简单,不需要处理权限信息。2. 适用于简单的权限体系。1. 可能返回大量无关文档,影响性能。2. 需要在查询后处理权限信息,增加了实现复杂度。

根据我的需求和场景,对性能要求较高,我们使用召回前过滤。如果希望简化查询过程,页可以考虑使用召回后过滤。
下面是在文档的权限格式,包含文档有权限的用户ID和部门ID

 

我们在设计索引mapping时

 

查询权限过滤参数

 
搜索行为日志收集

需要满足用户搜索历史记录,首先需要收集用户搜索行为日志。

#mermaid-svg-RGDIHV3yG6IIeTHR {font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR .error-icon{fill:#552222;}#mermaid-svg-RGDIHV3yG6IIeTHR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RGDIHV3yG6IIeTHR .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-RGDIHV3yG6IIeTHR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RGDIHV3yG6IIeTHR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RGDIHV3yG6IIeTHR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RGDIHV3yG6IIeTHR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RGDIHV3yG6IIeTHR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RGDIHV3yG6IIeTHR .marker.cross{stroke:#333333;}#mermaid-svg-RGDIHV3yG6IIeTHR svg{font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RGDIHV3yG6IIeTHR .label{font-family:“trebuchet ms”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR .cluster-label text{fill:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR .cluster-label span{color:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR .label text,#mermaid-svg-RGDIHV3yG6IIeTHR span{fill:#333;color:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR .node rect,#mermaid-svg-RGDIHV3yG6IIeTHR .node circle,#mermaid-svg-RGDIHV3yG6IIeTHR .node ellipse,#mermaid-svg-RGDIHV3yG6IIeTHR .node polygon,#mermaid-svg-RGDIHV3yG6IIeTHR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RGDIHV3yG6IIeTHR .node .label{text-align:center;}#mermaid-svg-RGDIHV3yG6IIeTHR .node.clickable{cursor:pointer;}#mermaid-svg-RGDIHV3yG6IIeTHR .arrowheadPath{fill:#333333;}#mermaid-svg-RGDIHV3yG6IIeTHR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RGDIHV3yG6IIeTHR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RGDIHV3yG6IIeTHR .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-RGDIHV3yG6IIeTHR .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-RGDIHV3yG6IIeTHR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RGDIHV3yG6IIeTHR .cluster text{fill:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR .cluster span{color:#333;}#mermaid-svg-RGDIHV3yG6IIeTHR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RGDIHV3yG6IIeTHR :root{–mermaid-font-family:“trebuchet ms”,verdana,arial,sans-serif;}

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

9%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RGDIHV3yG6IIeTHR :root{–mermaid-font-family:“trebuchet ms”,verdana,arial,sans-serif;}

[外链图片转存中…(img-EfR5UhtP-1715615063586)]
[外链图片转存中…(img-SUe1qPHv-1715615063587)]
[外链图片转存中…(img-gJtfHxvM-1715615063587)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新


特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


举报收藏 0评论 0
0相关评论
相关最新动态
推荐最新动态
点击排行
{
网站首页  |  关于我们  |  联系方式  |  使用协议  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号