#研发解决方案介绍#基于ES的搜索+筛选+排序解决方案
本文档适用人员:研发和运维
- 曾经的基于MongoDB的筛选+排序解决方案
- MongoDB方案的缺陷
- 看中了搜索引擎的facet特性
- 看中了ES的简洁
- 看中了ES的天生分布式设计
- 窝窝的ES方案
- ES的几次事故和教训
- ES自身存在的问题
|
由于频道页流量小于首页,尤其是用户很少点击到的深度筛选条件组合查询,所以下图中的所有枚举项商品数量都容易缓存失效或缓存挤出:
图2 筛选越来越复杂,标题数字却要保持准确性
一旦缓存失效后,但凡我从上图的“20元以下”点击切换到“51-80元”或做更深层次筛选,那么程序就要针对上面所有组合条件对 MongoDB 商品记录逐一做 count 计算。
虽然每一个 count 计算都很快不属于慢查询,但也架不住多啊,尤其是配上区县和商圈等动辄6、7层深的筛选组合,点击一次轻易就涉及成百次的 count 计算,代价还是很大的。
由于在商城模式下,不同频道很可能不断增加新筛选条件,导致筛选组合越来越复杂,最终可能要求我们从基于 NoSQL 的排序和筛选方案,尽快转变为基于搜索引擎的排序和筛选方案。
|
介绍分面
分面是指事物的多维度属性。例如一本书包含主题、作者、年代等分面。而分面搜索是指通过事物的这些属性不断筛选、过滤搜索结果的方法。可以将分面搜索看成搜索和浏览的结合。
灵活使用分面 有时用户并不明确自己的目的,因此提供宽松的筛选方式更符合这部分用户的预期。Bing 的旅行搜索中选择航班时,用户可以通过滑块来选择某个时间段起飞的航班。 |
- Field Facet:如果需要对多个字段进行Facet查询,那么将 facet.field 参数声明多次,Facet字段必须被索引;
- Date Facet:时间字段的取值有无限性,用户往往关心的不是某个时间点而是某个时间段内的查询统计结果,譬如按月份查;
- Facet Query:利用类似于filter query的语法提供了更为灵活的Facet,譬如根据价格字段查询时,可设定不同价格区间;
- 简单
- RESTful
- json 格式 Response
- 天生分布式
- Querydsl 风格查询
商品维度是我们主要的查询维度,其业务复杂度也比较高。针对网站查询特性,我们的商品主索引方案为:每个城市建立一个 index,所以一共有400多个 index,每个城市仅有1个主 shard(不分片)。这样做的好处是以后我们根据热点城市和非热点城市,可以将各个 index 手工分配到不同的 node 上,可以做很多优化。
其结构为:
图7 goodsinfo
为了减少索引量和功能拆分,减少商品索引的内存占用,所以我们把全文检索单独建为一个索引。
每个城市索引或者商品索引按频道分为几个type,如下图所示。
图9 type
商品频道映射到es的type是很容易理解的,因为每个频道的模型不同:有的频道特有“用餐人数”属性,有的频道特有“出发城市”和“目的地城市”属性 所以每个频道对应一个es的type,每个type绑定一种特定的mapping(这个mapping里面可以指定该频道各自的特殊属性如何储存到ES)。
ES 会保证所有 shard 的主副本不在同一个 node 上面,但我们是 ES 服务器集群,每台服务器上有多个 node,一个 shard 的主副本不在同一个节点还是不够的,我们还需要一个 shard 的主副本不在同一台服务器,甚至在多台物理机的情况下保证要保证不在同一个机架上,才可以保证系统的高可用性。
所以ES提供了一个配置:cluster.routing.allocation.awareness.attributes: rack_id。
这个属性保证了主副 shard 会分配到名称不同的 rack_id 上面。
当我们停止一个节点时,如停止 174_node_2,则 ES 会自动重新平衡数据,如下图所示:
图13 重新分布
即使一台物理机完全 down 掉,我们可以看到其他物理机上的数据是完整的,ES 依然可以保证服务正常。
查看其内存使用状况发现,ES 各个节点的 JVM perm 区均处于满或者将要满的状态,如下图所示:
图15 当时perm的容量
注1:jstat -gc <pid>命令返回结果集中,上图红色方框中字段的含义为:
PC Current permanent space capacity (KB). 当前perm的容量 ;
PU Permanent space utilization (KB). perm的使用。
大家可以看到图1中的PU值基本等于PC值了。
由于 ES 各个节点的 perm 区接近饱和状态,所以造成了服务器负载升高,GC 频繁,并进一步造成 ES 集群出现了类似于“脑裂”的状态。
- 引入新技术,还是要谨慎,毕竟如果真是 mevl 脚本引起的问题,其实线下做压力测试就能提前发现。
- 加强ES的监控。
- 虽然现在回过头来看,如果在第一时间重启所有 nodes,损失应该是最小的——但是王超认为当时采用的保守策略依然是有意义的,因为在弄清楚问题原因之前,直接重启 nodes 有可能反而造成更大的数据破坏。
Elastic Search 在窝窝运行几年来基本稳定,可靠性和可用性也比较高,但是也暴露了一些问题:
- ES 的更新效率,作为基于 lucene 的分布式中间件,受限于底层数据结构,所以其更新索引的效率较低,lucene 一直在优化;
- ES 的可靠性的前提是保证其集群的整体稳定性,但我们遇到的情况,往往是当某个节点性能不佳的情况下,可能会拖累与其同服务器上的所有节点,从而造成整个集群的不稳定。
- 其实解决这个问题不难,两种方法:
- 增加服务器,让节点尽可能地散开;
- 当某个节点出现问题的时候,需要我们及早发现处理,不至于拖累整个集群。其实监控一个节点是否正常的方法不难,ES 是基于 JVM 的服务,它出现问题,往往和 GC、和内存有关,所以只要监控其内存达到某个上限就报警即可;
没有一个好的客户端可视化集群管理工具,官方或者主流的可视化管理工具,基本都是基于 ES 插件的,不符合我们的要求,所以需要一款可用的客户端可视化集群管理工具; ES 的升级问题,由于 ES 是一个快速发展的中间件系统,每一次新版本的更新,更改较大,甚至导致我们无法兼容老版本,所以 ES 升级问题是个不小的问题,再加上我们数据量较大,迁移也比较困难。
——END——
窝窝的解决方案介绍列表:
#研发解决方案#基于StatsD+Graphite的智能监控解决方案
#研发中间件介绍#定时任务调度与管理JobCenter
#研发解决方案介绍#Recsys-Evaluate(推荐评测)
#研发解决方案介绍#Tracing(鹰眼)
#研发解决方案介绍#基于持久化配置中心的业务降级
#研发中间件介绍#异步消息可靠推送Notify
#研发解决方案介绍#IdCenter(内部统一认证系统)
#研发解决方案介绍#基于ES的搜索+筛选+排序解决方案
#数据技术选型#即席查询Shib+Presto,集群任务调度HUE+Oozie
es术语介绍:
cluster:
代表一个集群,集群中有多个节点,其中有一个为主节点。这个主节点是可以通过选举产生的。注意,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
shards
代表索引分片。es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
replicas
代表索引副本,es可以设置多个索引的副本。副本的作用,一是提高系统的容错性,当某个节点的某个分片损坏或丢失时可以从副本中恢复,二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
recovery
代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
river
代表es的一个数据源,也是其他存储方式(如:数据库)同步数据到es的一个方法。它是以插件方式存在的一个es服务,通过读取river中的数据并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia的。
gateway
代表es索引快照的存储方式。es默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘。gateway对索引快照进行存储,当这个es集群关闭再重新启动时,就会从gateway中读取索引备份数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和amazon的s3云存储服务。
discovery.zen
代表es的自动发现节点机制。es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。
Transport
代表es内部节点或集群与客户端的交互方式。默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)。
#研发解决方案介绍#基于ES的搜索+筛选+排序解决方案相关推荐
- #研发解决方案介绍#基于StatsD+Graphite的智能监控解决方案
2019独角兽企业重金招聘Python工程师标准>>> 关键词: 监控 .dashboard.PHP.graphite.statsd.whisper.carbon.grafana.i ...
- 有赞基于ES的搜索系统架构是如何演进的?
本文从架构上介绍了有赞搜索系统演进产生的背景以及希望解决的问题. 有赞搜索平台是一个面向公司内部各项搜索应用以及部分 NoSQL 存储应用的 PaaS 产品,帮助应用合理高效的检索和多维过滤功能.有赞 ...
- 程序员面试算法_程序员的前20个搜索和排序算法面试问题
程序员面试算法 大家好,如果您正在准备编程工作面试或正在寻找新工作,那么您知道这不是一个容易的过程. 在您职业的任何阶段,您都必须幸运地接到电话并进行第一轮面试,但是在初学者方面,当您寻找第一份工作时 ...
- 程序员的前20个搜索和排序算法面试问题
大家好,如果您正在准备编程工作面试或正在寻找新工作,那么您知道这不是一个容易的过程. 在您职业的任何阶段,您都必须幸运地接到电话并进行第一轮面试,但是在初学者方面,当您寻找第一份工作时就更加困难. 这 ...
- 基于 Es 实现站内全文搜索
点击上方关注 "终端研发部" 设为"星标",和你一起掌握更多数据库知识 摘要 对于一家公司而言,数据量越来越多,如果快速去查找这些信息是一个很难的问题,在计算机 ...
- 数字孪生体技术白皮书_基于Flownex的数字孪生体解决方案 系列介绍之二:数据中心应用实例...
致力于数字孪生体技术的研究与发展 通过解决方案和工程化应用造福人类 来源:数字孪生体实验室原创 作者:王永康 转载请注明来源和出处 导 读 <基于Flownex的数字孪生体解决方案>是我 ...
- #研发解决方案介绍#Tracing(鹰眼)
#研发解决方案介绍#Tracing(鹰眼) 参考文章: (1)#研发解决方案介绍#Tracing(鹰眼) (2)https://www.cnblogs.com/zhengyun_ustc/p/55so ...
- 帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件
帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件 - GXECMS博客 一.插件演示地址 后台演示地址:https://ecms.gxecms.cf/e/admin/inde ...
- Android音视频【十三】OpenSL ES介绍基于OpenSL ES实现音频采集
人间观察 勿再别人的心中修行自己, 勿再自己的心中强求别人. 前言 最近写文章有点偷懒了,离上次写文章大概一个月了. 一般Android音频的采集在java层使用AudioRecord类进行采集. 但 ...
最新文章
- Css 浏览器兼容性及其其他常见问题
- 谷歌Chrome 11对早期开发者开放使用
- hdu 5072 Coprime
- Android 11 修改libcore Cipher AS测试
- html 在线布局,html布局-管理系统布局
- 【hadoop-未解决】hadoop Error in security property. Constraint unknown: jdk.disabled.namedCurves
- pytorch源码解析2——数据处理torch.utils.data
- 瑞星服务器版序列号 2009,瑞星序列号2009 瑞星杀毒软件序列号和ID
- 骑士cms(74cms)个人版 整合UC
- PyQt5 clicked和clicked[bool]信号区别/setCheckable()的应用
- 国内有哪些不错的计算机视觉团队?
- 大中型 UGC 平台的反垃圾(anti-spam)工作
- C++面向对象-12-加号运算符重载
- ps入门教程、ps修图基本工具使用方法视频教学
- 双三次插值算法的OpenGL实现
- Ubuntu16.04设置并查看DNS
- Certificate for <xxx.xxx.xxx.com> doesn‘t match any of the subject alternative names: [xxx..com]
- 校招总结—FPGA从入门到放弃
- CANoe.DiVa 操作指南 -TP层测试
- Leetcode-D21-动态规划(二刷)-55. 跳跃游戏45. 跳跃游戏 II
热门文章
- 水晶报表技术(12)——一个投票系统水晶报表应用
- 3、Spring Cloud - Eureka(高可用Eureka Server集群)
- BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding
- Saltstack自动化环境部署
- 分布式架构中异步的使用场景
- Microsoft Lync Server 2013 协议路由
- 使用Win API创建工具栏
- tidb 架构 ~Tidb学习系列(4)
- mybatis中的resultMap与resultType、parameterMap与 parameterType的区别
- Android 中文 API (90) —— WindowManager