小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文消化于 Java3y 大神的Elasticsearch文章,以前都是一知半解,现在算是对整个流程有了初步了解,接下来就是在公司的项目业务中不短实践!!
1.Elasticsearch
1.1什么是Elasticsearch
首先,Elasticsearch是一个实时的分布式存储、搜索、分析引擎(搜索引擎)。
关于es,有人说它的功能,用关系型Mysql等也能实现,实现是可以,但是从性能优化与擅长来说,还是需要专业的工具。需要明确的是,es并不是要取代其他DB,相反的,在大部分业务场景中:”一个常见的设置是使用其他数据库作为主要的数据存储,使用Elasticsearch作为数据检索“——这是在2.X的官方文档里面提到的。
-
对比Mysql
- 在数据检索方面,以商品搜索为例,Mysql也不是不能做到,利用模糊查询—— '%名字%'
- 但是模糊查询的话,是不走索引的,所以在数据量大的情况下(亿条),查询会以秒作为单位
- 而且作为搜索功能来说的话,类比百度、淘宝等搜索,是存在一个分词+模糊查询(错词漏词)
1.2关于Elasticsearch
-
es的数据结构
关于es搜索快,是因为索引的区别
- 在其他数据库中,常用的是正向索引,以书本为例,正向索引就是书本的,通过书本的目录查找到页码,并跳转具体的页码获取内容
- 而es是用倒排索引,也就是通过分词,如:目录上出现过某个词,用户通过搜索这个词,找到目录中存在这个词的相关目录,并再通过目录跳转到具体的内容
-
es分词
es内置的分词都是英文的,而目前业务场景大部分都是中文, 目前中文分词用的最多就是IK
-
关于es的数据结构
- es分词后存储于TermDictionary,通过分词后找到对应的文档ID,保存在PostingList
- 由于分词的数量大,会先进行排序,等到查询的时候用二分查询,就不需要遍历整个TermDictionary
- 数据量过大的时候,不可能把所有的词都放在内存内,Es抽离了一层叫做Term Index,存储词的前缀,类似力扣做题的前缀树
-
关于Elasticsearch的类型
Elasticsearch Mysql Index Table Document Row(一行数据) Field Column(一个属性) Mapping Schema(数据库组织) DSL SQL -
Elasticsearch的架构
- 集群下有多个机器部署着es,这些机器称为节点;其中有一个是主节点,负责维护索引元数据,切换主副分片;主节点挂了会重新推选节点
- 在es中,index(表)的数据会分发到不同的节点去存储,这就叫做分片
- Index 存储到各个节点,分片也会有主副分片;主分片负责写入数据,副分片负责复制主分片的数据;读取的时候主副分片都可以读取
- 在一个集群里面每一个节点都是 协调节点(coordinating node),协调节点可看作前端的路由;当前节点收到请求,但是发现是其他节点处理的,会转发请求。【通过Hash算法计算出在那个主分片】
-
Elasticsearch的写操作
-
数据先写到内存缓存区,每隔1s刷新(refresh)到文件系统缓存区
- 这个过程需要1s,这也就是为什么es是近实时,而非完全实时的原因,但是对于大部分的业务都是可以接受的
- 当数据refresh到文件系统缓存区(FileSystemCache)时,生成Segment文件,生成后数据才会被索引到
-
为了防止宕机,es会将数据写到日志文件缓存区(translog buffer)中,每隔5s才会刷新到磁盘
- 这也就是当es宕机时,因为某个节点挂掉了,会有可能导致5s的数据丢失。
-
定期(30min)/定量从文件系统缓存区结合日志文件缓存区的segment文件异步刷新到磁盘,实现持久化
-
1.3 在项目中使用Elasticsearch
-
在项目中使用ES作为日志的输出,因为公司项目是TO-B面向农业的项目,所以暂时还没有类似电商的商品检索的功能;部分的模糊查询功能性业务可以使用mysql胜任。作为日志查询,领导没有开放服务器权限的前提下,把日志映射到ES,通过ES映射到可视化工具kibana中,供组员开发使用
-
很多时候,会被问到在项目中MongoDB和ES的技术选型
虽然都是属于json管理数据的no-sql数据库(文档型),但是业务场景不一样。es更多是辅助其他数据库作为检索、数据分析功能去使用。MongoDB更偏向于数据量大的业务,适用于一些事务要求性不高的业务。
-
业务选型
MongoDB的话在项目中会放一些历史数据,例如车辆轨迹的历史数据,一些设备的参数与反馈记录
ES的话则会参与一些实时的业务数据,复杂的事务等操作,例如库存里面的商品检索(虽然有点过度设计)