Elasticsearch是什么

介绍ElasticSearch

Elasticsearch 是一个实时的分布式搜索分析引擎,它能让你以前所未有的速度和规模,去探索你的数据。 它被用作全文检索、结构化搜索、分析以及这三个功能的组合:

  • Wikipedia 使用 Elasticsearch 提供带有高亮片段的全文搜索,还有 search-as-you-type 和 did-you-mean 的建议。
  • 卫报 使用 Elasticsearch 将网络社交数据结合到访客日志中,为它的编辑们提供公众对于新文章的实时反馈。
  • Stack Overflow 将地理位置查询融入全文检索中去,并且使用 more-like-this 接口去查找相关的问题和回答。
  • GitHub 使用 Elasticsearch 对1300亿行代码进行查询。

Elasticsearch 不仅仅为巨头公司服务。它也帮助了很多初创公司,比如 Datadog 和 Klout, Elasticsearch 帮助他们将想法用原型实现,并转化为可扩展的解决方案。Elasticsearch 能运行在你的笔记本电脑上,或者扩展到数百台服务器上来处理PB级数据。 Elasticsearch 中没有一个单独的组件是全新的或者是革命性的。全文搜索很久之前就已经可以做到了, 就像很早之前出现的分析系统和分布式数据库。 革命性的成果在于将这些单独的,有用的组件融合到一个单一的、一致的、实时的应用中。对于初学者而言它的门槛相对较低, 而当你的技能提升或需求增加时,它也始终能满足你的需求。 如果你现在打开这本书,是因为你拥有数据。除非你准备使用它 做些什么 ,否则拥有这些数据将没有意义。 不幸的是,大部分数据库在从你的数据中提取可用知识时出乎意料的低效。 当然,你可以通过时间戳或精确值进行过滤,但是它们能够全文检索、处理同义词、通过相关性给文档评分么? 它们能从同样的数据中生成分析与聚合数据吗?最重要的是,它们能实时地做到上述操作,而不经过大型批处理的任务么? 这就是 Elasticsearch 脱颖而出的地方:Elasticsearch 鼓励你去探索与利用数据,而不是因为查询数据太困难,就让它们烂在数据仓库里面。 Elasticsearch 将成为你最好的朋友。 Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上。 Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库—​无论是开源还是私有。 但是 Lucene 仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理。Lucene 非常 复杂。 Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。 然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:

  • 一个分布式的实时文档存储,每个字段 可以被索引与搜索
  • 一个分布式实时分析搜索引擎
  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据

Elasticsearch 将所有的功能打包成一个单独的服务,这样你可以通过程序与它提供的简单的 RESTful API 进行通信, 可以使用自己喜欢的编程语言充当 web 客户端,甚至可以使用命令行(去充当这个客户端)。 就 Elasticsearch 而言,起步很简单。对于初学者来说,它预设了一些适当的默认值,并隐藏了复杂的搜索理论知识。 它 开箱即用 。只需最少的理解,你很快就能具有生产力。 随着你知识的积累,你可以利用 Elasticsearch 更多的高级特性,它的整个引擎是可配置并且灵活的。 从众多高级特性中,挑选恰当去修饰的 Elasticsearch,使它能解决你本地遇到的问题。 你可以免费下载,使用,修改 Elasticsearch。它在 Apache 2 license 协议下发布的, 这是众多灵活的开源协议之一。Elasticsearch 的源码被托管在 Github 上 github.com/elastic/elasticsearch

和ElasticSearch交互

和 Elasticsearch 的交互方式取决于你是否使用 Java

Java API

如果你正在使用 Java,在代码中你可以使用 Elasticsearch 内置的两个客户端:

节点客户端(Node client)

节点客户端作为一个非数据节点加入到本地集群中。换句话说,它本身不保存任何数据,但是它知道数据在集群中的哪个节点中,并且可以把请求转发到正确的节点。

传输客户端(Transport client)

轻量级的传输客户端可以将请求发送到远程集群。它本身不加入集群,但是它可以将请求转发到集群中的一个节点上。 两个 Java 客户端都是通过 9300 端口并使用 Elasticsearch 的原生 传输 协议和集群交互。集群中的节点通过端口 9300 彼此通信。如果这个端口没有打开,节点将无法形成一个集群。

