新聞中心
本篇內(nèi)容介紹了“elasticsearch怎么實(shí)現(xiàn)客戶端負(fù)載均衡”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
成都創(chuàng)新互聯(lián)提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì),品牌網(wǎng)站設(shè)計(jì),廣告投放平臺(tái)等致力于企業(yè)網(wǎng)站建設(shè)與公司網(wǎng)站制作,十年的網(wǎng)站開發(fā)和建站經(jīng)驗(yàn),助力企業(yè)信息化建設(shè),成功案例突破千余家,是您實(shí)現(xiàn)網(wǎng)站建設(shè)的好選擇.
客戶端負(fù)載均衡技術(shù)是,客戶端維護(hù)一組服務(wù)器引用,每次客戶端請(qǐng)求的時(shí)候,會(huì)根據(jù)負(fù)載均衡算法選中一個(gè)節(jié)點(diǎn),發(fā)送請(qǐng)求。常用的負(fù)載算法有Random,Round robin,Hash,StaticWeighted等。ES的客戶端負(fù)載使用了Round robin算法。(另外Hash一致性算法還會(huì)在另一地方遇見的)一個(gè)Count請(qǐng)求的整個(gè)客戶端模塊的調(diào)用流程是

簡(jiǎn)化的調(diào)用流程
client 提供了客戶端的操作接口,比如count()
nodesService的execute()隨機(jī)一個(gè)節(jié)點(diǎn)出來(lái)
Proxy代理通過(guò)transportService發(fā)送請(qǐng)求
一些初始化的事情
我們先看下創(chuàng)建客戶端的代碼,這里配置了幾個(gè)配置項(xiàng)
Settings settings = ImmutableSettings.settingsBuilder()
.put("cluster.name", "myClusterName")
.put("client.transport.sniff", true).build();
client=new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress("localhost",9300));誰(shuí)會(huì)在乎這些配置項(xiàng)呢,就是TransportClientNodesService類。它負(fù)責(zé)著嗅探,維護(hù)集群節(jié)點(diǎn)列表。選舉節(jié)點(diǎn)。它的構(gòu)造方法里做了一些初始化工作
this.nodesSamplerInterval = componentSettings.getAsTime("nodes_sampler_interval", timeValueSeconds(5));
this.pingTimeout = componentSettings.getAsTime("ping_timeout", timeValueSeconds(5)).millis();
this.ignoreClusterName = componentSettings.getAsBoolean("ignore_cluster_name", false);
//.....
if (componentSettings.getAsBoolean("sniff", false)) {
this.nodesSampler = new SniffNodesSampler();
} else {
this.nodesSampler = new SimpleNodeSampler();
}
this.nodesSamplerFuture = threadPool.schedule(nodesSamplerInterval, ThreadPool.Names.GENERIC, new ScheduledNodeSampler());nodes_sampler_interval 嗅探集群節(jié)點(diǎn)的間隔,默認(rèn)5秒
pingTimeout Ping節(jié)點(diǎn)的超時(shí)時(shí)間,默認(rèn)是5秒
ignoreClusterName 忽略集群名稱,集群驗(yàn)證的時(shí)候
sniff 是否開啟集群嗅探
另外TransportClientNodesService維護(hù)著2個(gè)列表,集群節(jié)點(diǎn)列表nodes和監(jiān)聽列表listedNodes。其中監(jiān)聽列表就是通過(guò)TransportClient.addTransportAddress()增加的節(jié)點(diǎn)列表。
嗅探集群節(jié)點(diǎn)
interface NodeSampler {
void sample();
}NodeSampler接口很簡(jiǎn)單,只有一個(gè)sample()方法,它的實(shí)現(xiàn)類有2個(gè)SniffNodesSampler和SimpleNodeSampler,我們?cè)诔跏蓟镆呀?jīng)看到了,如果"sniff"配置項(xiàng)是true的話使用SniffNodesSampler類。它們2個(gè)的實(shí)現(xiàn)邏輯是
SimpleNodeSampler
循環(huán)listedNodes列表里的每一個(gè)節(jié)點(diǎn)
沒有連接就連接到這個(gè)節(jié)點(diǎn)
發(fā)送"cluster/nodes/info"請(qǐng)求獲取節(jié)點(diǎn)的集群名稱,需要的話,做集群名驗(yàn)證。
增加到nodes節(jié)點(diǎn)列表
SniffNodesSampler
創(chuàng)建一個(gè)listedNodes和nodes去重后的列表nodesToPing
循環(huán)nodesToPing里的每一個(gè)節(jié)點(diǎn)
沒有連接就連接到這個(gè)節(jié)點(diǎn),如果是nodes列表的就正常連接,listedNode列表的建立個(gè)輕連接就好了
發(fā)送"cluster/state"請(qǐng)求獲取節(jié)點(diǎn)的狀態(tài),這里會(huì)有集群所有的數(shù)據(jù)節(jié)點(diǎn)dataNodes
再次確認(rèn)下已經(jīng)和所有節(jié)點(diǎn)建立連接
增加到nodes節(jié)點(diǎn)列表
我們可以發(fā)現(xiàn)SimpleNodeSampler最終的節(jié)點(diǎn)列表還是listedNodes,如果我們建立客戶端的時(shí)候,只添加了一個(gè)localhost,那它所有的請(qǐng)求都會(huì)發(fā)送到localhost。只有SniffNodesSampler才去探測(cè)集群的所有節(jié)點(diǎn)。也就是SimpleNodeSampler的意圖是讓集群中的某些個(gè)節(jié)點(diǎn),專門用于接受用戶請(qǐng)求。SniffNodesSampler的話,所有節(jié)點(diǎn)都會(huì)參與負(fù)載。
class ScheduledNodeSampler implements Runnable {
@Override
public void run() {
try {
nodesSampler.sample();
if (!closed) {
nodesSamplerFuture = threadPool.schedule(nodesSamplerInterval, ThreadPool.Names.GENERIC, this);
}
} catch (Exception e) {
logger.warn("failed to sample", e);
}
}
}ScheduledNodeSampler線程啟動(dòng)后,Sampler就開始忙碌起來(lái)了。
選舉節(jié)點(diǎn)
有了集群節(jié)點(diǎn)列表后execute()方法就可以通過(guò)輪詢調(diào)度算法Round robin,選舉節(jié)點(diǎn)了。算法的特點(diǎn)是實(shí)現(xiàn)起來(lái)簡(jiǎn)單優(yōu)雅,請(qǐng)求會(huì)被均衡的發(fā)送到各個(gè)節(jié)點(diǎn)上。
publicT execute(NodeCallback callback) throws ElasticSearchException { ImmutableList nodes = this.nodes; if (nodes.isEmpty()) { throw new NoNodeAvailableException(); } int index = randomNodeGenerator.incrementAndGet(); if (index < 0) { index = 0; randomNodeGenerator.set(0); } for (int i = 0; i < nodes.size(); i++) { DiscoveryNode node = nodes.get((index + i) % nodes.size()); try { return callback.doWithNode(node); } catch (ElasticSearchException e) { if (!(e.unwrapCause() instanceof ConnectTransportException)) { throw e; } } } throw new NoNodeAvailableException(); }
關(guān)鍵是這一行代碼,說(shuō)那么多話,其實(shí),我只是了為了這么,一行代碼啊 ?
DiscoveryNode node = nodes.get((index + i) % nodes.size());
“elasticsearch怎么實(shí)現(xiàn)客戶端負(fù)載均衡”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
網(wǎng)站標(biāo)題:elasticsearch怎么實(shí)現(xiàn)客戶端負(fù)載均衡
分享地址:http://www.dlmjj.cn/article/gsocpc.html


咨詢
建站咨詢
