最新版本官方文档https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
文档增删改参考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs.htmlhtml
Index,索引:一系列具备相似属性的文档集合,相似于数据库里的表,集群中能够包含的索引数不限,索引是逻辑概念(对应物理上为分片,shard),通常应提早手工建立而非自动建立便于管理,索引的名称和存储名称不相同可是有着对应关系,可经过查询索引信息的uuid获得。一个典型的索引定义以下:java
{ "logstash-2018-06": { "aliases": {}, "mappings": { "_default_": { "dynamic_templates": [ { "message_field": { "path_match": "message", "match_mapping_type": "string", "mapping": { "norms": false, "type": "text" } } }, { "string_fields": { "match": "*", "match_mapping_type": "string", "mapping": { "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } }, "norms": false, "type": "text" } } } ], "properties": { "@timestamp": { "type": "date" }, "@version": { "type": "keyword" }, "geoip": { "dynamic": "true", "properties": { "ip": { "type": "ip" }, "latitude": { "type": "half_float" }, "location": { "type": "geo_point" }, "longitude": { "type": "half_float" } } } } }, "doc": { "dynamic_templates": [ { "message_field": { "path_match": "message", "match_mapping_type": "string", "mapping": { "norms": false, "type": "text" } } }, { "string_fields": { "match": "*", "match_mapping_type": "string", "mapping": { "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } }, "norms": false, "type": "text" } } } ], "properties": { "@timestamp": { "type": "date" }, "@version": { "type": "keyword" }, "beat": { "properties": { "hostname": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "version": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "geoip": { "dynamic": "true", "properties": { "ip": { "type": "ip" }, "latitude": { "type": "half_float" }, "location": { "type": "geo_point" }, "longitude": { "type": "half_float" } } }, "host": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "message": { "type": "text", "norms": false }, "offset": { "type": "long" }, "prospector": { "properties": { "type": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "source": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "tags": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } }, "settings": { "index": { "refresh_interval": "5s", "number_of_shards": "5", "provided_name": "logstash-2018-06", "creation_date": "1527913627481", "number_of_replicas": "1", "uuid": "0VidmJtrT1uoz-TygNCn_Q", "version": { "created": "6020499" } } } } }
Type,类型:在6.0.0以前的版本中,类型用于在索引中进行二次分类/分区以便在相同索引中存储不一样类型的文档,好比同时存储blog和user,这个版本开始,不能再在一个索引中建立多个类型,类型是逻辑概念。
Document,文档:文档表明能够被索引的基本单元,相似数据库里的表,文档在ES中表示为JSON,在索引/类型中,能够存储无限的文档。从物理上来讲,文档存储在索引中,从逻辑上,文档实际上归属于索引中的某个类型。一个典型的文档以下:node
{ "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
其实就是一个json。文档由 _index 、 _type 和 _id 惟一标识一个文档。mysql
Near Realtime (NRT),准实时:Elasticsearch是准实时搜索平台(官方称秒级)。
Cluster,集群:全部Elasticsearch节点都运行在集群中,即便只有一个节点,集群中能够包含的节点数不限,节点是物理概念,集群是逻辑概念。
Node,节点:简单地说,ES中的全部节点都是用来存储数据的。具体地说,从功能上来看,Elasticsearch有5种类型的节点:
Data节点,虽然每一个节点均可以做为数据节点,可是经过在elasticsearch.yml配置文件中进行以下设置,能够限定某些节点只能做为数据节点,设置专用数据节点可使得数据节点和Master节点隔离。git
node.data: true
node.master: false
node.ingest: falsegithub
Master节点,负责管理整个集群,其持有全部节点的状态并周期性的将集群状态分发给其余全部节点,包括新加入的节点以及退出的节点。master节点的主要职责是配置管理,其包含完整的元数据以及全部索引的映射,当更新密集时,状态信息可能会很是大,每秒1w条数据时,状态信息可能有几十M。2.0版本以后,更新的集群状态信息只发diff,而且是被压缩的。若是master节点挂了,新的主节点会从剩余有资格的主节点中产生,默认状况下,每一个节点均可以成为主节点。经过在elasticsearch.yml配置文件中进行以下设置,能够限定某些节点只能做为主节点。sql
node.data: false
node.master: true
node.ingest: false数据库
Ingest节点,能够在实际索引前执行预处理数据。经过在elasticsearch.yml配置文件中进行以下设置,能够限定某些节点只能做为Ingest节点。json
node.data: falseapi
node.master: false
node.ingest: true
Tribe节点,是一种特殊的协调节点,或者成为联邦节点,用于代理执行跨集群的操做。
Coordinating/Client节点,在ES中,每一个请求的执行分为两个步骤:分发和聚合。这两个均由接收请求的协调节点管理,同时他们也是ES集群的负载均衡器。经过在elasticsearch.yml配置文件中进行以下设置,能够限定某些节点只能做为协调节点,对于较大型的生产系统,应该配置专门的协调节点,由于聚合节点比较消耗资源。
node.data: false
node.master: false
node.ingest: false
Routing,路由:路由容许咱们在索引和搜索数据时选择具体的分片。
Lucene:提供了基于java的索引和搜索技术,Solr相似于ES,也是基于Lucene Core,提供了管理接口。
Shards & Replicas,分片与副本:一个索引包含的文档在存储的时候不必定是一块儿的,存储文档的每一个物理单元称为分片(Elasticsearch 没有采用节点级别的主从复制,而是基于分片,跟couchbase同样)(相似于数据库的分区以及段Partition/Segment)。分片的做用无非两个:
为了保证高可用,每一个分片能够设置副本数量。在索引建立的时候,能够指定分片和副本的数量,副本数能够按需调整可是分片数量一经定义、没法修改。默认状况下,Elasticsearch为每一个索引分配5个分片和1个副本(5个主分片,5个副本分片),这意味着双节点模式。
文档根据公式shard = hash(routing) % number_of_primary_shards计算存储的具体分片,默认是根据文档的id计算,可自定义。
每一个Elasticsearch分片是一个Lucene索引/实例(须要注意,Lucene的概念和ES不彻底一一对应),一个Lucene索引中文档的数量限制为Integer.MAX_VALUE - 128,这一点须要注意不要超出,分片中文档的数量能够经过API _cat/shards监控。
索引和分片的关系以下:
索引和分片在存储的组织上能够看得出关系(经过api也能够看出):
Analysis,分析:ES是一个全文搜索引擎,为了高性能,它会提早或者按需将文本转换为一系列的符号,ES在索引时执行分析。对于全文检索,ES还会对查询字符串执行搜索时分析。
Mapping(6.0.0开始准备移除,见Type),映射:映射定义了文档及其包含的字段如何打分和索引的过程,包括:哪一个字段应该用于全文检索,哪些字段包含日期、数字以及地理信息等。
Mapping Type(6.0.0开始准备移除,见Type,移除的缘由是由于ES早期的假设不正确,一开始是假设Index是database,type是表,而数据库里面,不一样表中的列是无关的,而Lucene的内部实现则认为是一个字段,因此就懵逼了),映射类型:每一个索引都有一个映射类型,定义文档如何索引。一个映射类型包含了下列信息:
除了在建立索引的时候声明映射类型外,ES还支持动态映射,也就是建立文档的时候自动建立索引、映射类型以及字段(注:生产中应避免使用动态映射特性以最大化性能和存储利用率)。
Mapping parameter,映射参数:对于每种数据类型,咱们能够为此声明必定的映射参数,有些参数能够应用于全部数据类型,有些则适用于部分数据类型。好比用于文本分析的分析器就是一个映射参数,完整的映射参数能够参考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/mapping-params.html。
===================================
Elasticsearch基于Java编写,最新版本6.2.x要求Java 8。
ES提供REST API给用户用于平常管理,端口是9100,不过通常状况下,咱们都会安装插件Elasticsearch Head,具体安装能够参考https://www.cnblogs.com/zhjh256/p/9126144.html。虽然Head不错,可是有时候现成的环境并无安装Head,又须要及时排查问题,此时就须要对常见的api熟悉,能够参考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/_exploring_your_cluster.html。
全部的Elasticsearch REST APIs都是JSON格式做为出入参,这意味着必备Postman,友好强大。一些通用的参数能够参考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/api-conventions.html
Elastic出品的全部产品几乎都包含三个配置文件:XXX.yml,jvm.options,log4j2.properties。Elasticsearch也遵照相同的惯例。
elasticsearch.yml中最重要的包括:
jvm.options最主要的是-Xms和-Xmx以及gc、oom、线程池(对于全部的java应用来讲,这几方面都是必须事先预防的)。
elasticsearch.yml的全部配置参数能够没有一个统一的地方定义全部,整体在https://www.elastic.co/guide/en/elasticsearch/reference/2.3/setup-configuration.html,索引相关的在https://www.elastic.co/guide/en/elasticsearch/reference/2.3/index-modules.html,分析器相关的在https://www.elastic.co/guide/en/elasticsearch/reference/2.3/analysis.html。注:最新版本的没有去掉了analyse配置的文档,故列出了2.x版本的参考。
JDK 8u40以前的版本G1GC有bug,会致使索引损坏。
分析是将文本转化为符号的过程,在文档被索引的时候,内置的english分析器会执行分析。任何一个mapping中的text字段均可以声明本身的分析器,好比:
"mappings": { "_doc": { "properties": { "text": { "type": "text", "fields": { "english": { "type": "text", "analyzer": "english" } } } } } }
默认状况下,ES会使用索引建立时设置的default分析器,若是该分析器无效或者不存在的话,使用标准分析器(https://www.elastic.co/guide/en/elasticsearch/reference/6.2/analysis-standard-analyzer.html)。ES提供了一些内置的分析器,见https://www.elastic.co/guide/en/elasticsearch/reference/6.2/analysis-analyzers.html。对于中文而言,这并不合适,所以社区开发了elasticsearch-analysis-ik(中文词语)和https://github.com/medcl/elasticsearch-analysis-pinyin(用于汉字转拼音)。
自定义分析器的建立以及规范参考https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-custom-analyzer.html。
自定义分析器的安装须要在elasticsearch.yml中进行配置,具体可参考https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html。
默认状况下,当有个文档须要索引时,ES会计算文档ID的哈希值,基于该哈希值选择存储的分片,而后这些文档被复制到副本分片。可是查询的时候,因为查询条件并不是都是ID等值查询,因此不知道哪一个分片中实际存储了匹配的文档,所以须要查询全部的分片,处理客户端请求的节点成为协调节点。以下:
经过API能够看到每一个索引的路由信息,以下:
不少时候,在全文搜索的时候,咱们会限制仅在某个用户下,好比仅搜索www.cnblogs.com/zhjh256下的文档,此时路由选择就发挥做用了。提供路由值最简单的方式就是在HTTP请求中增长routing参数。即便是最高效的哈希查找,若是能够确保每次搜索时限定具体分片,理论上默认状况下吞吐量就能够提高5倍。
ES REST API提供了一批接口用于管理索引、索引的配置、别名、映射以及索引模板,索引内部信息的监控等。从纯粹使用的角度来讲,索引API使用较少,因此它更多地属于管理类API。完整的索引API能够参考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/indices.html。建立一个索引,如:
PUT test { "settings" : { "number_of_shards" : 1 }, "mappings" : { "type1" : { "properties" : { "field1" : { "type" : "text" } } } } }
建立索引的时候映射类型不是必须的。若是没有定义映射类型,建立文档的时候会自动根据api中的类型名进行建立。
有些时候,咱们发现有些文本中有的内容,咱们查询的时候并不匹配,此时能够针对具体的文本执行手工分析过程,看下ES是如何解析的,这个时候可使用_analyze API(postman怎么发送参数格式为JSON的get?),如:
GET _analyze { "tokenizer" : "keyword", "filter" : ["lowercase"], "text" : "this is a test" }
索引模板顾名思义,就是为索引定义默认设置,在建立索引的时候自动套上去,由于索引自己的建立是很少的,因此无关紧要。
对于程序来讲,JSON很适合自动化处理,可是对人类而言,其友好性就差了不少。因此,对于管理型的查询API,ES提供了平面化的接口。例如,查看集群中节点的状态:
GET /_cat/nodes?v
返回以下:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 192.168.1.104 56 94 1 0.23 0.33 0.24 mdi * node-1
更多cat APIs,可参考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/cat.html。
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs-replication.html
文档接口分为单文档接口和多文档接口。
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs.html
index api,插入或者更新一个JSON文档,并使其可搜索。例如,在twitter索引的_doc类型下建立一个id为1的文档。
PUT twitter/_doc/1 { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
若是_doc类型不存在,会自动建立。若是已经存在了一个叫作_type的类型,则会建立失败,提示不容许包含多个类型。
ES提供了两种查询接口:搜索APIs和Query DSL。准确的说,前者能作的事情,后者都能作,前者和文档APIs等一块儿适合于比较简单的CRUD。
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search.html
http://www.querydsl.com/
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/query-dsl.html
Elasticsearch与Solr的适用场景比较可参考:https://www.cnblogs.com/simplelovecs/articles/5129276.html
倒排索引(Lucene中的段)被写入磁盘后是 不可改变 的:它永远不会修改
es增长新的补充索引来反映新近的修改,而不是直接重写整个倒排索引。每个倒排索引都会被轮流查询到—从最先的开始–查询完后再对结果进行合并
按段(per-segment)搜索的发展
新段会被先写入到文件系统缓存,稍后再被刷新到磁盘,只要文件已经在缓存中, 就能够像其它文件同样被打开和读取了。
每一次对 Elasticsearch 进行操做时均记录事务日志,当 Elasticsearch 启动的时候,而且会重放 translog 中全部在最后一次提交后发生的变动操做。
为节省资源,提升检索效率,Elasticsearch经过在后台进行段合并,小的段被合并到大的段,而后这些大的段再被合并到更大的段。
经过optimize API能够将一个分片强制合并到指定的段数目。 (一般减小到一个)。例如在日志这种用例下,天天、每周、每个月的日志被存储在一个索引中。 老的索引实质上是只读的;它们也并不太可能会发生变化。
按集群节点来均衡分配这些分片,从而对索引和搜索过程进行负载均衡,复制每一个分片以支持数据冗余,从而防止硬件故障致使的数据丢失
当集群只有一个节点,到变成2个节点,3个节点时的 shard 变换图以下:
除了官方文档外,还有一些资料对于学习ES是有帮助的,这里列举以下:
Anatomy of an Elasticsearch Cluster: Part I