概要

  • Elasticsearch是分布式全文搜索引擎,底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。Elasticsearch 是 Lucene 的封装,提供了 REST API 的操作接口和Java API,开箱即用。
  • Elasticsearch特性:
    • 1.一个分布式的实时文档存储,每个字段 可以被索引与搜索
    • 2.一个分布式实时分析搜索引擎
    • 3.能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据
  • Elasticsearch交互:
      1. Java API
        transport.tcp.port: 9309 // tcp服务端口(java api调用)
      1. RESTful API
        http.port: 9209 // rest服务端口

特点

1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
2)Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
4)数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;Elasticsearch作为传统数据库的一个补充,提供了数据库所不能提供的很多功能

核心概念

  • Node、Cluster
    • es本质是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个es实例,单个es实例称为一个节点(Node),一组节点构成一个集群(Cluster)
  • Index:
    • es数据管理的顶层单位是Index(索引),Index名必须是小写
  • Type:
    • 分组,不同的 Type 应该有相似的结构(schema),举例来说,id字段不能在这个组是字符串,在另一个组是数值。这是与关系型数据库的表的一个区别。性质完全不同的数据(比如products和logs)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然可以做到)
  • Document:
    • Index里面的单条记录叫Document(文档),文档使用json格式
  • 关系型数据库和Elasticsearch比较

    • Elasticsearch介绍 - 图1

      集群

  • 一个运行中的 Elasticsearch 实例称为一个 节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。

  • 当一个节点被选举成为 主节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。同一台服务器中可以部署多个节点,但是只有一个节点能成为主节点。
  • 作为用户,我们可以将请求发送到 集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。
  • 集群健康检查: GET /_cluster/health?pretty
    • Elasticsearch介绍 - 图2
    • status字段表示集群是否正常工作
      • green:所有主分片和副本都正常工作
      • yellow:所有主分片正常工作,不是所有副本分片都正常工作
      • red:有主分片没有正常工作
    • 1个节点 3个主分片,副本数为1(3个主分片位于主节点,没有副本分片) status:yellow
    • 2个节点 3个主分片,副本数为1(3个主分片位于主节点,3个福分片位于副节点) status:green
    • 6个节点 3个主分片,副本数为1(每个节点含有一个分片) status:green

索引、分片

  • 索引实际上是一个逻辑命名空间,指向一个或多个物理分片
  • 一个分片是一个底层的工作单元,它仅仅保存全部数据的一部分,一个分片是一个Lucence的实例,本身就是一个完整的搜索引擎,文档是被存储和索引到分片中,但是应用程序是直接与索引交互而不是与分片。
  • Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
    • 一个分片可以是 主分片或者副本分片。 索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。
      一个副本分片只是一个主分片的拷贝。 副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。
      在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改。
      技术上来说,一个主分片最大能够存储 Integer.MAX_VALUE - 128 个文档,但是实际最大值还需要参考你的使用场景:包括你使用的硬件, 文档的大小和复杂程度,索引和查询文档的方式以及你期望的响应时长。
  • 索引创建的时候默认有5个分片
  • 创建一个有3个分片的索引:

    1. /GET /test_index
    2. {
    3. "settings":
    4. {
    5. "number_of_shards":3,
    6. "number_of_replicas":1
    7. }
    8. }
    9. number_of_shards: 主分片数 number_of_replicas: 副本数
  • 读操作(搜索和返回数据)可以同时被主分片或副本分片处理,所以越多的副本分片,也将拥有越多的吞吐量 动态调整副本分片数: /GET /test_index/_settings {“number_of_replicas”: 2}

  • 如果只是在相同节点数目的集群上增加更多的副本分片并不能提高性能,因为每个分片从节点上获得的资源会变少。 你需要增加更多的硬件资源来提升吞吐量。
    但是更多的副本分片数提高了数据冗余量:我们可以在失去部分节点的情况下不丢失任何数据。
  • 当主节点出现故障时,集群会选举一个新的节点作为主节点,同时会将副本分片提升为主分片,这个过程是瞬间完成的。(主分片并不一定要在主节点上)

文档

  • 在Elasticsearch中,文档(Document)是指最顶层或者根对象, 这个根对象被序列化成 JSON 并存储到 Elasticsearch 中,指定了唯一 ID
  • 文档元数据
    • _index: 索引
    • _type: 类型
    • _id: ID
    • _index、_type、_id三个组合可以唯一确定一个文档
  • 索引文档
    • 索引(index)在es中含有多层含义:
      1. 名词:es数据管理的顶层单位,类似数据库
      2. 动词:存储数据到es的行为叫索引,类似关系数据库的insert
      3. 倒排索引:es使用倒排索引来提高数据检索速度,文档中的每一个属性都是被索引的(有一个倒排索引)和可搜索的
  • 索引文档
    • 指定ID: PUT /index/type/id {“name”:”wfy”,”age”:18}
    • 自动生成ID: POST /index/type {“name”:”wfy”,”age”:18}
    • 索引文档时,假如索引不存在,es会自动创建索引和映射,并索引文档,可以在配置文件中关闭自动创建索引
  • 文档搜索

    • es默认按照相关性得分(score)排序并返回结果,也这是区别关系型数据库的一个概念,关系型数据库中的一条记录要么匹配要么不匹配
    • 搜索指定索引、类型的所有文档: GET /index/type/_search

      • _source字段包含查询结果
        1. {
        2. "_index" : "website",
        3. "_type" : "blog",
        4. "_id" : "123",
        5. "_version" : 1,
        6. "found" : true,
        7. "_source" : {
        8. "title": "My first blog entry",
        9. "text": "Just trying this out...",
        10. "date": "2014/01/01"
        11. }
        12. }
    • 搜索last_name=smith的文档: 1.使用Query-string: GET /index/type/_search?q=last_name:smith

    • 使用DSL:GET /index/type/_search {“query”:{“match”:{“last_name”:”smith”}}}
    • 搜索last_name=smith或fir的文档 GET /index/type/_search {“query”:{“match”:{“last_name”:”smith fir”}}}
    • 短语搜索: match_phrase
      • 搜索短语 rock climbing GET /index/type/_search {“query”:{“match_phrase”:{“about”:”rock climbing”}}}
    • 高亮搜索:highlight
      1. curl -XGET '172.16.16.167:9209/megacorp/employee/_search' -d '{
      2. "query": {
      3. "match_phrase": {
      4. "about": "rock climbing"
      5. }
      6. },
      7. "highlight": {
      8. "fields": {
      9. "about": {}
      10. }
      11. }
      12. }'