背景:目前国内有大量的公司都在使用 Elasticsearch,包括阿里、京东、滴滴、今日头条、小米、vivo等诸多知名公司。除了搜索功能之外,Elasticsearch还结合Kibana、Logstash、Elastic Stack还被广泛运用在大数据近实时分析领域,包括日志分析、指标监控等多个领域。目录
1、Elasticsearch整体架构图
1.1 源码地址
1.2 架构分层
2、各层级模块解释
2.1 应用层
2.1.1 RestFul API
2.1.2 Java API
2.2 协议层
2.2.1 Thrift
2.2.2 Memcached
2.2.3 Http
2.2.4 TCP
2.2.5 JMX
2.3 发现/脚本层
2.3.1 Discovery
2.3.2 Scripting
2.4 数据处理层
2.4.1 Index Module
2.4.2 Search Module
2.4.3 Mapping
2.4.4 River
2.5 核心架构层
2.5.1 Lucene
2.6 数据存储层
2.6.1 Gateway
1、Elasticsearch整体架构图 首先,建议大家在了解架构之前,下载源码看一看工程结构,能更好的有助于理解整体架构图。
1.1 源码地址 github: https://github.com/elastic/elasticsearch
gitee: https://gitee.com/mirrors/elasticsearch
1.2 架构分层 我们先从应用层、协议层、发现/脚本层、数据处理层、核心架构层以及数据存储层这6层来梳理ES整体架构。分层如下:
文章图片
如果有一些朋友对其中涉及的名词不清楚,可以先看这篇文章:Elasticsearch的相关名称解释 。
2、各层级模块解释 2.1 应用层 2.1.1 RestFul API
在ElasticSearch中,提供了功能丰富的RestFul API操作,包括CURD操作和创建索引,删除索引等。样例格式如下:
查看集群信息:http://127.0.0.1:9200/2.1.2 Java API
查看全部索引:http://127.0.0.1:9200/_all
查看索引信息:http://127.0.0.1:9200/test_search_after/_mapping
查看索引数据:http://127.0.0.1:9200/test_index/_search
1) TransportClient (7.x 废弃、8.0移除, 难以向下兼容版本)2.2 协议层 2.2.1 Thrift
Settings settings = Settings.builder().put("cluster.name", "test").build(); TransportClient transportClient = new PreBuiltTransportClient(settings) .addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300)) .addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9301));
2) RestHighLevelClient(7.x以后常用)
RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http"),new HttpHost("localhost", 9201, "http")));
Thrift是一种接口描述语言和二进制通讯协议,可以用来进行扩展且跨语言的服务的开发。它也是一个RPC框架来,是由Facebook为大规模跨语言服务开发而开发的。日常开发中,通常主要是针对Client和Server的thrift文件编写,如果有使用protobuf的经验会更容易上手。目前在市面上使用比较少,作为了解内容即可。2.2.2 Memcached
Memcached是基于key-value,具有高性能、分布式的内存对象存储的缓存系统,它通过减轻数据库负载加速动态C端应用快速查询;目前使用的比较少,基本被Redis所替代。2.2.3 Http
Elasticsearch对外提供的API是以HTTP协议的方式,通过JSON格式以REST约定对外提供。它为我们提供了RestFul API和Java API RestHighLevelClient来提供开发使用。2.2.4 TCP
ElasticSearch由Transport负责通信,而Transport是基于TCP通信采用Netty实现。基于Netty的通信编码中需要为客户端创建Bootstrap、服务端创建ServerBootstrap。
说明:Netty是一个基于NIO的客户、服务器端的编程框架,它吸收了多种协议(FTP、SMTP、HTTP等)的优秀经验,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
// Netty4Transport.jaav
@Override
protected void doStart() {
boolean success = false;
try {
sharedGroup = sharedGroupFactory.getTransportGroup();
clientBootstrap = createClientBootstrap(sharedGroup);
//Bootstrap
if (NetworkService.NETWORK_SERVER.get(settings)) {
for (ProfileSettings profileSettings : profileSettingsSet) {
createServerBootstrap(profileSettings, sharedGroup);
bindServer(profileSettings);
//ServerBootstrap
}
}
success = true;
} finally {
if (success == false) {
doStop();
}
}
}
2.2.5 JMX
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的代理和服务框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。(日常ES中使用比较少,作为了解部分即可)2.3 发现/脚本层 2.3.1 Discovery
ZenDiscovery属于ES的特殊发现机制,也是ES的内置发现机制,它提供了两种发现方式:单播和多播。主要作用是发现集群中的节点以及选举Master节点。
多播: 指一个节点可以向多台机器发送请求。生产环境中ES不建议使用这种方式,对于一个大规模的集群,组播会产生大量不必要的通信。2.3.2 Scripting
单播: 当一个节点加入一个现有集群,或者组建一个新的集群时,请求发送到一台机器。当一个节点联系到单播列表中的成员时,它就会得到整个集群所有节点的状态,然后它会联系Master节点并加入集群。单播也是ES 默认配置方式。
Elasticsearch中最强大、有用的功能可能是其 Scripting 功能,通过辅助解决一些辅助业务问题。但由于存在性能 和 使用场景少的问题,目前实际生产中使用比较少。官方文档性能优化中明确指出使用脚本会导致性能低;非复杂业务场景下,基础的增、删、改、查基本上就能搞定。脚本示例:2.4 数据处理层 2.4.1 Index Module
"script": { "lang":"...", "source" | "id": "...", "params": { ... } }lang:代表language脚本语言,默认指定为:painless。 source:脚本的核心部分,id应用于:stored script。 params:传递给脚本使用的变量参数。
索引模块是按索引创建的模块,控制index相关的所有方面。
比如常见的Settings操作: Settings settings = Settings.builder().put("cluster.name", "test").build();2.4.2 Search Module
查询模块主要用于搜索并返回查询结果。常见的查询语句如下:
GET /_search//搜索所有的索引中所有的类型2.4.3 Mapping
GET /alibaba/_search//在alibaba索引中搜索所有的类型
GET /alibaba,kxtx/_search//在alibaba和kxtx索引中中搜索所有的文档
GET /m*,k*/_search//在任何以m或者k开头的索引中搜索所有的类型
GET /alibaba/employee/_search//在alibaba索引中搜索employee类型
GET /gb,us/user,tweet/_search//在gb和us索引中搜索user和tweet类型
GET /_all/user,tweet/_search//在所有的索引中搜索user和tweet 类型
【elasticsearch|第3篇: Elasticsearch架构及模块功能介绍】这部分可以参考前面的文章,Elasticsearch的相关名称解释2.4.4 River
Elastisearch中提供了River模块来从其他数据源中获取数据,该项功能以插件的形式存在,目前已有的River插件包括:RabbitMQ、ActiveMQ、CSV、FileSystem、JDBC、GitHub、Kafka等,已经覆盖了大部分的数据源,特别是针对关系型数据库提供了统一的jdbc-river来进行数据操作。2.5 核心架构层 2.5.1 Lucene
Lucene是最先进、功能最强大的搜索库,直接基于lucene开发非常复杂,API复杂(实现一些简单的功能,写大量的java代码),需要深入了解原理。2.6 数据存储层 2.6.1 Gateway
而Elasticsearch也是基于Lucene,隐藏了Lucene复杂性,提供了简单易用的Restful API接口、Java api接口等,易于用户操作。基本可以做开箱即用,租赁很多默认参数优化,不需要任何额外设置。
Gateway 是 Elasticsearch 索引的持久化存储方式,ES 默认是先把索引存放到内存中,当内存满了之后,再持久化到硬盘里。当这个 Elasticsearch 集群关闭或者再次重新启动时就会从 Gateway 中读取索引数据。 Gateway支持多种类型:本地文件系统(默认)、分布式文件系统Hadoop 以及 AMZ 的S3云存储服务。
推荐阅读
- YARN调度架构中的AppMaster
- Elasticsearch的Mapping配置
- 编程语言|一年暴增1600万程序员!GitHub 2021年度报告发布(中国755万开发者排全球第二)
- 算法|盘点知识图谱在 5 大智能领域的应用
- Java|从架构视角去理解Spring,避免重复造轮子
- ChunJun支持异构数据源DDL转换与自动执行 丨DTMO 02期回顾(内含课程回放+课件)
- java|gitlab入门_作为GitLab贡献者入门
- elasticsearch之mappings parameters
- elasticsearch对已存在的索引增加mapping字段