热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于Elasticsearch搜索平台

背景随着公司业务的高速发展以及数据爆炸式的增长,当前公司各产线都有关于搜索方面的需求,但是以前的搜索服务系统由于架构与业务上的设计,不

基于 Elasticsearch 搜索平台

背景

随着公司业务的高速发展以及数据爆炸式的增长,当前公司各产线都有关于搜索方面的需求,但是以前的搜索服务系统由于架构与业务上的设计,不能很好的满足各个业务线的期望,主要体现下面三个问题:

  1. 不能支持对语句级别的搜索,大量业务相关的属性根本无法实现
  2. 没有任何搜索相关的指标评价体系
  3. 扩展性与维护性特别差

基于现状,对行业内的搜索服务做出充分调研,确认使用 Elasticsearch 做底层索引存储,同时重新设计现有搜索服务,使其满足业务方对维护性、定制化搜索排序方面的需求。

整体技术架构

沪江搜索服务底层基于分布式搜索引擎 ElasticSearch,ElasticSearch 是一个基于 Lucene 构建的开源,分布式,Restful 搜索引擎;能够达到近实时搜索,稳定,可靠,快速响应的要求。

基于 Elasticsearch 搜索平台

搜索服务整体分为5个子系统

  • 搜索服务( Search Server ) : 提供搜索与查询的功能
  • 更新服务( Index Server ) : 提供增量更新与全量更新的功能
  • Admin 控制台 : 提供 UI 界面,方便索引相关的维护操作
  • ElasticSearch 存储系统 : 底层索引数据存储服务
  • 监控平台: 提供基于 ELK 日志与 zabbix 的监控

外部系统接口设计

基于 Elasticsearch 搜索平台

  • 查询
    • 查询接口提供 http 的调用方式,当出现跨机房访问的时候,请使用http接口,其余都可以使用 dubbo RPC 调用
  • 增量更新
    • 数据增量更新接口采用提供 MQ 的方式接入。当业务方出现数据更新的时候,只需将数据推送到对应的 MQ 通道中即可。更新服务会监听每个业务方通道,及时将数据更新到 Elasticsearch 中
  • 全量索引
    • 更新服务会调用业务方提供的全量 Http 接口(该接口需提供分页查询等功能)

全量更新

众所周知,全量更新的功能在搜索服务中是必不可少的一环。它主要能解决以下三个问题

  • 业务方本身系统的故障,出现大量数据的丢失
  • 业务高速发展产生增减字段或者修改分词算法等相关的需求
  • 业务冷启动会有一次性导入大批量数据的需求

基于上面提到的问题,我们与业务方合作实现了全量索引。但是在这个过程中,我们也发现一个通用的问题。在进行全量更新的时候,其实增量更新也在同时进行,如果这两种更新同时在进行的话,就会有遇到少量增量更新的数据丢失。比如说下面这个场景

  1. 业务方发现自己搜索业务 alias_A 数据大量数据丢失,所以进行索引重建。其中 alias_A 是别名,就是我们通常说 alias ,但是底层真正的索引是index_201701011200 (建议:索引里面包含时间属性,这样就能知道是什么创建的)
  2. 首先创建一个新的索引 index_201706011200,然后从数据中拉出数据并插入ES 中,并记录时间戳T1,最后索引完成的时间戳为 T2 ,并切换搜索别名index_1 指向 index_201706011200。
  3. 索引创建成功之后的最新数据为T1这个时刻的,但是 T1 到 T2 这段时间的数据,并没有获取出来。同时 index_201701011200 老索引还在继续消费 MQ 中的数据,包括 T1 到 T2 时间内的缺少数据。
  4. 所以每次索引重建的时候,都会缺少 T1T2 时间内的数据。