Java 客户端作为节点必须和 Elasticsearch 有相同的 主要 版本;否则,它们之间将无法互相理解。

RESTful API with JSON over HTTP

所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。 Elasticsearch 为以下语言提供了官方客户端–Groovy、JavaScript、.NET、 PHP、 Perl、 Python 和 Ruby—​还有很多社区提供的客户端和插件,所有这些都可以在 Elasticsearch Clients 中找到。 一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:

curl -X://:/?<QUERY_STRING>’ -d ‘‘

< > 标记的部件: VERB适当的 HTTP 方法 或 谓词 : GET、 POST、 PUT、 HEAD 或者 DELETE。 PROTOCOLhttp 或者 https(如果你在 Elasticsearch 前面有一个 https 代理) HOSTElasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。 PORT运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。 PATHAPI 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。 QUERY_STRING任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读) BODY一个 JSON 格式的请求体 (如果请求需要的话) 例如,计算集群中文档的数量,可以用这个:

curl -XGET ‘http://localhost:9200/\_count?pretty‘ -d ‘
{
“query”: {
“match_all”: {}
}
}

Elasticsearch 返回一个 HTTP 状态码(例如:200 OK)和(除`HEAD`请求)一个 JSON 格式的返回值。前面的 curl 请求将返回一个像下面一样的 JSON 体:

{
“count” : 0,
“_shards” : {
“total” : 5,
“successful” : 5,
“failed” : 0
}
}

在返回结果中没有看到 HTTP 头信息是因为没有要求`curl`显示它们。想要看到头信息,需要结合 -i 参数来使用 curl 命令:

curl -i -XGET ‘localhost:9200/‘

在剩余的部分,用缩写格式来展示这些 curl 示例,所谓的缩写格式就是省略请求中所有相同的部分,例如主机名、端口号以及 curl 命令本身。而不是像下面显示的那样用一个完整的请求:

curl -XGET ‘localhost:9200/_count?pretty’ -d ‘
{
“query”: {
“match_all”: {}
}
}’

用缩写格式显示:

curl -X GET “localhost:9200/_count?pretty” -H ‘Content-Type: application/json’ -d’
{
“query”: {
“match_all”: {}
}
}

面向文档

在应用程序中对象很少只是一个简单的键和值的列表。通常,它们拥有更复杂的数据结构,可能包括日期、地理信息、其他对象或者数组等。 也许有一天你想把这些对象存储在数据库中。使用关系型数据库的行和列存储,这相当于是把一个表现力丰富的对象塞到一个非常大的电子表格中:为了适应表结构,你必须设法将这个对象扁平化—​通常一个字段对应一列—​而且每次查询时又需要将其重新构造为对象。 Elasticsearch 是 面向文档 的,意味着它存储整个对象或 文档。Elasticsearch 不仅存储文档,而且 索引 每个文档的内容,使之可以被检索。在 Elasticsearch 中,我们对文档进行索引、检索、排序和过滤—​而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。

JSON

Elasticsearch 使用 JavaScript Object Notation(或者 JSON)作为文档的序列化格式。JSON 序列化为大多数编程语言所支持,并且已经成为 NoSQL 领域的标准格式。 它简单、简洁、易于阅读。 下面这个 JSON 文档代表了一个 user 对象:

{
“email”: “john@smith.com“,
“first_name”: “John”,
“last_name”: “Smith”,
“info”: {
“bio”: “Eco-warrior and defender of the weak”,
“age”: 25,
“interests”: [ “dolphins”, “whales” ]
},
“join_date”: “2014/05/01”
}

虽然原始的 user 对象很复杂,但这个对象的结构和含义在 JSON 版本中都得到了体现和保留。在 Elasticsearch 中将对象转化为 JSON 后构建索引要比在一个扁平的表结构中要简单的多。

几乎所有的语言都有可以将任意的数据结构或对象转化成 JSON 格式的模块,只是细节各不相同。具体请查看 serialization 或者 marshalling 这两个处理 JSON 的模块。官方 Elasticsearch 客户端 自动为您提供 JSON 转化。