Elasticsearch特点:分布式,高性能,高可用,高伸缩的搜索和分析;
1)可作为一个大型分布式集群,处理PB级别的数据,服务大型公司,亦可运行在少数或单台设备上服务小型公司
分布式的特性:
Elasticsearch致力于隐藏式分布式系统的复杂性,如下这些操作都是在底层自动完成的:
- 将你的文档分区到不同的容器或者分片(shards)中,他们可以存在于一个或多个节点中
- 将分片均匀的分配到各个节点,对索引和搜索做负载均衡。
- 冗余每一个分片,防止硬件故障造成的数据丢失
- 将集群中任意一个节点上的请求路由到相应数据所在的节点
- 无论是节点增加或减少,分片都可以做到无缝的扩展和迁移
2)Elasticsearch主要将全文检索、数据分析以及分布式技术,合并在了一起;
3)对用户而言,使用便利
4)相比传统数据库作搜索性能和功能有了很大提升(全文检索,同义词处理,相关度排名,复杂数据分析,对海量数据近实时处理等等);
功能:
1)分布式搜索引擎和数据分析引擎;
2)全文检索,结构化检索,数据分析。
3)对海量数据进行近实时的处理
集群内部工作方式
Elasticsearch用于构建高可用和可扩展的系统,扩展的方式可以是购买更高配置的Server(纵向扩展:vertical scale or scaling up)或者购买更多数量的server(横向扩展:horizontal scale or scaling out).
Elasticsearche虽说能从更强大的硬件中获得更好的性能,但是纵向扩展仍存在自身的局限性,真正扩展的往往是横向扩展,通过增加节点来分担负载增加可靠习惯。(对于大多数数据库而言,横向扩展的意味着你的程序讲座非常大的改动才能利用这些添加的设备。ES在这里就显现出优点,因为ES天生就是分布式的:他知道如何管理节点来提高扩展和高可用,这意味着你的程序不需要关心这些。)
全文检索和Lucene
1)全文检索,倒排索引
2)lucene,本来是一个jar包,内部包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。在使用Java开发的时候,引入lucene的jar包,然后基于lucene的api进行开发时,lucene会帮助我们在已有的数据中建立索引,帮助我们组织索引结构,此外还可以使用lucene提供的功能和api来针对磁盘上的索引数据,进行搜索。
一、ES部分名词解释
【Cluster】
集群,一个ES集群由一个或多个节点(Node)组成,每个集群都有一个cluster name作为标识。
【node】
节点,一个ES实例就是一个node,一个机器可以有多个实例,所以并不能说一台机器就是一个node,大多数情况下每个node运行在一个独立的环境或虚拟机上。
【index】
索引,即一系列documents的集合。
【Routing】
路由,当你索引一个文档,它是存储在一个主分片里。这分片的选择是通过哈希的路由值。默认情况下,路由值来自文档的ID;如果该文档指定了父文档,则使用父文档的ID(以确保这个子文档和父文件都存储在相同的分片上)。这个路由值可以在索引的时候,通过指定数值或者配置字段映射来覆盖
【shard】
1. 分片,ES是分布式搜索引擎,每个索引有一个或多个分片,索引的数据被分配到各个分片上,相当于一桶水用了N个杯子装。
2. 分片有助于横向扩展,N个分片会被尽可能平均地(rebalance)分配在不同的节点上(例如你有2个节点,4个主分片(不考虑备份),那么每个节点会分到2个分片,后来你增加了2个节点,那么你这4个节点上都会有1个分片,这个过程叫relocation,ES感知后自动完成)。
3. 分片是独立的,对于一个Search Request的行为,每个分片都会执行这个Request。
4. 每个分片都是一个Lucene Index,所以一个分片只能存放 Integer.MAX_VALUE - 128 = 2,147,483,519 个docs。[LUCENE-5843] IndexWriter should refuse to create an index with more than INT_MAX docs
【replica】
1. 复制,可以理解为备份分片,相应地有primary shard(主分片)。
2. 主分片和备分片不会出现在同一个节点上(防止单点故障),默认情况下一个索引创建5个分片一个备份(即5primary+5replica=10个分片)
3. 如果你只有一个节点,那么5个replica都无法分配(unassigned),此时cluster status会变成Yellow。
ES集群状态有三种:
- Green:所有主分片和备份分片都准备就绪(分配成功),即使有一台机器挂了(假设一台机器一个实例),数据都不会丢 失,但会变成Yellow状态
- Yellow:所有主分片准备就绪,但存在至少一个主分片(假设是A)对应的备份分片没有就绪,此时集群属于警告状态,意味着集群高可用和容灾能力下降,如果刚好A所在的机器挂了,并且你只设置了一个备份(已处于未就绪状态),那么A的数据就会丢失(查询结果不完整),此时集群进入Red状态
- Red:至少有一个主分片没有就绪(直接原因是找不到对应的备份分片成为新的主分片),此时查询的结果会出现数据丢失(不完整)
4. replica的作用主要包括:
a.容灾:primary分片丢失,replica分片就会被顶上去成为新的主分片,同时根据这个新的主分片创建新的replica,集群数据安然无恙
b. 提高查询性能:replica和primary分片的数据是相同的,所以对于一个query既可以查主分片也可以查备分片,在合适的范围内多个replica性能会更优(但要考虑资源占用也会提升[cpu/disk/heap]),另外index request只能发生在主分片上,replica不能执行index request。
5. 对于一个索引,除非重建索引否则不能调整分片的数目(主分片数, number_of_shards),但可以随时调整replica数(number_of_replicas)。
二、ES的文档数据格式的优点
1.可以提供复杂的面向对象的数据结构;
2.如果不适用ES,使用传统的关系型数据库,复杂的对象只能拍平,放到多个关联表中,查询的时候需要查询多个表,而且还得重新组合成复杂对象,特别麻烦;
3.基于ES面向文档的特性,而且提供了倒排索引,所以可以胜任复杂的查询和检索需求;
4.使用传统,流行的文档对象来存储,很容易处理;
三、ES集群简单管理
1、集群健康状态
使用_cat相关api查看,如下:
[root@es-master ~]# curl http://localhost:9200/_cat/health?pretty
#返回结果
1549092107 02:21:47 elasticsearch green 3 3 134 67 0 0 0 0 – 100.0%
可以看出,如果集群中的所有节点都正常启动,整个集群的状态为green;
2、集群的三种状态
(1)红(red):不是所有的primary shard都是active状态的,部分索引有数据丢失了;
(2)黄(yellow):每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态,此时可以继续使用;
(3)绿(green):每个索引的primary shard和replica shard都是active状态的;
#集群启动时状态变化过程:
集群启动的时候,首先会有某些节点先启动,这些节点会被作为主节点,在所有的主节点未完全启动之前,集群此时处于red状态;
———————————————————————————————————————
当主节点全部启动之后,集群状态会变为yellow状态;———————————————————————————————————————
所有的replica节点都启动完成之后,集群中的所有节点都已经齐全,此时集群变为green状态;
3、_cat中的重要api
查看集群中的节点数
[root@es-master ~]# curl http://localhost:9200/_cat/nodes?pretty
192.168.199.12 29 95 12 0.00 0.08 0.06 mdi * es-node2
192.168.199.11 41 88 25 0.64 0.75 0.57 mdi – es-node1
192.168.199.11 20 88 25 0.64 0.75 0.57 mdi – es-node3
#表示集群中有三个节点,es-node1,es-node2,es-node3;
查看集群中的分片数
[root@es-master ~]# curl http://localhost:9200/_cat/shards?pretty
student_index 3 p STARTED 1 4.3kb 192.168.199.11 es-node1
student_index 3 r STARTED 1 4.3kb 192.168.199.11 es-node3
student_index 2 p STARTED 2 8.5kb 192.168.199.12 es-node2
student_index 2 r STARTED 2 8.5kb 192.168.199.11 es-node3
student_index 1 r STARTED 1 4.4kb 192.168.199.11 es-node1
student_index 1 p STARTED 1 4.4kb 192.168.199.12 es-node2
student_index 4 p STARTED 1 4.4kb 192.168.199.11 es-node1
student_index 4 r STARTED 1 4.4kb 192.168.199.11 es-node3
student_index 0 p STARTED 0 261b 192.168.199.12 es-node2
student_index 0 r STARTED 0 261b 192.168.199.11 es-node3#表示student_index索引默认有10个分片,5个primary和5个replica;
查看集群中的索引列表
[root@es-master ~]# curl http://localhost:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
…结果略#默认展示的是系统索引和自己创建的索引,参数v表示查看详细信息;
_cat还有其他api,但是不是很常用,如果需要,可以通过如下命令查看即可
[root@es-master ~]# curl http://localhost:9200/_cat
/_cat/allocation
/_cat/shards
/_cat/nodes
/_cat/tasks
…其他输出结果略.
四、ES简单操作
此处以电商系统商品搜索为例,使用kibana图形化操作界面,介绍ES的简单操作。
1、创建
用法:
PUT /index_name/type_name/id
{}
例如:创建一个索引名称为shop_index,类型为productInfo,id为1的索引
PUT /shop_index/productInfo/1 { "name": "HuaWei Mate8", "desc": "Cheap and easy to use", "price": 2500, "producer": "HuaWei Producer", "tags": [ "Cheap", "Fast" ] }
2、查询
用法:
GET /index_name/type_name/id
例如:查询id为1的商品信息
GET /shop_index/productInfo/1 { "_index": "shop_index", "_type": "productInfo", "_id": "1", "_version": 1, "found": true, "_source": { "name": "HuaWei Mate8", "desc": "Cheap and easy to use", "price": 2500, "producer": "HuaWei Producer", "tags": [ "Cheap", "Fast" ] } }
3、修改
方法一:替换,通过ID替换,如果文档存在,则直接覆盖
用法:
PUT /index_name/type_name/id
{}
例如:将商品价格修改为2400
PUT /shop_index/productInfo/1 { "name": "HuaWei Mate8", "desc": "Cheap and easy to use", "price": 2400, "producer": "HuaWei Producer", "tags": [ "Cheap", "Fast" ] }
注意:
替换某个文档时,需要带着文档中的所有字段,否则未带着的字段会丢失,切记!!!
方法二:通过ID更新部分字段
用法:
POST /index_name/type_name/id/_update
{}
例如:将上述商品的价格改为2200
POST /shop_index/productInfo/1/_update { "doc": { "price": 2200 } }
4、删除
用法:
DELETE /index_index/type_index/id
例如:删除id为1的商品记录:
DELETE /shop_index/productInfo/1