本文主要介绍ElasticSearch的基本概念,文档、索引、集群、节点、分片等学习概念。同时将ElasticSearch和关系型数据库做一个简单的类比。简单介绍一下RESTAPI的用法。ElasticSearch术语index和document偏向于逻辑概念,而nodes和shards则更偏向于物理概念。首先说一下什么是文档:文档(Document)ElasticSearch(简称ES)是面向文档的,文档是所有可搜索数据的最小单位。举几个例子,让大家更清楚什么是文件:日志文件中的日志项,电影的详细信息,专辑的详细信息,MP3播放器中的歌曲,文件中的文件。一个PDF文档。具体内容是一条客户数据,一条产品分类数据,一条订单数据。您可以将文档理解为关系数据库中的一条记录。在ES中,文档会被序列化成JSON格式保存在ES中。JSON对象由字段组成,每个字段都有对应的字段类型(字符串/数组/布尔/日期/二进制/范围类型)。在ES中,每个文档都有一个UniqueID,可以是自己指定的,也可以是ES自动生成的。在上一篇文章中,我教大家如何搭建一个ELK实时日志分析平台。我们讲了通过Logstash将数据导入ES。部分测试数据集及对应的转换格式如下:movieId,title,genres193585,Flint(2017),Drama193587,BungoStrayDogs:DeadApple(2018),Action|Animation193609,AndrewDiceClay:DiceRules(1991),Comedy我们从测试数据集csv文件中一个一个读取RowData电影数据,然后通过Logstash转换后,以JSON格式进入ES。JSON中的每个字段都有自己的数据类型,ES可以帮你自动计算出一个数据类型,ES中的数据也支持数组和嵌套。每个文档都有对应的元数据,用于标记文档的相关信息。让我们了解元数据包含的内容:{"_index":"movies","_type":"_doc","_id":"2035","_score":1.0,"_source":{"title":"Blackbeard'sGhost","genre":["Children","Comedy"],"id":"2035","@version":"1","year":1968}}其中_index代表索引名称文件属于哪个;_type表示文档所属的类型名称;_id是文档的唯一标识;_source为文档原始JSON数据,搜索文档时默认返回_source字段;@version是文档的版本信息,可以解决版本冲突的问题;_score是相关分数,也就是这个文档在这个query中的分数。介绍完文档,再来看索引:索引(Index)索引简单来说就是结构相似的文档的集合。比如可以有客户索引、商品分类索引、订单索引,一个索引有一个名字,一个索引可以包含很多文档,一个索引代表一类相似或相同的文档。例如,如果创建一个产品索引,则可以在其中存储所有的产品数据,即所有的产品文档。每个索引都是自己的Mapping定义文件,用来描述要包含的文档字段类型。分片体现了物理空间的概念,索引中的数据分散在分片上。在一个索引中,你可以为它设置Mapping和Setting。映射定义了索引中所有文档字段的类型结构。Setting主要指定使用多少个分片以及数据如何分布。索引在不同的上下文中具有不同的含义。比如在ES中,索引就是一类文档的集合,这里是名词;同时,将文档保存到ES的过程也称为索引。除了ES,mentionIndexes还可能是B-treeindexes或invertedindexes。倒排索引是ES中一个重要的数据结构,在以后的文章中会进行讲解。接下来对类型进行说明:7.0之前的类型(Type),每个索引可以设置多个Type,每个Type都会有相同的文档结构,但是从6.0开始,Type已经废除了,从7.0开始,一个索引可以只创建一个Type,即_doc。每个索引可以有一个或多个类型。类型是索引中的逻辑数据分类。一个Type下的文档都有相同的字段(Field)。例如,博客系统有一个索引,可以定义用户数据类型、博客数据类型、评论数据类型等。至此,我们已经了解了文档、索引和类型的概念。接下来,我们将学习什么是集群?什么是节点?什么是分片?我们先来看一下集群的概念。集群(Cluster)ES集群实际上是一个分布式系统。满足高可用,高可用是指当集群中某个节点服务停止响应时,整个服务仍然可以正常工作,即服务可用性;在部分节点丢失的情况下,不会有数据丢失,即数据可用性。当用户请求量增加,数据越来越多时,系统需要将数据分发到其他节点,实现横向扩展。当集群中某个节点出现问题时,不会影响整个集群的服务。在ES的分布式架构中,不同的集群以不同的名字来区分。默认名称是elasticsearch,可以在配置文件中修改,或者在命令行使用-Ecluster.name=wupx设置,一个集群中可以有一个或多个节点。ES集群有三种颜色表示健康度:绿色:主分片和副本正常分配黄色:主分片全部正常分配,部分副本分片未正常分配红色:部分主分片未分配(对于例如,当服务器的磁盘容量超过85%时,会创建一个新的索引)了解了集群之后,我们再来看看什么是节点。节点(Node)节点其实就是一个ES实例,本质上是一个Java进程。一台机器上可以运行多个ES进程,但是在生产环境中,一般建议一台机器上只运行一个ES实例。每个节点都有自己的名字,节点名很重要(在进行运维管理操作时),可以通过配置文件配置,也可以在启动时指定-Enode.name=node1。每个节点启动后,都会分配一个UID,保存在data目录下。默认节点将加入一个名为elasticsearch的集群。如果直接启动很多节点,它们会自动组成一个elasticsearch集群。当然一个节点也可以组成一个elasticsearch集群。CandidateMasterNode(Master-eligibleNode)&MasterNode(MasterNode)每个节点启动后,默认是Master-eligible节点,可以通过在配置文件中设置node.master:false来禁用,Master-符合条件的节点可以参与选择主进程并成为主节点。当第一个节点启动时,它会选举自己作为主节点。集群的状态保存在每个节点上。只有Master节点可以修改集群的状态信息。如果任何一个节点都可以修改信息,就会导致数据不一致。集群状态(ClusterState),维护一个集群中必要的信息,主要包括以下信息:所有节点信息,所有索引及其相关的MappingandSetting路由信息分片信息我们来看看什么是DataNode和CoordinatingNode?DataNode&CoordinatingNode顾名思义,可以保存数据的节点称为DataNode,负责保存分片上存储的所有数据。当集群无法保存现有数据时,可以通过添加数据节点来解决存储问题,对数据扩容起到至关重要的作用。CoordinatingNode负责接收Client的请求,将请求分发到合适的节点,最后汇集结果返回给Client。默认情况下,每个节点都扮演协调节点的角色。还有其他的节点类型,大家可以了解一下:其他节点类型Hot&WarmNode:HotNode是高配置的节点,可以有更好的磁盘吞吐量和更好的CPU,冷节点(WarmNode)存储一些更久的-术语节点,这些节点的机器配置会比较低。采用不同硬件配置的数据节点,实现Hot&Warm架构,降低集群部署成本。机器学习节点(MachineLearningNode):负责运行机器学习工作,用于异常检测。TribeNode:连接不同的ES集群,支持将这些集群视为一个集群。预处理节点(IngestNode):预处理操作允许数据在索引文档之前,即写入数据之前,通过一系列预先定义的处理器(processors)和管道(pipelines)进行转换和丰富。改变。当每个节点启动时,它会读取elasticsearch.yml配置文件来决定它扮演什么角色。来看看配置节点类型吧!配置节点类型开发环境中的一个节点可以承担多个角色。在生产环境中,应该设置一个单一的角色节点(dedicatednode)。说完节点,再看看什么是分片?分片(Shard)由于单台机器无法存储大量的数据,ES可以将一个索引中的数据分成多个分片(Shard),分布在多个存储在一台服务器上。通过分片,可以横向扩展,存储更多数据,将搜索、分析等操作分散到多台服务器上,提高吞吐量和性能。index和sharding的关系如上图所示。一个ES索引包含很多分片,一个分片就是一个Lucene索引。它是一个完整的搜索引擎,可以独立执行索引和搜索任务。Lucene索引由很多段组成,每个段是一个倒排索引。ES每次刷新都会生成一个新的segment,里面包含了几个文档的数据。在每个段中,文档的不同字段分别被索引。每个字段的值由若干词(Term)组成,Term是原始文本内容经过tokenizer和语言处理后的最终结果(例如,去除标点符号,转换为词根)。分片有两种,一种是主分片,一种是副本分片。primaryshard主要用来解决横向扩展的问题。通过主分片,数据可以分布到集群中的所有节点。主分片是一个正在运行的Lucene实例。我们在创建ES索引的时候,可以指定分片的个数,但是主分片的个数在创建索引的时候就已经指定了,以后是不允许修改的,除非使用Reindex来修改。副本分片用于解决数据高可用问题。也就是说,当集群中的某个节点发生硬件故障时,副本分片也可以保证数据不会丢失,因为副本分片是主分片。对于复制,索引中副本分片的数量可以动态调整。通过增加副本数,可以在一定程度上提高服务查询的性能(读吞吐量)。下面通过一个例子来理解primaryshards和replicashards是如何将数据分散到集群的不同节点上的:PUT/blogs{"settings":{"number_of_shards":3,"number_of_repicas":1}}以上是对的定义blogs索引,其中settings中的number_of_shards表示主分片数为3,number_of_repicas表示只有一份。上图是一个wupx的集群,一共有3个节点。通过上面索引博客的配置,当数据进来的时候,ES会将主要分片分散在三个节点上,同时,将每个分片的副本分发到其他节点上。当集群中的某个节点发生故障时,ES内部会产生故障转移机制。故障转移机制将在以后的文章中解释。在上图中,可以看到三个主分片分布到三个节点上。如果此时在集群中增加一个节点,是不是可以增加系统的可用性呢?带着这个问题,我们先来看看sharding的设置:shardingsettingsharding设置在生产环境中非常重要。很多时候需要提前做好容量规划,因为primaryshard需要在创建索引的时候预先设置好,之后不能修改。在前面的例子中,一个索引被分成了3个primaryshards,无论这个集群加入多少个节点,索引都只能分散在3个节点上。当分片设置过大时,也会带来副作用。一方面会影响搜索结果的评分和统计结果的准确性。此外,单个节点上的分片过多也会导致资源浪费。也会影响性能。从7.0版本开始,ES默认的primaryshards个数由5个改为1个,也可以解决这方面over-sharding的问题。了解了ES的术语之后,我们再用我们熟悉的关系型数据库做个类比,方便我们的理解。RDBMS&ES相信大家对关系型数据库(简称RDBMS)应该比较了解,所以我们把关系型数据库和ES做个类比,方便大家理解:从表中不难看出那关系数据库和ES有如下对应关系:关系数据库中的表(Table)对应ES中的索引(Index)。关系数据库中的每条记录(Row)对应ES中的文档(Document)。关系数据库中的字段(Column)对应ES中的字段(Filed)。关系数据库中的表定义(Schema)对应ES中的映射(Mapping)。SQL可以用来在关系型数据库中进行查询等操作,ES中也提供了DSL来进行查询等操作。ES比较适合做全文搜索或者对搜索结果进行评分,但是如果对数据的事务性要求比较高,会结合使用关系型数据库和ES。为了方便其他语言的集成,ES提供了RESTAPI来调用其他程序。当我们的程序要与ES集成时,只需要发送一个HTTP请求就可以得到相应的结果。接下来使用基础API介绍:RESTAPI打开Kibana,我们首先打开Kibana的管理菜单(Management),里面提供了索引管理功能,可以看到索引管理里面有一个电影索引,是在导入的上一篇文章,点击index,可以看到indexSetting和Mapping信息,如何设置会在后面的文章中介绍。言归正传,给大家介绍一下RESTAPI:接下来打开Kibana的开发工具(DevTools),以电影作为索引。现在输入GETmovies,点击Execute,可以看到电影索引相关的信息,主要包括索引的Mapping和Setting。输入GETmovies/_count点击Execute,可以看到索引文档的总数。运行结果如下:{"count":9743,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0}}输入如下代码POSTmovies/_search{}点击execute查看前10个文档,了解文档格式。也可以对索引名称进行通配符查询,使用GET/_cat/indices/mov*?v&s=index查看匹配的索引。使用GET/_cat/indices?v&s=docs.count:desc按文档数排序。使用GET/_cat/indices?v&health=green查看状态为绿色的索引。使用GET/_cat/indices?v&h=i,tm&s=tm:desc查看各个索引占用的内存。ES也提供了API来查看集群的健康状态。使用GET_cluster/health获取集群的健康状态。返回结果如下:{"cluster_name":"wupx","status":"green","timed_out":false,"number_of_nodes":2,"number_of_data_nodes":2,"active_primary_shards":10,"active_shards“:10,”relocating_shards“:0,”initializing_shards“:0,”unassigned_shards“:0,”delayed_unassigned_shards“:0,”number_of_pending_tasks“:0,”number_of_in_flight_fetch“:0,”task_max_waiting_in_queue_millis“:0,”active_shards_percent_as_number“:100.0}可以看到集群名称为wupx,集群状态为green,一共有2个节点,均负责DataNode角色,另外还有10个primaryshards。RESTAPI就介绍到这里,剩下的大家可以自行探索。细心的朋友会发现Kibana是如何变成中文界面的。其实在Kibana7.0版本之后,可以找到官方中文资源文件(位于Kibana目录下的node_modules/x-pack/plugins/translations/translations/)修改config目录下的kibana.yml文件,添加配置项i18n.locale:"zh-CN"到文件中,重启Kibana完成本地化。小结本文主要学习文档、索引、集群、节点等概念,了解每个集群中的每个节点可以承担不同的角色,也了解什么是primaryshards和replicashards及其在分布式系统中的作用。也和关系型数据库打个比方,方便大家理解。此外,还介绍了RESTAPI的使用,最后总结了ES术语的思维导图。思维导图的源文件可以在公众号吴佩轩回复es获取。ES术语参考《Elasticsearch技术解析与实战》《Elasticsearch源码解析与优化实战》Elasticsearch核心技术与实战Elasticsearch顶尖高手系列https://www.elastic.co/guide/en/elasticsearch/reference/7.1/index.html
