1、ES学习建议
1.1、为什么学习ES?
- 首先:ES使用文件系统缓存+倒排索引机制,让结果更快地返回,减少等待,提升系统总体的性能;
- 其次:我们在应用里面需要模糊查询的场景,使用ES几乎都可以来解决;
- 最后:学习ES对数据高效写入及查询的思想
1.2、学习的建议
- 1、阅读源码。读源码其实也是一种实战锻炼,可以帮助你从代码逻辑中彻底理解ES的实际运行机制。当遇到问题时,可以直接从代码层面进行定位、分析和解决问题
- 2、亲自动手实践
- 在开发中,使用并体会其特性
- 3、学习的路线
- ES全景知识图 todo
- 经验
- 只要有人跟你聊到es,你可以自己合盘脱出自己对分布式搜索引擎基本原理的一个理解,以及你们在项目中一般是如何优化的,包括你们生产环境是怎么部署的,数据量多大。让别人感觉你这块至少还是正经了解和干过的。
1.3、ES学习资料
- 推荐书籍
- todo
1、什么是Elasticsearch?
ES构建于Lucene之上,近实时搜索、分析文档,并且支持结构化、非结构化文档
- 结构化:有固定的数据格式、以及长度,通常见于数据库
- 非结构化:数据结构不固定,不定长
ES具有分布式、高可用、可伸缩的特性
支持更快的检索性能
2、如何使用?
1、Elasticsearch 提供restful 风格的java客户端,使用时选择对应版本
2、也可用zcy-search-util,注解化生成对应dsl,简单快捷 ,强烈推荐
3、spring data es
基础概念:
- 文档:一条json数据,对应mysql表里的一行数据
- 索引:文档的一个集合,对应mysql的表
- Mapping:定义 ES 对索引中字段的存储类型、分词方式等,类似于数据库的Schema
2.1、创建索引mapping
- ES可根据写入的document自动构建mapping,但是不一定是使用场景的最佳mapping。
- mapping一旦创建,字段设置将不可更改,建议根据场景、性能要求,自己提前手动创建mapping
2.2、写入数据
3、搜索
3、在商品搜索的应用
数据量:5千万文档、1.4T 大小
- 索引拆分:全量、基础、协议、可售(前台)
- 独立集群、部署架构调整
document模型设计
- mysql,有两张表
- 订单表:id order_code total_price
1 测试订单 5000
- 订单条目表:id order_id goods_id purchase_count price
1 1 1 2 2000
2 1 2 5 200
- 在mysql里,都是
select * from order join order_item on order.id=order_item.order_id where order.id=1
1 测试订单 5000 1 1 1 2 2000
1 测试订单 5000 2 1 2 5 200
- 在es里该怎么玩儿,es里面的复杂的关联查询,复杂的查询语法,尽量别用,一旦用了性能一般都不太好
- 设计es里的数据模型
- 写入es的时候,搞成两个索引,order索引,orderItem索引
- order索引,里面就包含id order_code total_price
- orderItem索引,里面写入进去的时候,就完成join操作,id order_code total_price … id order_id goods_id purchase_count price
- 写入es的java系统里,就完成关联,将关联好的数据直接写入es中,搜索的时候,就不需要利用es的搜索语法去完成join来搜索了
- document模型设计是非常重要的,很多操作,不要在搜索的时候才想去执行各种复杂的乱七八糟的操作。es能支持的操作就是那么多,不要考虑用es做一些它不好操作的事情。如果真的有那种操作,尽量在document模型设计的时候,写入的时候就完成。另外对于一些太复杂的操作,比如 join,nested,parent-child 搜索都要尽量避免,性能都很差的。
- 很多复杂的乱七八糟的一些操作,如何执行
- 两个思路,在搜索/查询的时候,要执行一些业务强相关的特别复杂的操作:
- 1)在写入数据的时候,就设计好模型,加几个字段,把处理好的数据写入加的字段里面
- 2)自己用java程序封装,es能做的,用es来做,搜索出来的数据,在java程序里面去做,比如说我们,基于es,用java封装一些特别复杂的操作
插件:
- 定制分词插件:基于hanlp、远程词库、词库管理、
索引:
- 开启慢查询日志
- merge 限制 (商品每天变更200-1000w)
- 夜间force merge
- number 类型用 keyword、index:false 不索引等
- shard数调整优化,同时方便后续快速扩容
写入:
- 一对多通过_update_by_query 修改
- 批量写入
- 不紧急数据夜间写入
响应时长:一般几百毫秒就能搞定
性能
- 针对聚合,限制聚合大小
- 聚合结果缓存
- 限制每shard结果数据量
- 设置超时时间,到时间结束检索、返回结果
- 限制页大小
- 结果字段按需获取
准确性
- 查询改写:同义词、实体识别
- 类目预测
业务支撑
- 通过top hit 支持箪食类外卖模式的检索
- zcy-search,通过注解来快速支撑简单需求
3.1、说说你们公司es生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片?以及一些调优手段 ?
想了解应聘者之前公司接触的ES使用场景、规模,有没有做过比较大规模的索引设计、规划、调优。
解答
:如实结合自己的实践场景回答即可。比如:ES集群架构13个节点,索引根据通道不同共20+索引,根据日期,每日递增20+,索引:10分片,每日递增1亿+数据,每个通道每天索引大小控制:150GB之内。
- 现状,版本:公司内目前ES集群版本为6.2.3
1、整个集群的硬件配置
- 3台master:4核8G
- 选举出的主节点负责创建索引、删除索引、跟踪哪些节点是群集的一部分
- 3台coordinator:8核32G
- 将协调节点独立,有助于降低数据节点的压力,避免互相影响
- 10台data:32核128G
- 负责数据的存储和相关的操作
- 留给文件系统缓存的内存空间为 64 X 10 640G
- 集群总内存占用是:24G + 96G + 1280G = 1.4 T
2、数据、分片
- 单节点5个主分片(默认)+5个副本分片
- 商品索引的数据量大概是50G,所以这个数据量之内,我们每个索引分配的是8个shard
- 每个分片大约14G~15G,整体存储占用1.4T
- 目前ES有4个节点、14个索引、236个分片、文档数12亿
- 14个索引分别是啥(商品信息、商品审核信息、快照信息、sku信息、属性信息、库存、服务承诺之类)
- suppliers_search-read:供应商搜索
- items-read:前台商品索引(协议商品、疫苗、分销、大宗等)搜索
- agreement_items-write:协议商品搜索
- channel_items-read:基础商品搜索
- back_items-read:全量商品搜索
- audit_app-read:商品审核记录搜索
- audit_data-read:商品审核数据搜索
- 然后是店铺、品牌、spu等
- 写可以达到 2 万
- bulk 1000 左右
- bulk是es提供的一种批量增删改的操作API
- bulk的操作类型
- create 如果文档不存在就创建,但如果文档存在就返回错误
- index 如果文档不存在就创建,如果文档存在就更新
- update 更新一个文档,如果文档不存在就返回错误
- delete 删除一个文档,如果要删除的文档id不存在,就返回错误
3、预估
- 数据量:现每月平均月增400w~600w商品左右,预计年底到明年初可接近1亿
- 存储:每天日增量数据大概是500MB,每月增量数据大概是6亿
4、基本原理
4.1、ES核心概念
- cluster
- 由一个或多个node组成
- node角色
- ES共有多种node角色,同一个node也可承担多个角色。
- 1、Master-eligible node
- 2、Data node
- 3、Coordinating node
- 4、Ingest node
- 5、Remote-eligible node
- 6、Machine learning node
- 7、Transform node
- master eligible node
- 用来选主,只有候选主节点才有选举权和被选举权,其它节点不参与选主
- 选举出的主节点负责创建索引、删除索引、跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点、追踪集群中节点的状态等,稳定的主节点对集群的健康是非常重要的。
- 通常,为了稳定性,最好使用低配置机器创建独有的候选主节点,不小于3个。
/config/elasticsearch.yml
node.master: true
- data node
- 负责数据的存储和相关的操作,例如对数据进行增、删、改、查和聚合等操作,所以数据节点(Data 节点)对机器配置要求比较高,对 CPU、内存和 I/O 的消耗很大。
data节点是集群中压力很大的节点,最好将数据节点和主节点分开,以免影响主节点稳定性,导致脑裂,造成索引、数据不一致等。
/config/elasticsearch.yml
node.data: true
- coordinating node
- 一般来说,每个节点都可承担协调节点的角色。通常,哪个节点接收客户端请求,就是本次请求的协调节点。
协调节点用来处理客户端请求,进行请求分发,结果合并,并返回给客户端。
将协调节点独立,有助于降低数据节点的压力,避免互相影响。
- shard
- 一个node可包含多个shard。一个shard就是一个Lucene实例,索引由一系列shard组成。ES之所以称作分布式搜索,既是可以将数据分散在多个shard上,提供更高的性能。
- 因为写入时,需要通过路由,确定写在哪一个shard上,所以需要在索引创建时,确定好shard数,一旦设置后将不可变。
- 默认每个索引会有5个shard。
settings.index.number_of_shards: 5
写入、搜索
4.2、es的分布式架构原理能说一下么(es是如何实现分布式的啊)?
面试官心理分析
- 在搜索这块,lucene是最流行的搜索库。几年前业内一般都问,你了解lucene吗?你知道倒排索引的原理吗?现在早已经out了,因为现在很多项目都是直接用 基于lucene的分布式搜索引擎 elasticsearch,简称es。
- 而现在分布式搜索基本已经成为大部分互联网行业的java系统的标配,其中尤为流行的就是es,前几年es没火的时候,大家一般用solr。但是这两年基本大部分企业和项目都开始转向es了。
- 所以互联网面试,肯定会跟你聊聊分布式搜索引擎,也就一定会聊聊es,如果你确实不知道,那你真的就out了。
- 如果面试官问你第一个问题,确实一般都会问你es的分布式架构设计能介绍一下么?就看看你对分布式搜索引擎架构的一个基本理解。