一.索引
索引只是一个用来指向一个或多个分片(shards)的“逻辑命名空间(logical namespace)”。
一个分片(shard)是一个最小级别“工作单元(worker unit)”,它只是保存了索引中所有数据的一部分。
当你的集群扩容或缩小,Elasticsearch将会自动在你的节点间迁移分片, 以使集群保持平衡。
索引名必须是全部小写,不能以下划线开头,不能包含逗号。
_type的名字可以是大写或小写,不能包含下划线或逗号。
你可以向已有映射中增加字段, 但你不能修改它。如果一个字段在映射中已经存在, 这可能意味着那个字段的数据已经被索引。 如果你改变了字段映射, 那已经被索引的数据将错误并且不能被正确的搜索到。
我们可以更新一个映射来增加一个新字段,但是不能把已有字段的类型那个从analyzed改到not_analyzed。
字段设置为analyzed会对其进行分词操作置为全文文本,而设置为not_analyzed会置为精确值。
一个索引可以由一个或多个原始分片组成,所以一个对于单个索引的搜索请求也需要能够把来自多个分片的结果组合起来。
1.1重新索引数据
虽然你可以给索引添加新的类型,或给类型添加新的字段,但是你不能添加新的分析器或修改已有字段。假如你这样做,已被索引的数据会变得不正确而你的搜索也不会正常工作。
修改在已存在的数据最简单的方法是重新索引:创建一个新配置好的索引, 然后将所有的文档从旧的索引复制到新的上。
为了更高效的索引旧索引中的文档,使用[scan-scoll]来批量读取旧索引的文档,然后将通过[bulk API]来将它们推送给新的索引。
注:即使你认为现在的索引设计已经是完美的了,当你的应用在生产环境使用时, 还是有可能在今后有一些改变的。所以请做好准备:在应用中使用别名而不是索引。然后你就可以在任何时候重建索引。别名的开销很小,应当广泛使用。
二.分片
分片可以是主分片(primary shard)或复制分片(replica shard)。
主分片:你索引中的每个文档属于一个单独的主分片, 所以主分片的数量决定了索引最多能存储多少数据。
复制分片只是主分片的一个副本, 它可以防止硬件故障导致的数据丢失, 同时可以提供读请求, 比如搜索或者从别的shard取回文档。
当索引创建完成的时候, 主分片的数量就固定了, 但是复制分片的数量可以随时调整。
注意:若添加复制分片,而ES仅有一个节点,则此时ES状态为黄色,因为当前节点仅分配了主分片;可增加节点,启动第二个节点,令复制分片能够分配到响应节点上,此时ES状态改为绿色。其中,主分片与复制分配分开存储。
文档的索引将首先被存储在主分片中, 然后并发复制到对应的复制节点上。 这可以确保我们的数据在主节点和复制节点上都可以被检索。
路由分片:
shard = hash(routing) %number_of_primary_shards (1)
其中,routing 值是一个任意字符串, 它默认是 _id 但也可以自定义。 这个 routing 字符串通过哈希函数生成一个数字, 然后除以主切片的数量得到一个余数(remainder), 余数的范围永远是 0 到 number_of_primary_shards - 1 , 这个数字就是特定文档所在的分片。
主分片的数量只能在创建索引时定义且不能修改:如果主分片的数量在未来改变了, 所有先前的路由值就失效了, 文档也就永远找不到了。
新建、 索引和删除请求都是写(write)操作, 它们必须在主分片上成功完成才能复制到相关的复制分片上。
主/备分片写操作(单请求):
在主分片和复制分片上成功新建、 索引或删除一个文档必要的顺序步骤:
1. 客户端给Node 1发送新建、索引或删除请求。
2. 节点使用文档的_id确定文档属于分片0。它转发请求到Node 3,分片0位于这个节点上。
3. Node 3在主分片上执行请求,如果成功,它转发请求到相应的位于Node 1和Node 2的复制节点上。当所有的复制节点报告成功,Node 3报告成功到请求的节点,请求的节点再报告给客户端。
客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了。
主/备分片写操作(多请求):
使用一个 bulk 执行多个create、index、delete和update请求的顺序步骤:
1.客户端向Node 1发送bulk请求。
2.Node 1为每个分片构建批量请求,然后转发到这些请求所需的主分片上。
3.主分片一个接一个的按序执行操作。当一个操作执行完,主分片转发新文档(或者删除部分) 给对应的复制节点,然后执行下一个操作。复制节点为报告所有操作完成,节点报告给请求节点,请求节点整理响应并返回给客户端。
三.横向扩展/缩小容量
如果我们启动第三个节点, 我们的集群会自我感知, 这时便成为了三节点集群(cluster-three-nodes)。分片会被重新分配以平衡负载。
如果我们杀掉的节点是一个主节点,必须有一个主节点来让集群的功能可用, 所以发生的第一件事就是各节点选举了一个新的主节点。
删除一个文档也不会立即从磁盘上移除, 它只是被标记成已删除。Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。
当我们发送请求, 最好的做法是循环通过所有节点请求, 这样可以平衡负载。