ld512870 发表于 2017-3-22 17:21:33

elasticsearch是怎么在各个集群之间进行交互的。

es和solrcloud都是基于lucene的全文搜索引擎。其中solrcloud是借助于zookeeper这个分布式协调系统来实现集群中各个机器通信的。那么,es是怎么实现的呢?光看到说是p2p,然后是什么广播。但是没看懂,有没有详细一点的呢?

arsenduan 发表于 2017-3-22 17:44:19

本帖最后由 arsenduan 于 2017-3-22 17:48 编辑

Solr 利用 Zookeeper 进行分布式管理, Elasticsearch 自身带有分布式协调管理功能;在同一个子网内,只需要在每个节点上设置相同的集群名,elasticsearch就会自动的把这些集群名相同的节点组成一个集群。节点和节点之间通讯以及节点之间的数据分配和平衡全部由elasticsearch自动管理。

langke93 发表于 2017-3-22 17:58:45

确实有点难懂,主要有几个陌生的概念首先明白p2p的含义
P2P就是指数据的传输不再通过服务器,而是网络用户之间直接传递数据。比如我们以前使用的电驴,还有迅雷

ES 采用的是一种 P2P 的 gossip 选举方式

Elasticsearch有一个自动发现(Discovery)功能
群中节点的自动发现和Master节点的选举。节点之间使用p2p的方式进行直接通信,不存在单点故障的问题。Elasticsearch中,Master节点维护集群的全局状态,比如节点加入和离开时进行shard的重新分配。
自动发现机制在目前版本(1.3.1)提供了四种选择,一种是默认实现,其他都是通过插件实现。
1.      Azure discovery 插件方式,多播
2.      EC2 discovery 插件方式,多播
3.      Google Compute Engine (GCE)discovery 插件方式多播
4.      zen discovery默认实现 多播/单播


上面其实比较难以理解的是多播:
那么什么是多播:
多播是指一条信息向局域网内有限几个节点传递

#####################################
多播的实现是靠多播组,在局域网内,一个多播地址唯一的定义了一个多播组(端口号任意),可以使用的多播地址是有规定的,从224.0.0.0—239.255.255.255之间,但是其中的一些地址不能用,是用作特殊用途的:224.0.0.0 –224.0.0.2224.0.1.1224.0.0.9 224.0.1.24。一个节点如果想接受自某个多播组或向某个多播组发送信息,必须首先加入多播组,然后给予UDP发送。

更多内容

是详细的代码实现。
1.初始化
    WSAStartup(MAKEWORD(2,2),&wsad);
2.这里传建一个用于多播通信的socket,注意这个socket的参数为设置成多播
    s=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED);
3.将socket绑定到一个本地地址、端口,和广播不同,在多播中,无论是发送还是接收端都必须绑定一个本地地址,这个地址就是多播通信时处理信息的端口
    udpAdress.sin_family=AF_INET;
    udpAdress.sin_port=htons(22222);
    udpAdress.sin_addr.s_addr=inet_addr("10.11.131.32");
    bind(s,(SOCKADDR*)&udpAdress,sizeof(udpAdress));
4.定义多播组的地址
    multiCastGroup.sin_family=AF_INET;
    multiCastGroup.sin_port=htons(1111);此处端口任意,每个节点的可以设置成不同的
    multiCastGroup.sin_addr.s_addr=inet_addr("224.0.0.3"); 此处需使用上面规定地址段内的多播地址
5.加入这个多播组。注意这里的函数返回了一个socket,这个socket不负责通信,只是在脱离多播组时使用
    SOCKET sockM=WSAJoinLeaf(s,(SOCKADDR*)&multiCastGroup,sizeof(multiCastGroup),NULL,NULL,NULL,NULL,JL_BOTH);
6.下面使用recvfrom接受多播信息,或者使用sendto发送多播信息   
ret=recvfrom(s,data,1000,0,(SOCKADDR*)&sender,&senferAddSize);
sendto(s,data(),totalbyte,0,(SOCKADDR*)&multiCastGroup,sizeof(multiCastGroup));
7.最后关闭清理
    closesocket(sockM);
    closesocket(s);
    WSACleanup();

其他:
1)在多播组中,默认情况下一个发出多播信息的节点也会收到自己发送的信息,这称为多播回环,可以关闭多播回环:
bool val=false;
setsocket(s,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)val,sizeof(val));
2)在多播时,通常要设置适当的TTL(TTL的值是多少,那么多播信息就可以经过多少路由器,每经过一个路由器,TTl的值自动减1):
int val=3;
setsocket(s,IPPROTO_IP,IP_MULTICAST_TTL,(char*)val,sizeof(int));






ld512870 发表于 2017-3-23 10:22:23

langke93 发表于 2017-3-22 17:58
确实有点难懂,主要有几个陌生的概念首先明白p2p的含义
P2P就是指数据的传输不再通过服务器,而是网络用户 ...

你说的对。难点就是在于p2p的原理。。。得先明白p2p是怎么通信的,才能明白es集群之间的发现机制。

liuyou2036 发表于 2020-7-16 09:14:17

有点难懂
页: [1]
查看完整版本: elasticsearch是怎么在各个集群之间进行交互的。