多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 索引(Index) 一个索引就是一个拥有几分相似特征的文档的集合。比如说订单数据的索引,商品数据的索引。一个索引由一个名字来标识(必须全部是小写字母)。并且当我们要对这个索引中的文档进行索引、搜索、更新和删除的时 候,都要使用到这个名字。 ## 文档(Document) 一个文档是一个可被索引的基础信息单元,也就是一条数据。 ## 字段(Field) 相当于是数据表的字段 ## 分片(Shards) 将索引划分成多份的能力,每一份就称之为分片 分片很重要,主要有两方面的原因: * 允许你水平分割 / 扩展你的内容容量。 * 允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。 至于一个分片怎样分布,它的文档怎样聚合和搜索请求,是完全由 Elasticsearch 管理的, 对于作为用户的你来说,这些都是透明的,无需过分关心。 ## 副本(Replicas) 创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。 复制分片之所以重要,有两个主要原因: * 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。 * 扩展你的搜索量/吞吐量,因为搜索可以在所有的副本上并行运行。 ## 倒排索引 传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。 而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表 即为倒排索引。 ## 词条 索引中最小的存储和查询单元 ## 词典 字典,词条的集合,数据结构一般是B+ 树或者 HashMap ## 倒排索引不变 倒排索引被写入磁盘后是 不可改变的,它永远不会修改。 不变性有重要的价值: * 不需要锁。如果你从来不更新索引,你就不需要担心多进程同时修改数据的问题。 * 一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求内存,而不会命中磁盘。这提供了很大的性能提升。 * 其它缓存(像 filter 缓存),在索引的生命周期内始终有效。它们不需要在每次数据改变时被重建,因为数据不会变化。 * 写入单个大的倒排索引允许数据被压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的使用量。 ## 动态更新索引 ### 如何在保留不变性的前提下实现倒排索引的更新? 用更多的索引。通过增加新的补充索引来反映新近的修改,而不是直接重写整个倒排索引。每一个倒排索引都会被轮流查询到,从最早的开始查询完后再对结果进行合并。Elasticsearch 基于 Lucene, 这个 java 库引入了按段搜索的概念。每一 段本身都是一个倒排索引, 但索引在 Lucene 中除表示所有段的集合外, 还增加了提交点的概念 — 一个列出了所有已知段的文件。 ![](https://img.kancloud.cn/82/c6/82c6fc997e4d82810ec9a04bb8f79637_831x499.png) #### 按段搜索会以如下流程执行: 1.新文档被收集到内存索引缓存 ![](https://img.kancloud.cn/be/1b/be1b0d54df54ff4e8adba7cc4c7ab502_821x592.png) 2. 不时地, 缓存被 提交 (1) 一个新的段—一个追加的倒排索引—被写入磁盘。 (2) 一个新的包含新段名字的 提交点 被写入磁盘 (3) 磁盘进行 同步 — 所有在文件系统缓存中等待的写入都刷新到磁盘,以确保它们被写入物理文件 3. 新的段被开启,让它包含的文档可见以被搜索 4. 内存缓存被清空,等待接收新的文档 ![](https://img.kancloud.cn/16/81/1681860ad01b96c3de005c410a345185_830x614.png) 当一个查询被触发,所有已知的段按顺序被查询。词项统计会对所有段的结果进行聚合,以 保证每个词和每个文档的关联都被准确计算。 这种方式可以用相对较低的成本将新文档添 加到索引。 段是不可改变的,所以既不能从把文档从旧的段中移除,也不能修改旧的段来进行反映文档 的更新。 取而代之的是,每个提交点会包含一个 .del 文件,文件中会列出这些被删除文档 的段信息。 当一个文档被 “删除” 时,它实际上只是在 .del 文件中被 标记 删除。**一个被标记删除的文档仍然可以被查询匹配到, 但它会在最终结果被返回前从结果集中移除。** 文档更新也是类似的操作方式:当一个文档被更新时,旧版本文档被标记删除,文档的新版 本被索引到一个新的段中。 可能两个版本的文档都会被一个查询匹配到,但被删除的那个 旧版本文档在结果集返回前就已经被移除。 ## 近实时搜索 在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh 。 默认情况下每个分 片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是 近 实时搜索: 文档的变化 并不是立即对搜索可见,但会在一秒之内变为可见。 可以通过设置 refresh_interval , 降低每个索引的刷新频率 { "settings": { "refresh_interval": "30s" } } ## 主节点选举机制 * 每个节点最小的ID,把它选举为临时Master,然后对该master进行投票; * 每个节点收集票数,当票数大于指定的法定个数时,成为Master,然后对加入的节点进行集群信息广播。 ## 路由计算规则 通过 hash 函数生成一个数字,然后这个数字再除以主分片的数量(num_of_primary_shards)后得到余数。 这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了。(Redis也是这样,但是Redis的主分片是可以重新设置数量的) 路由规则可以自定义,默认的是文档_id ## 分片控制 用户可以访问任何一个节点获取数据,这个节点就是协调节点,他会把请求以轮询的方式(负载均衡)转发到其他节点。