Elasticsearch基本组成
Elasticsearch组成示意图
                             Cluster
+--------------------------------------------------------------------------+
|               Node 1                             Node 2                  |
|  +-----------------------------+    +-----------------------------+      |
|  |                             |    |                             |      |
|  | +---------+   +-----------+ |    | +---------+   +-----------+ |      |
|  | | shard A |   |replica B1 | |    | | shard B |   |replica A1 | |      |
|  | +---------+   +-----------+ |    | +---------+   +-----------+ |      |
|  |                             |    |                             |      |
|  +-----------------------------+    +-----------------------------+      |
|                                                                          |
|               Node 3                                                     |
|  +---------------------------------+                                     |
|  |                                 |                                     |
|  | +-------------+   +-----------+ |                                     |
|  | | reaplica A2 |   |replica B2 | |                                     |
|  | +-------------+   +-----------+ |                                     |
|  |                                 |                                     |
|  +---------------------------------+                                     |
|                                                                          |
+--------------------------------------------------------------------------+
Elasticsearch是一个分布式系统,以集群(Cluster)方式运行。所谓集群就是多台计算机
协同对外提供服务,是相对于单台计算机而言,集群方式有两个好处:1. 集群内某台计算
机出现故障时,不影响集群作为一个整体对外提供服务,2. 充分了利用了多台计算机的运
算能力,有更强的服务能力。上图中的Node 1、Node 2和Node 3分别指集群内的一台计算
机,Node也可以按照英文本义翻译成节点。
在Elasticsearch的语境中,Index(索引)有两种意思:
- 含义和mysql中的索引类似,就是为了便于搜索,写入时建立的索引结构
- 类似mysql中的表(table)的概念,结构和逻辑上相似的数据组成的集合,称为一个Index
 这一节讨论的是第2种含义的索引(Index)
在分布式的情况下,一个索引(Index)被分成很多分片(shard),每一个分片是一个相对独立
单元,能够提供数据写入, 更新, 查询等.不同分片(shard)可以分布在不同的Node上,以便
充分利用分布式多台计算机的优势.
一个分片(shard)还可以有一个或者多个副本,分片副本的数据完全拷贝对应分片的数据,
这也是从分布式系统容灾的角度设计的.当一个分片所在机器因为某种原因无法提供服务时
或者数据丢失时,该分片的副本此时能提供服务.
一个索引的分片数量在索引创建后就不可更改,分片副本数量可以随时更改
shard内部结构
Elasticsearch是基于Apache Luence开发的,一个分片(shard)是相对独立的单元,实际是一
个Luence中的索引(Index),它的内部结构如下:
        shard(Luence Index)
+-------------------------------------+
| segement1                           |
|   +-+   segement2                   |
|   | |     +-+   segement3           |
|   | |     | |     +-+    segement4  |
|   | |     | |     | |     +-+       |
|   | |     | |     | |     | |       |
|   +-+     +-+     +-+     +-+       |
+-------------------------------------+
shard由许多segement组成,一个segement可以看成是一个小的索引,可以进行文档的搜索
segement中存储数据的结构有: Inverted Index(倒排索引)、Stored Field、
Document Value(field cache)。
- Inverted Index(倒排索引)用于搜索,可以根据搜索关键词,快速找到匹配文档的ID
- stored Field原始的文档,Elasticsearch中原始文档是json格式的字符串,我们可以根
 据文档ID从Stored Field中获取某个字段的值
- Document Value的用途和Stored Field一样,也是为了根据文档ID来获取某个字段的值,
 但Document Value获取的速度更快,对于大量数据aggregation(聚合)的场景场景十分有用
segement本身还有一个重要性质:segement对象创建后是不可变的。这意味着Elatic-
search在删除请求时,并不会立刻删除文件,而是将segement中的文件先标记为删除状态。
segement创建的时机有2个:新增文档时或者segement合并。
- 新增的文档首先进入到内存中缓存(此时无法被搜索到),默认情况下,每隔1s钟,
 Elasticsearch会把缓存的文档刷新到一个新建的Segement里(此时可以被索引到)。这也是
 Elasticsearch不是实时,而是接近实时(near real time)的原因。
- 随着时间推移,Shard里会有越来越多的大大小小的segement,这时Elasticsearch会合并
 小的segement,合并的同时,会真正删除掉标记为删除的数据
Inverted Index(倒排索引)
Inverted Index(倒排索引)结构并不复杂,我们直接看一个例子,假设有以下3条数据:
1: winter is coming
2: ours is fury
3: the choice is yours
对应的Inverted Index(倒排索引)如下
terms      frequency   documents ID
-----------------------------------
choice        1           3
comming       1           1
fury          1           2
is            3         1,2,3
ours          1           3
the           3         1,2,3
winter        1           1
yours         1           3
输入的字符串经过处理得到了terms,包含terms的文档ID和出现频率也记录了下来。
当我们根据某个词语搜索时,能够迅速得到包含这个词语的文档,这是Elasticsearch搜索
的原理。
其他一些高级的搜索也是基于同样原理,比如中文里的根据拼音首字母搜索,在插入数据
时可以建立拼音字母的terms,比如有下面的文档
1: 北京大学
2: 清华大学
为了支持拼音首字母搜索,可以建立下面的索引
terms      frequency   documents ID
-----------------------------------
bjdx        1           1
qhdx        1           2
由此也说明,处理输入数据得到terms这一步是非常重要的
一次完整的搜索过程
                                         Elasticsearch Cluster
                               +--------------------------------------+
                               |                      +-------+       |
                               |                .---->|Node B |       |
   o   ...{"term":"winter"}... |      +------+ /      +-------+       |
   T  -------------------------+----> |Node A|/                       |
  / \                          |      |      |\       +-------+       |
                               |      +------+ `----->|Node C |       |
                               |                      +-------+       |
                               +--------------------------------------+
- 用户发起查询请求,查询语法是Elasticsearch特有的,也是JSON格式的
- 请求随机的分发到Node A,由Node A来处理这个请求
- NodeA根据请求的索引,把请求分别发送到改索引的所有shard
- 各个shard接收到请求后,在shard内的每个segement里执行搜索请求,然后每个
 segement的数据
- 各个shard把自己的搜索结果发送给Node A, Node A汇总最后的结果,返回给用户
Elasticsearch和CAP定理
Elasticsearch作为一个分布式系统究竟有多可靠呢?特别是在发生网络故障的时候?
这不是一个容易回答的问题,Elasticsearch官方长期维护了一个页面
说明这个问题.
总之把Elasticsearch当作主要的数据存储并不被推荐,认为Elasticsearch不丢数据的想法
也是不对的.