一、es背景和使用场景
ElasticSearch基于Lucene的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful api接口。ES经常被用作文档数据库,主要得益于它的分布式特性和实时搜索能力。
1.1集群和节点
ES可以作为一个独立的搜索服务器工作,对于大型数据处理场景和容错功能,ES也支持在多台协同工作的服务器上运行,即可以在集群模式(cluster)下运行。集群中的每个服务器被成为节点(node),可以通过索引分片将海量数据进行分割分配到不同的节点之上。一个节点上可以运行多个es实例,每个实例即一个es服务进程。通过副本可以实现更强的可用性和更高的性能。
1.2索引
索引(Index)是ES存储数据的地方,这里和关系型数据库中的索引有所不同。这里的索引可以理解为关系型数数据库中的一张表。与关系型数据库相比,es可以高效、快速地对索引中的数据进行全文检索,并且不需要存储原始数据。
1.3分片和副本
当需要存储大规模文件时,由于内容和硬盘的限制,单节点处理是不能够满足需求的。需要将索引进行切割和分配,这就引入了分片的概念。分片(Shards)就是对索引进行分割, 每个分片可以被存储在集群中的不同节点之上。当需要查询一个由多个分片组成的索引时,es将查询结果进行自动合并。这些过程对于具体客户端应用而言是封闭的,无需知道分片的存在。
提高查询的吞吐量和高可用性,可以开启分片的副本功能。副本(replications)是对原始分片的一个精确拷贝,每个主分片可以由零个或多个副分片。当主分片丢失时(存贮数据的服务器不可用),集群就可以将副本分片提升为新的主分片。
1.4文档
文档(document)是ES中存储的主要实体,类比关系型数据库es中的每个文档可以理解为数据库表中的一行数据。类似于MongoDB,es的文档也可以具有不同的结构,但es要求公共字段具有相同类型。
文档由字段构成,es允许一个字段出现多次,该类字段被成为多值字段。每个字段对应一种类型,字段类型可以是复合的,字段可以包含其他子文档或数组。es可以自动判断字段类型,与关系型数据库不同,es文档不需要固定结构,不同的文档可以具有不同的字段集合,而且在程序开发的时候不需要知道文档的字段。也可以通过模式映射(schema mapping)定义文档结构。
二、es的CRUD
es是基于RESTful API对数据进行管理的,它可以方便我们管理索引、更新实例参数、检查节点和集群状态、索引数据并提供搜索服务。下面介绍API中的CRUD(创建create、检索retrieve、更新update、删除delete)操作的用法。
在es中,每一块数据都有定义好的索引和类型,可以把索引比作文档集合或数据库中的表。与数据库中的记录不同,添加到索引中的文档并没有定义好的结构和字段类型。更确切地说,每个字段都有自定义类型,不过es可以猜到每个字段对应的类型(因为json是半类型化的,数字是不加引号的),并自动定制在内部结构中存储数据的方式。
与es的交互方式采用http的请求方式,请求的格式如下:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
是请求的方法,比如:GET、POST、DELETE、PUT等。 协议:http或者https。 主机地址。 端口 API的路径。比如查看集群状态: /_cluster/stats
。参数。比如:?pretty,打印出格式化以后的Json。 - 请求的内容。比如:添加索引时的数据。
2.1文档的增删改查
创建文档
[root@master ~]# curl -XPOST -H "Content-Type: application/json" \
http://192.168.137.11:9200/sf/bdp/devpos?pretty -d \
'{"name":"WayneGao",
"Age":24,
"gender":"male",
"work":"dev&ops"}'
{
"_index" : "sf",
"_type" : "bdp",
"_id" : "devpos",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
json包含了一组字段,各字段可以有不同的形式。
-H 指定headers中的传输格式为application/json -d 选项的取值用作请求负载的文本——请求正文。
检索文档
[root@master ~]# curl http://192.168.137.11:9200/sf/bdp/devpos?pretty
{
"_index" : "sf",
"_type" : "bdp",
"_id" : "devpos",
"_version" : 3,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "WayneGao",
"Age" : "24",
"gender" : "male",
"work" : "dev&ops"
}
}
更新文档
root@master ~]# curl -XPUT -H "Content-Type: application/json"
http://192.168.137.11:9200/sf/bdp/devpos?pretty
-d '{"name":"WayneGao",
"Age":"24",
"gender":"male",
"work":"dev&ops",
"tags":"handsome",
"web":[
"nginx",
"openresty",
"httpd"]
}'
删除文档
[root@master ~]# curl -XDELETE http://192.168.137.11:9200/sf/bdp/devpos?pretty
{
"_index" : "sf",
"_type" : "bdp",
"_id" : "devpos",
"_version" : 6,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
2.2手工创建索引和配置映射
下面介绍如何创建新的索引和如何创建合适且与已有数据结构相匹配的映射。
索引是ES中存储数据的一种逻辑结构吗ES集群可以同时运行个索引,除此之外,单个索引是有分片组成的,所以它可以分散到集群地多个节点中去。不仅如此,每个分片可以有一个完全相同的副本,用于调控搜索性能以及发生故障的备份恢复。
所有组成索引的分片实际上就是被分解成多个类型的Apacehe Lucene索引。
2.2.1索引操作
虽然在创建文档的时候es索引就被创建了,但是我们还是想自己来创建索引。
不定义数据类型和格式
[root@master ~]# curl -XPUT 'http://192.168.137.11:9200/sf-tech?pretty'
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "sf-tech"
}
指定索引的结构和映射 settings 和 mappings
**
模式映射用于定义索引结构,每个索引都可以有多种类型,但此时仅考虑一个索引只有一种类型的情况。
- 请求的方法用
PUT
。 - /后面直接跟索引的名称即可。
索引的设置和字段都放在Body中
[root@master ~]# curl -XPUT -H "content-type":"application/json" http://192.168.137.11:9200/org -d '{
"settings":{
"number_of_shards":2,
"number_of_replicas":2
}
,
"mappings":{
"properties":{
"id":{
"type":"long"
},
"name":{
"type":"text"
}
}
}
}'
请求体中分为两个部分:
settings
和mappings
。在settings
中,我们设置了分片数和副本数。number_of_shards
:分片的数量;number_of_replicas
:副本的数量;
在mappings
中,我们设置索引的字段,在这里,我们只设置了id和name,id的映射类型是long,name的映射类型是text。