ES是如何解决高并发的?
es是一个分布式全文检索框架,隐藏了复杂的处理机制,内部使用分片机制、集群发现、分片负载均衡请求路由。
Shards分片:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的服务器上,构成分布式搜索。
Replicas分片:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个服务器某个分片损坏或丢失时可以从副本中恢复。二是提高了es的查询效率,es会自动对搜索请求进行负载均衡。
需要注意的是,分片的数量只能在索引创建前指定,并且在创建后不能更改,而副本是可以更改的。
为什么要实现集群?
单台es服务器,随着业务量的发展索引文件慢慢增多,会影响到效率和内存存储问题等。
采用集群的方式部署,可以将单个索引的分片分布到多个不同服务器上存储,从而实现高可用,提高容错性等。
集群原理分析
每个索引都会被分成多个分片进行存储,默认创建索引是分配5个分片进行存储,每个分片都会分布式分配在多个不同的服务器上。
每一个分片为了实现高可用,都会有自己对应的副本(副分片),主分片和对应的副分片不能存放在同一台服务器上,只可以和其它副分片存放在一起。
按图中所示,有3个分片和3个副分片,这样子存放可以保证有其中一台服务器宕机时,另一台服务器可以恢复完整的数据。
如果是按P1 R1 P2 ,R2 P3 R3这样子存放的话,当其中一台服务器宕机的情况下,另一台的数据就不完整了。
而且分片和副分片放在同一台服务器上,是没有意义的,一旦宕机,会一起丢失。所以单机版的es是不会有副分片的,因为没有意义,集群才有。
需要注意的是,写操作会在分片上进行,写完之后会实时同步到副分片;而读操作会在分片和副分片轮询。
上述所描述的是以两台服务器为基础进行讲解的,那么当需要再添加一台服务器的时候,也就是集群变成有3台服务器,此时会发生什么情况?
由于分片数量只能在索引定义的时候设置,之后就不能再进行更改,那我们还是以3个分片+3个副分片进行分析,由上图所示,可以看出,当服务器多了一台之后,变成3台服务器,那么每台服务器均匀分布有2个分片和副分片,当服务器宕机了两台时,数据就不完整了。
前面提到了副分片是可以在索引定义好之后还能再进行修改数量的,那么我们可以通过添加副分片来解决这个问题。
一般分片的数量应该设置成服务器数量的平方,有三台服务器的话,就设置有9个分片(3个分片+6个副分片)。
想要查看索引分片信息的话。
可以访问链接 http://192.168.1.108:9200/indextest/_settings
可以看到返回了两个参数
number_of_shards:5 主分片
number_of_replicas:1 副分片
返回的数据显示副本数为1,意思是每个分片都对应有一个副分片;所以加起来有10个分片,5个主分片,5个副分片。
为什么分片定义好之后就不能修改了?
es的负载均衡是通过数据路由的方式实现的。
当客户端发起创建文档的时候,es需要确定这个文档应该放在索引的哪个分片上。这个过程就是数据路由。
路由算法: shard = hash(routing) % 分片数。 routing就是文档id,hash是对文档id进行取哈希值。
如上图所示,es的负载均衡是根据路由算法的,即将文档id取hash值然后取余分片数,获取到对应的分片存在的服务器进行访问。如果修改了分片数量的话,就乱套了。
当访问一台没有存放对应分片的服务器获取数据时,这台服务器会转发到另一台有存放的服务器。例如向node1服务器获取id=1的文档,那么node1会转发到node2获取
集群环境搭建
1.准备三台服务器,可以用虚拟机,先配置一台虚拟机,然后通过克隆的方式再创建两台虚拟机。
服务器名称 | IP地址 |
node-1 | 192.168.1.106 |
node-2 | 192.168.1.107 |
node-3 | 192.168.1.108 |
2.修改配置文件elasticsearch.yml
cluster.name: myes #集群名称,三台服务器集群名称都需相同
node.name: node-1 #节点名称,每台服务器都不能相同,其它两台为node-2,node-3
network.host: 192.168.1.108 #当前服务器ip地址
discovery.zen.ping.unicast.hosts: ["192.168.1.106", "92.168.1.107","92.168.1.108"] #三台服务器的ip
discovery.zen.minimum_master_nodes: 2
最后一个参数表示的是 形成集群的最少节点数目。
例如一个有10节点的集群,且每个节点都有成为主节点的资格。那我们设置最少节点数目为6,当有三台服务器宕机的时候,还剩余7台服务器>6,那么还能继续形成集群,而宕机的三台服务器<6,当三台服务器恢复正常后不会自己形成一个集群,该参数就是为了防止“脑裂”。
官方的推荐值是(N/2)+1,其中N是具有master资格的节点的数量(我们的情况是3,因此这个参数设置为2,但对于只有2个节点的情况,设置为2就有些问题了,一个节点DOWN掉后,你肯定连不上2台服务器了,这点需要注意)。
3.关闭防火墙 systemctl stop firewalld.service
默认底层开启9300 集群
4.启动每台服务器的es
验证集群效果
http://192.168.1.108:9200/_cat/nodes?pretty
需要注意的是,如果是采用一个虚拟机搭建好环境,然后再克隆两个虚拟机的方式搭建的集群,由于将es的data文件夹也一起克隆了,可能会导致数据不同步,报failed to send join request to masterc错误。
解决办法是直接删除掉每台服务器的data文件夹。