elasticsearch 代码分析之modules and services

最近需要研究搜索的集群。由于大脑日渐萎缩,只好把代码记下来以供参考,好久没在csdn上写东西了,呵呵。
elasticsearch是一个基于lucene的搜索集群,关于lucene的介绍有如下参考:
Annotated-Lucene源码剖析中文版
Architecture and Implementation of Apache Lucene
Lucene 源码分析
elasticsesarch作为一个封装lucene的开源项目,根据CAP理论在牺牲一致性(C)的,保证了数据的分布(P)和可达(A)。当然数据是有最终一直性的。
参考资料:solar VS elk http://solr-vs-elasticsearch.com/
关于elasticsearch如何保证cap我们以后会深入理解。
本章先告诉大家如何看elasticsearch源代码:
如果你熟悉AOP 或者spring framework, 就会发现elasticsearch源代码是按照模块组织的。只不过用了另外一个开源框架Guice。guice如何实现依赖注入的参考:
http://malsup.com/jquery/media/guice.pdf
扯了很多终于可以讲主题了:
elasticsearch的官网:https://www.elastic.co/blog/found-elasticsearch-internals列出了所有elasticsearch 的模块。今天就已discovery module为例看看elasticsearch是如何注册并使用这一service的。
node.class代表elasticsearch的一个节点,他包含了启动一个节点的所有服务:`

Node(Settings preparedSettings, Version version, Collection> classpathPlugins) { final Settings pSettings = settingsBuilder().put(preparedSettings) .put(Client.CLIENT_TYPE_SETTING, CLIENT_TYPE).build(); Environment tmpEnv = InternalSettingsPreparer.prepareEnvironment(pSettings, null); Settings tmpSettings = TribeService.processSettings(tmpEnv.settings()); ESLogger logger = Loggers.getLogger(Node.class, tmpSettings.get("name")); logger.info("version[{}], pid[{}], build[{}/{}]", version, JvmInfo.jvmInfo().pid(), Build.CURRENT.hashShort(), Build.CURRENT.timestamp()); logger.info("initializing ..."); if (logger.isDebugEnabled()) { logger.debug("using config [{}], data [{}], logs [{}], plugins [{}]", tmpEnv.configFile(), Arrays.toString(tmpEnv.dataFiles()), tmpEnv.logsFile(), tmpEnv.pluginsFile()); }this.pluginsService = new PluginsService(tmpSettings, tmpEnv.pluginsFile(), classpathPlugins); this.settings = pluginsService.updatedSettings(); // create the environment based on the finalized (processed) view of the settings this.environment = new Environment(this.settings()); final NodeEnvironment nodeEnvironment; try { nodeEnvironment = new NodeEnvironment(this.settings, this.environment); } catch (IOException ex) { throw new IllegalStateException("Failed to created node environment", ex); }final ThreadPool threadPool = new ThreadPool(settings); boolean success = false; try { ModulesBuilder modules = new ModulesBuilder(); modules.add(new Version.Module(version)); modules.add(new CircuitBreakerModule(settings)); // plugin modules must be added here, before others or we can get crazy injection errors... for (Module pluginModule : pluginsService.nodeModules()) { modules.add(pluginModule); } modules.add(new PluginsModule(pluginsService)); modules.add(new SettingsModule(this.settings)); modules.add(new NodeModule(this)); modules.add(new NetworkModule()); modules.add(new ScriptModule(this.settings)); modules.add(new EnvironmentModule(environment)); modules.add(new NodeEnvironmentModule(nodeEnvironment)); modules.add(new ClusterNameModule(this.settings)); modules.add(new ThreadPoolModule(threadPool)); modules.add(new DiscoveryModule(this.settings)); modules.add(new ClusterModule(this.settings)); modules.add(new RestModule(this.settings)); modules.add(new TransportModule(settings)); if (settings.getAsBoolean(HTTP_ENABLED, true)) { modules.add(new HttpServerModule(settings)); } modules.add(new IndicesModule(settings)); modules.add(new SearchModule(settings)); modules.add(new ActionModule(false)); modules.add(new MonitorModule(settings)); modules.add(new GatewayModule(settings)); modules.add(new NodeClientModule()); modules.add(new ShapeModule()); modules.add(new PercolatorModule()); modules.add(new ResourceWatcherModule()); modules.add(new RepositoriesModule()); modules.add(new TribeModule()); pluginsService.processModules(modules); injector = modules.createInjector(); client = injector.getInstance(Client.class); threadPool.setNodeSettingsService(injector.getInstance(NodeSettingsService.class)); success = true; } finally { if (!success) { nodeEnvironment.close(); ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS); } }logger.info("initialized"); }

通过它的构造函数可以清楚的看到elasticsearch加载了那些模块
modules.add(new DiscoveryModule(this.settings));

说明elasticsearch加载了DiscoveryModule。
elasticsearch 代码分析之modules and services
文章图片

每个discovery module 包含了不同的多个Discovery模块,每个discovery模块都是先了自己的publishi方法,通过广播的形式将master node接受到的node change event时间告诉其他的监听器。
其中最重要的就是 ZenDiscovery,它负责在局域网内通过多播(multi-broadcast)或者单播的形式发现其他节点并将之纳入cluster中。
【elasticsearch 代码分析之modules and services】第一次写关于开源项目研究的笔记,不尽之处希望大家多多指正。
有想一起研讨的也多多给我留言。

    推荐阅读