[7]elasticsearch源码深入分析——client通信流程与负载均衡

本篇为elasticsearch源码分析系列文章的第七篇,由于接触到作为客户端和ElasticSearch集群通信,所以本篇以ElasticSearch的Client的通信为出发点,讲解有关Client通信和负载均衡的有关详情,叙述的不好或不对的地方还请大家指正:)

如何与集群(Cluster)通信

使用Node与cluster通信
Node node = NodeBuilder.nodeBuilder().clusterName("yourclustername").client(true).node();
Client client = node.client(); 

因为该节点是仅仅是作为一个客户端而不用保存数据,所以必须设置client(true)。
使用TransportClient与cluster通信

5.0.0版本之前可以通过如下的代码来构建TransportClient,

通过指定名称来创建

Settings settings = Settings.settingsBuilder().put("cluster.name", "es-client").put("client.transport.sniff", true).build();
TransportClient transportClient = TransportClient.builder().settings(settings).build();

通过IP地址来创建

TransportClient transportClient = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress("192.168.1.100", 9300));

通过同网段嗅探来创建

Settings settings = Settings.settingsBuilder().put("client.transport.sniff", true).build();
TransportClient transportClient = TransportClient.builder().settings(settings).builder();

如果设置client.transport.sniff为true,表示客户端去嗅探整个cluster的状态,把集群中其它机器的ip地址加到客户端中,这样做的好处是一般你不用手动设置集群里所有集群的ip到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器。

但在5.0.0版本之后新增了PreBuiltTransportClient类,而TransportClient变为Abstract类型,且被PreBuiltTransportClient继承。该类的主要意图是,指定在创建TransportClient时必须加载以下的插件:

  • Netty4Plugin
  • ReindexPlugin
  • PercolatorPlugin
  • MustachePlugin
  • ParentJoinPlugin

可见这些插件是节点的必备插件。所以5.0.0版本以后的TransportClient的创建方式变为:

PreBuiltTransportClient(Settings settings, Class<? extends Plugin>... plugins);

注:集群名称和嗅探模式可以在Settings中设置,而TransportAddress依旧可以通过addTransportAddress方法来设置。

TransportClient中TransportClient加载插件的代码

加载插件

可以看到用到了代理,TransportClient的部分API都是TransportClientNodesService进行代理的

初始化TransportClientNodesService

client单次请求流程

客户端请求的详细流程如下:

先是实例化部分:

  • 1.PreBuiltTransportClient(Settings, plugins, hostFailureListenter)实例化
  • 2.super实例化TransportClient
  • 3.TransportClient执行buildTemplate方法
  • 4.buildTemplate方法中实例化TransportClientNodesService类的对象nodesService

然后是请求部分:

  • 1.请求从AbstractClient的不同请求方法中进入(如bulk,clearScroll,delete,explain,fieldCaps,get,index,multiGet,mutiSearch,multiTermVectors,search,searchScroll,termVectors,update)
  • 2.执行AbstractClient的execute(action, Request,listener)
  • 3.执行TransportClient的doExecute方法,执行TransportClient中proxy的execute
  • 4.执行TransportProxyClient的execute方法
  • 5.执行TransportClientNodesService实例nodesService的execute方法
  • 6.调用NodeListenerCallback回调方法doWithNode
  • 7.执行TransportActionNodeProxy的execute方法
  • 8.执行TransportService的sendRequest方法
  • 9.TransportService调用sendRequest后的回调依次回传
    • TransportActionNodeProxy
    • NodeListenerCallback
    • TransportClientNodesService
    • TransportClient

整个客户端模块的简要流程如下:

  • client 提供了客户端的操作接口,比如count()
  • 代理端TransportClientNodesService的execute()随机一个节点出来
  • 代理端TransportClientNodesService通过transportService发送请求

Client的负载均衡

Client的负载均衡是通过TransportClientNodesService类实现的。TransportClientNodesService实例维护一组DiscoveryNode引用,每次客户端请求的时候,会根据负载均衡算法选中一个节点(DiscoveryNode),发送请求。常用的负载算法有Random,Round robin,Hash,StaticWeighted等。ES的客户端负载使用了Round robin算法。

此外TransportClientNodesService还负责嗅探,维护集群节点列表,选举节点的工作。

注入TransportClientNodesService

TransportClientNodesService的实例化首先注入了集群名称,线程池,最小兼容版本,客户端传输采样时间间隔,ping超时时间。然后配置了节点采样模型NodeSampler。NodeSampler接口很简单,只有一个sample()方法,它的实现类有2个SniffNodesSampler和SimpleNodeSampler,我们在初始化里已经看到了,如果"sniff"配置项是true的话使用SniffNodesSampler类。

两个实现类如下

  • 嗅探同一集群中的所有节点(SniffNodesSampler,client会主动发现集群里的其他节点,即使节点不在配置文件中,会创建fully connect)
  • 或者是只关注配置文件配置的节点(SimpleNodeSampler,ping listedNodes(也就是配置中设置的节点)中的所有node,区别在于这里创建的都是light connect)

简单的说,SimpleNodeSampler会限制当前可用client一定是在配置中设置的节点中的,这样的意图是让集群中的某些节点专门用来负责接收用户请求,而SniffNodesSampler会使用所有发现的节点,让其参与负载,即使这个节点不在配置中。

得到集群节点列表后,代理端TransportClientNodesService在每次execute时,就可以通过getNodeNumber方法随机获取节点。

如下图:

execute方法调用getNodeNumber
关键的节点选择代码

数据写入

节点是如何写入的呢? 在TransportClient的buildTemplate方法中,实例化TransportService的步骤中,通过networkModule的getRransportInterceptor方法得到的TransportInterceptor实例就是通过nettychannel写入数据的地方,如下图:

实例化TransportClient
实例化TransportService

数据还是通过上文的NodeSampler实例来写入的,FutureTransportResponseHandler设置回调操作,如下图:

NodeSampler

遍历所有的数据节点,写入到新节点里面

数据写入
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 断断续续看Ribbon的源码差不多也有7-8天了,总算告一段落。本文记录了这些天对源码的阅读过程与一些分析理解,如...
    程序猿DD阅读 6,541评论 6 11
  • from http://www.infoq.com/cn/articles/etcd-interpretation...
    小树苗苗阅读 13,941评论 3 38
  • 雨兮兮,下了一整夜,风也刮了一整夜。 今夜比以往的夜更深。 刘老汉朦胧的双眼看见两个年轻人,他们相互搀扶着进城。 ...
    悟空和孔乙己阅读 150评论 0 0
  • 那年,那些年…… 文:冰凌 那年,枝头上的三朵杏花开的正艳 你说,一朵是你,一朵是我,一朵是他 一个叫相知节的故事...
    凌儿的天空阅读 229评论 0 0