Elasticsearch
文档分布式存储
文档存储在分片上
-  
文档会存储在具体的某个主分片和副本分片上:例如文档1,会存储在PO和RO分片.上
 -  
文档到分片的映射算法
- 确保文档能均匀分布在所用分片.上,充分利用硬件资源,避免部分机器空闲,部分机器繁忙
 - 潜在的算法 
    
-  
随机/ Round Robin。当查询文档1,分片数很多,需要多次查询才可能查到文档1
 -  
维护文档到分片的映射关系,当文档数据:量大的时候,维护成本高
 -  
实时计算,通过文档1,自动算出,需要去那个分片.上获取文档
 
 -  
 
 
文档到分片的路由算法
- shard = hash(_ routing) % number of .primary_ _shards 
  
- Hash算法确保文档均匀分散到分片中
 - 默认的_ _routing 值是文档id
 - 可以自行制定routing数值, 例如用相同国家的商品,都分配到指定的shard
 - 设置Index Settings后,Primary 数,不能随意修改的根本原因
 
 
更新一个文档

删除一个文档

本节知识点回顾
- 可以通过设置Index Settings, 控制数据的分片
 - Primary Shard的值不能修改,修改需要重新Index。默认值是5,从7开始,默认值改为1
 - 索引写入数据后,Replica 的值可以修改。增加副本,可提高大并发下的读取性能
 - 通过控制集群的节点数,设置Primary Shard数,实现水平扩展
 
分片及其生命周期
分片的内部原理
- 什么是ES的分片
- ES中最小的工作单元/是一个Lucene的Index - 一些问题: 
  
- 为什么ES的搜索是近实时的(1秒后被搜到)
 - ES如何保证在断电时数据也不会丢失
 - 为什么删除文档,并不会立刻释放空间
 
 
倒排索引不可变性
-  
倒排索引采 用Immutable Design,一旦生成,不可更改
 -  
不可变性, 带来了的好处如下:
- 无需考虑并发写文件的问题,避免了锁机制带来的性能问题
 - 旦读入内核的文件系统缓存,便留在哪里。只要文件系统存有足够的空间,大部分请求就会直接请求内存,不会命中磁盘,提升了很大的性能缓存容易生成和维护/数据可以被压缩
 
 -  
不可变更性,带来了的挑战:如果需要让一个新的文档可以被搜索,需要重建整个索引。
 
Lucene Index

什么是Refresh

什么是Transaction Log

什么是Flush

Merge
-  
Segment 很多,需要被定期被合并
- 减少 Segments /删除已经删除的文档
 
 -  
ES和Lucene会自动进行Merge操作
- POST my_ index/ forcemerge
 
 
知识点回顾
- Shard 和Lucene Index 
  
- Index Buffer / Segment / Transaction Log
 
 - Refresh & Flush
 - Merge
 
剖析分布式查询及相关性评分
分布式搜索的运行机制
- Elasticsearch 的搜索,会分两阶段进行 
  
- 第一阶段一 Query
 - 第二阶段- Fetch .
 
 - Query- -then-Fetch
 
Query阶段

Fetch阶段

Query Then Fetch 潜在的问题
-  
性能问题
- 每个分片,上需要查的文档个数= from + size
 - 最终协调节点需要处理: number_ of shard * ( from+size )
 - 深度分页
 
 -  
相关性算分
- 个分片都基于自己的分片,上的数据进行相关度计算。这会导致打分偏离的情况,特别是数据量很少时。相关性算分在分片之间是相互独立。当文档总数很少的情况下,如果主分片大于1,主分片数越多,相关性算分会越不准
 
 
解决算分不准的方法
-  
数据量不大的时候,可以将主分片数设置为1
- 当数据量足够大时候,只要保证文档均匀分散在各个分片上,结果一般就不会出现偏差
 
 -  
使用 DFS Query Then Fetch
-  
搜索的URL 中指定参数“search?search_ type=dfs query _then. _fetch”
 -  
到每个分片把各分片的词频和文档频率进行搜集,然后完整的进行一次相关性算分,耗费更加多的CPU和内存,执行性能低下,一般不建议使用.
 
 -  
 
相关性算分问题Demo
- 写入 3条记录“Good”/“Good morning”/“good morning everyone’
 - 使用1个主分 片测试,Good 应该排在第一,Good DF数值应该是3
 - 和20 个主分片,测试
 - 当多个个主分片时,3个文档的算分都-样。可 以通过Explain API进行分析
 - 在3个主分片上 执行DFS Query Then Fetch,结果和一个分片上一致
 
Demo
DELETE message
PUT message
{
  "settings": {
    "number_of_shards": 20
  }
}
GET message
POST message/_doc?routing=1
{
  "content":"good"
}
POST message/_doc?routing=2
{
  "content":"good morning"
}
POST message/_doc?routing=3
{
  "content":"good morning everyone"
}
POST message/_search
{
  "explain": true,
  "query": {
    "match_all": {}
  }
}
POST message/_search
{
  "explain": true,
  "query": {
    "term": {
      "content": {
        "value": "good"
      }
    }
  }
}
POST message/_search?search_type=dfs_query_then_fetch
{
  "query": {
    "term": {
      "content": {
        "value": "good"
      }
    }
  }
}
 
本节知识点回顾
- 学习了 分布式搜索Query then Fetch的机制 
  
- Why/How
 
 - Query Then Fetch带来的潜在问题 
  
- 深度分页: 使用Search After
 - 算分不准:设置1个主分片/数据量大时,只需要保证文档平均分布/ DFS Query then Fetch
 
 