最后,针对上面这个场景,我们提出通过 zookeeper 分布式锁来暂停 index consumer 的消费,具体步骤如下

  1. 创建 new_index
  2. 获取该 index 对应的别名,来修改分布式锁的状态为 stop
  3. index consumer 监控 stop 状态,暂停索引数据的更新
  4. new_index 索引数据创建完毕,更新分布式锁状态为start
  5. index consumer 监控 start 状态,继续索引数据的更新

基于 Elasticsearch 搜索平台
这样的话,我们就不用担心在创建索引的这段时间内,数据会有缺少的问题。相信大家对于这种方式解决全量与增量更新数据有所体会。

集群无缝扩容

数据量爆炸式的增加,导致我们 ES 集群最终还是遇到了容量不足的问题。在此背景下,同时结合 ES 本身提供的无缝扩容功能,我们最终决定对线上ES集群进行了在线的无缝扩容,将从原来的 3 台机器扩容为 5 台,具体步骤如下

  • 扩容前准备
    • 目前我们线上已经有 3 台机器正在运行着,其中 node1 为 master 节点,node2 和 node3 为data节点,节点通信采用单播的形式而非广播的方式。
    • 准备 2 台( node4 与 node5 )机器,其中机器本身配置与 ES 配置参数需保持一致
  • 扩容中增加节点
    • 启动 node4 与 node5 (注意一个一个启动),启动完成之后,查看node1,2,3,4,5 节点状态,正常情况下 node1,2,3 节点都已发现 node4 与 node5,并且各节点之间状态应该是一致的
  • 重启 master node
    • 修改 node1,2,3节点配置与 node4,5保持一致,然后顺序重启 node2与 node3 ,一定要优先重启 data node,最后我们在重启 node1( master node).到此为止,我们的线上 ES 集群就在线无缝的扩容完毕

基于 Elasticsearch 搜索平台

部署优化

  • 查询与更新服务分离
    • 查询服务与更新服务在部署上进行物理隔离,这样可以隔离更新服务的不稳定对查询服务的影响
  • 预留一半内存
    • ES 底层存储引擎是基于 Lucene ,Lucene 的倒排索引是先在内存中生成,然后定期以段的形式异步刷新到磁盘上,同时操作系统也会把这些段文件缓存起来,以便更快的访问。所以Lucene的性能取决于和OS的交互,如果你把所有的内存都分配给 Elasticsearch,不留一点给 Lucene,那你的全文检索性能会很差的。所有官方建议,预留一半以上内存给 Lucene 使用
  • 内存不要超过 32G
    • 跨 32G 的时候,会出现一些现象使得内存使用率还不如低于 32G,具体原因请参考官方提供的这篇文章 Don’t Cross 32 GB!
  • 尽量避免使用 wildcard
    • 其实使用 wildcard 查询,有点类似于在数据库中使用左右通配符查询。(如:*foo*z这样的形式)
  • 设置合理的刷新时间
    • ES 中默认 index.refresh_interval 参数为1s。对于大多数搜索场景来说,数据生效时间不需要这么及时,所以大家可以根据自己业务的容忍程度来调整

总结

本章主要介绍公司搜索服务的整体架构,重点对全量更新中数据一致性的问题, ES 在线扩容做了一定的阐述,同时列举了一些公司在部署 ES 上做的一些优化。本文主要目的,希望大家通过阅读沪江搜索实践,能够给广大读者带来一些关于搭建一套通用搜索的建议


