Elasticsearch用于构建高可用和可扩展的系统。可以通过购买更好的服务器(纵向扩展或向上扩展)或购买更多服务器(横向扩展或横向扩展)来实现扩展。虽然Elasticsearch可以从更强大的硬件获得更好的性能,但垂直扩展有其局限性。真正的扩展应该是横向的,通过增加节点来分散负载,增加可靠性。对于大多数数据库,向外扩展意味着您的程序必须进行重大更改才能利用这些新增功能。相比之下,Elasticsearch天生就是分布式的:它知道如何管理节点以提供高可扩展性和高可用性。这意味着您的程序不需要关心这个。ES是如何实现分布式索引的?ES中存储数据的基本单位是索引。为了向ES中添加数据,我们需要添加一个索引(index)。这里需要说一下ES中索引和分片(shards)的关系:a分片是一个最低级别的“workerunit”,它只保存索引中所有数据的一部分;所有文档都存储在分片中,并重复索引直接与应用程序交互。我们以酒店搜索为例,添加所有酒店索引hotel_idxPUT/hotel_idx{"settings":{"number_of_shards":3,"number_of_replicas":1}}我们启动了三个ES节点,目前hotel_idx分配了3个primaryshards(primaryshards),每个主分片有1个副本分片。1.ES客户端将选择一个节点。如果选择NODE1,它将成为写入数据的协调节点。ES如何知道将文档(一段酒店数据)路由到哪个分片?其实他是根据这个公式:shard=hash(routing)%number_of_primary_shardsrouting是一个变量值,默认是文档的_id,也可以设置成自定义值,这里可以是hotel_id酒店的。路由通过hash函数生成一个数,然后用这个数除以number_of_primary_shards(primaryshards的个数)得到余数。这个分布在0和number_of_primary_shards-1之间的剩余部分就是我们要查找的文档所在的分片的位置。2、写入P0后,会同步到它的副本R0。如果同步成功,则返回给协调节点Node1,最后返回给Client3。ES客户端可以读取数据,读取主分片和次分片。如何保证高可用如上NODE1-如果master节点宕机,ES会重新选举(后面需要考虑分享分布式选举的话题),如果选择NODE2作为master。如果是非master宕机(node2),master节点node1会将Node3的R1副本转移到primaryshardP1上接收写操作。如果Node2恢复,之前的P1将被转移到R1副本。如何扩容ES在创建索引的时候需要指定primaryshards的个数,所以指定的primaryshards不能扩容。当存储容量超过当前ES节点时,一些生产方式一般是重新建立一个新的。索引比当前分片多一点,然后导入数据,但是这种方法也有一些缺点:这样做消耗的时间是我们无法提供的;我们一般的做法是提前预分配,通过事先规划,我们可以使用预分配的方式来完全避免这个问题。其中,副本分片可以动态扩展。在大读场景下,适当扩容replica会增加吞吐量。PUT/hotel_idx/_settings{"number_of_replicas":2}如何估计分片容量其实很难解释,因为相关因素太多了:你使用的硬件,文档的大小和复杂度,文档如何索引分析、运行的查询类型、执行的聚合、您的数据模型等。针对生产经验的建议:1.根据您将在生产环境中使用的硬件,创建具有单个节点的集群。2.创建一个与您将在生产中使用的配置和分析器相同的索引,但让它只有一个主分片,没有副本分片。索引实际文档(或尽可能接近实际文档)。3.运行实际查询和聚合(或尽可能接近实际)。基本上,您需要复制真实环境的使用方式,并将它们全部压缩到一个分片上,直到它“死掉”。实际挂起的定义也取决于你:一些用户需要所有响应在50毫秒内返回;其他人很乐意等待5秒钟。因此,一旦定义了单个分片的容量,就很容易计算出整个索引的分片数量。用你需要索引的数据总数加上一部分预期增长除以单个分片的容量,结果就是你需要的主分片数。
