ElasticSearch 入门

1,362 阅读4分钟

ElasticSearch 简介

ElasticSearch是面向文档的基于Lucene的搜索引擎,可以形容成:

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

ElasticSearc 将所有的功能打包成了一个服务,提供基于HTTP协议,以JSON为数据交互个数的RESTful API的形式进通信。 ElasticSearch 是面向文档型数据库,一条数据就是一个文档。

适用场景:明细查询、过滤、排序
不适合场景

  • 大数据量、高基数(桶太多)聚合
  • 大数据量、高基数(唯一值太多)去重(去重也是不准确的)
  • 关联查询:es对关联查询支持的不好
  • 多维度组合聚合:在基数较大的时候,会存在严重的性能问题
  • 数据精确:不保证一点不丢数据,框架都有有问题的时候
  • 大量导出:不适合大批量查询
  • 数据分析:不适用于离线计算

几个重要名词

1. 索引(index

相当于Mysql中的数据库(database),用于存放文档

2. 类型(type

相当于Mysql中的表(table),定义了相同数据结构的文档存放

3. 文档(document

相当于Mysql中的一行记录(row),是索引的基本单元,包含一个或多个键值对,表现形式就是json对象

4. 字段(filed)

相当于Mysql中的一列(column),是key-value形式的

举例:

  1. 存储文档
curl -X PUT "localhost:9200/megacorp/employee/1" 
-H 'Content-Type: application/json' -d
'{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}'

如上所示,我们将一个以json形式表现的雇员对象存入了ElasticSearch集群中,这个文档存在于集群中的megacorp索引中,类型是employee,文档的id是1

如果原来索引不存在会自动在集群中创建

  1. 查询文档
curl -X GET "localhost:9200/megacorp/employee/1"

返回值:

{
  "_index" :   "megacorp",// 文档的索引
  "_type" :    "employee",// 文档的类型
  "_id" :      "1",// 文档的id
  "_version" : 1,// 文档的版本(用于并发修改,乐观控制)
  "found" :    true,// 表示是否检索到
  "_source" :  {// 实际文档内容
      "first_name" :  "John",
      "last_name" :   "Smith",
      "age" :         25,
      "about" :       "I love to go rock climbing",
      "interests":  [ "sports", "music" ]
  }
}

如上所示,在megacorp索引中查询类型为employee,id=1的文档;而返回的json中包含了文档的所有属性。

Tip: 从上面的返回结果可以知道index,type和id可以唯一确定一个文档

这只是最简单的存储和检索,后面会介绍更详细的条件查询,聚合等操作。

分布式介绍

我们知道ElasticSearch是分布式的,是可以处理PB级别的数据,所以下面简单介绍一下ES是如何实现这些特性的。

一个运行中的ES实例是一个节点,一个集群中有一个或者多个节点,这些节点中的cluste.name是相同的。
我们在创建索引时可以指定这个索引的主分片数和副本分片数,默认是5个主分片,1个副本分片(5*1=5个分片)。这些分片会均匀的分布在集群的所有数据节点中。
在客户端发送请求时,集群中所有的节点都能处理这个请求,节点会找到文档所存储的分片,并在该分片所在的节点做检索,将结果返回给请求的那个节点做最终的过滤和组合,然后返回给客户端。
那么在往这个索引上面存储文档时,会存储到5个分片中的一个分片上,而这个路由是由下面的公式决定的

shard = hash(routing) % number_of_primary_shards

routing是可以设置的一个值,默认是文档的id

number_of_primary_shards是主分片的数量(5)

也正是这个公式的原因,所以规定了索引创建后不能修改主分片数

所有的文档 API( get 、 index 、 delete 、 bulk 、 update 以及 mget )都接受一个叫做 routing 的路由参数,通过这个参数我们可以自定义文档到分片的映射。

重点回顾

  • ES中的数据结构index->type->document->filed 类比关系型数据库。
  • 客户端如何和ES服务器交互,使用http+json的方式
  • ES是分布式的,天生支持横向扩展(使用分片的方式存储以及自定义路由的方式可以动态扩容)



未完待续!!!