推荐阅读
  • 为什么多数程序员难以成为架构师?
    探讨80%的程序员为何难以晋升为架构师,涉及技术深度、经验积累和综合能力等方面。本文将详细解析Tomcat的配置和服务组件,帮助读者理解其内部机制。 ... [详细]
  • 本文详细介绍了如何在 Linux 系统上安装 JDK 1.8、MySQL 和 Redis,并提供了相应的环境配置和验证步骤。 ... [详细]
  • 用阿里云的免费 SSL 证书让网站从 HTTP 换成 HTTPS
    HTTP协议是不加密传输数据的,也就是用户跟你的网站之间传递数据有可能在途中被截获,破解传递的真实内容,所以使用不加密的HTTP的网站是不 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • 本文深入探讨了如何利用Maven高效管理项目中的外部依赖库。通过介绍Maven的官方依赖搜索地址(),详细讲解了依赖库的添加、版本管理和冲突解决等关键操作。此外,还提供了实用的配置示例和最佳实践,帮助开发者优化项目构建流程,提高开发效率。 ... [详细]
  • 在安装并配置了Elasticsearch后,我在尝试通过GET /_nodes请求获取节点信息时遇到了问题,收到了错误消息。为了确保请求的正确性和安全性,我需要进一步排查配置和网络设置,以确保Elasticsearch集群能够正常响应。此外,还需要检查安全设置,如防火墙规则和认证机制,以防止未经授权的访问。 ... [详细]
  • 本文推荐了六款高效的Java Web应用开发工具,并详细介绍了它们的实用功能。其中,分布式敏捷开发系统架构“zheng”项目,基于Spring、Spring MVC和MyBatis技术栈,提供了完整的分布式敏捷开发解决方案,支持快速构建高性能的企业级应用。此外,该工具还集成了多种中间件和服务,进一步提升了开发效率和系统的可维护性。 ... [详细]
  • 掌握PHP框架开发与应用的核心知识点:构建高效PHP框架所需的技术与能力综述
    掌握PHP框架开发与应用的核心知识点对于构建高效PHP框架至关重要。本文综述了开发PHP框架所需的关键技术和能力,包括但不限于对PHP语言的深入理解、设计模式的应用、数据库操作、安全性措施以及性能优化等方面。对于初学者而言,熟悉主流框架如Laravel、Symfony等的实际应用场景,有助于更好地理解和掌握自定义框架开发的精髓。 ... [详细]
  • ZeroMQ在云计算环境下的高效消息传递库第四章学习心得
    本章节深入探讨了ZeroMQ在云计算环境中的高效消息传递机制,涵盖客户端请求-响应模式、最近最少使用(LRU)队列、心跳检测、面向服务的队列、基于磁盘的离线队列以及主从备份服务等关键技术。此外,还介绍了无中间件的请求-响应架构,强调了这些技术在提升系统性能和可靠性方面的应用价值。个人理解方面,ZeroMQ通过这些机制有效解决了分布式系统中常见的通信延迟和数据一致性问题。 ... [详细]
  • ElasticSerach初探第一篇认识ES+环境搭建+简单MySQL数据同步+SpringBoot整合ES
    一、认识ElasticSearch是一个基于Lucene的开源搜索引擎,通过简单的RESTfulAPI来隐藏Lucene的复杂性。全文搜索,分析系统&# ... [详细]
  • 初学SpringBootch06接口架构风格 RESTful
    ch06-接口架构风格RESTful1.1认识RESTful1.1.1RESTful架构风格1.2RESTful注解1.3RESTful风格的使用1.3.1加入Maven依赖1.3 ... [详细]
  • 部署solr建立nutch索引
    2019独角兽企业重金招聘Python工程师标准接着上篇nutch1.4的部署应用,我们来部署一下solr,solr是对lucene进行了封装的企 ... [详细]
  • 1.0为什么要做这个博客站?  在工作学习中,经常要搜索查找各种各样的资料,每次找到相关资料后都会顺手添加到浏览器书签中,时间一长,书签也就满了。而且下次再点击这个书签时,可能就会忘记当时为什么要添加这个书签了,更有可能书签连接已经无效。这样一来,也就不方便 ... [详细]
  • 洞见RSAC|点击获取企业安全策略“工具包”
    为用户提供安全智 ... [详细]
  • 谈起RESTFUL大家未免都耳熟能详,但是要介绍一下它是什么,可能就是停留在听过或者见过的阶段了。一贯喜欢以通俗的语言来消化知识的小马自然不会放过它了& ... [详细]
author-avatar
吕贞吟明辉碧瑜
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有