“智慧的开始,是对自己无知的承认。” ——苏格拉底
点关注,不迷路
大家好,我是侠风,以后会持续更新在大厂实践中的一些硬核技术知识分享,希望小可爱们"一键三连"呀。
数据库使用排名
DB-Engines Ranking链接地址:db-engines.com/en/ranking
从上图我们可以看到,Elasticsearch作为一个搜索数据库,排名还是非常靠前的。其实除了Elasticsearch,还有Solr、Sphinx、Whoosh、Bleve等,都是搜索数据库,但是Elasticsearch的市场占有率是最高的。
ES与solr的区别:两者底层都是使用lucene去进行文本搜索。但是Solr更加专注于文本处理,而ES则常用于查询、过滤与分组分析统计。ES的分布式架构,不管是易用性,扩展性,还是速度上,都要优于Solr,ES的社区活跃度也更加高。
集群结构
集群(Cluster):一个集群就是由一个或多个节点(Node)构成的,每个集群都有一个唯一的名字,默认是elasticsearch,在 config/elasticsearch.yml 中配置。
节点(Node):一个节点就是一个Elasticsearch的运行实例,每个节点都有自己的名字,默认是运行实例的机器名,例如上图中的node-1、node-2、node-3。
索引(Index):一个索引就是一个拥有相同特性的文档集合,可以类比为关系型数据库中的表。在存储结构上由 _index、_type、_id 唯一标识为一个文档。
分片(Shard):一个索引可以被拆分为多个分片,每个分片都是一个独立的Lucene实例,可以类比为关系型数据库中的分区。上图中有P0、P1、P2三个分片。这三个副本共同组成一份完整的索引数据。
副本(Replica):每个分片可以有多个副本,副本是分片的完整拷贝,可以类比为关系型数据库中的备份。上图中有R0、R1、R2三个副本。
Lucene: 每个分片都是一个Lucene实例,可以将其看做一个独立的搜索引擎,它能够对Elasticsearch中的数据进行索引和搜索。
segment: Lucene索引文件的存储形式,一个segment就是一个倒排索引文件,每个分片包含多个segment。
注意: 分片数和副本数可以在创建索引的时候指定,当索引创建以后,可以动态的改变副本数,但是不能改变分片数。给索引扩容方案,可以在后续文章中讲解。
索引数据结构
ES存储在集群index中的是一个个的文档,它是指最顶层或者根对象,这个根对象被序列化成JSON格式,然后存储在ES中,它指定的唯一ID,也就是document id。
文档中的元数据
一个文档不仅仅包含它的数据 ,也包含 元数据 —— 有关文档的信息。 三个必须的元数据元素如下:
- _index: 文档在哪存放
- _type: 文档表示的对象类别
- _id: 文档唯一标识
倒排索引
ES使用倒排索引的数据结构,它适用于快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,都有一个包含它的文档列表。
例如,假设我们有两个文档,每个文档的 content 域包含如下内容:
- The quick brown fox jumped over the lazy dog
- Quick brown foxes leap over lazy dogs in summer
为了创建倒排索引,我们首先将每个文档的 content 域拆分成单独的 词(我们称它为 词条 或 tokens ),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。结果如下所示:
现在,如果我们想搜索 quick brown ,我们只需要查找包含每个词条的文档:
两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单 相似性算法 ,那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。
ES数据写入过程
ES 如何做到准实时搜索
ES写入是会先refresh到操作系统的cache中,默认1s刷新一次,这个时候会生成segment,跟磁盘中的结构是一样的,没刷新一次,会生成一个新的segment。并且因为是内存操作,写入非常快。
ES读取时,会从cache中读取,如果cache中没有,则从磁盘中读取。所以基本可以做到准实时。
结尾
感谢看完的小可爱,如果觉得文章对你有帮助,请帮忙"一键三连"呀,感谢感谢。
后续会持续更新硬核技术文章,欢迎关注我。有任何技术问题也可以共同探讨,包括面试技巧,简历优化,疑难解答等。