1. 安装ElasticSearch与配置
2. Head插件安装
3. Kibanna安装/Dev Tools安装
4. Elasticsearch 面向文档,它存储和索引整个对象或者文档;对文档进行索引/检索/过滤,而不是对列。
5. 存储数据到Elasticsearch的行为叫做索引,一个Elasticsearch集群可以包含多个索引,相应的索引也可以包含多个类型,这些不同的类型存储着不同的文档,每个文档又有多个属性。
6. Elasticsearch和Lucene使用了一个叫做倒排索引的结构来提高数据检索速度,默认每个文档中的每个属性都会被索引,而且可搜索。
7. 启动:直接运行{ES_HOME}/bin/elasticsearch.bat 则直接运行在9002端口下。
8. 启动Kibanna:直接运行{KIBANA_HOME}/bin/kibana.bat 访问:
http://localhost:5601/app/kibana#/dev_tools/console?_g=()
9. 启动head:直接在C:\软件安装\head\elasticsearch-head-master\elasticsearch-head-master下运行 grunt server 访问:
http://localhost:9100/
10.curl使用:在CMD中执行:
curl -i -XGET http://localhost:9200/website/blog/124?pretty
1. 使用一条put命令就可以完成创建索引和类型以及添加数据。
PUT/megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": ["sports", "music" ]
}
2. 使用get命令检索文档:
GET /megacorp/employee/1
3. 轻量检索
GET /megacorp/employee/_search
4. 高亮检索
GET /megacorp/employee/_search?q=last_name:Smith
5. 查询表达式
GET/megacorp/employee/_search
{
"query": {
"match": {
"last_name": "Smith"
}
}
}
6. 查询范围使用filter
GET/megacorp/employee/_search
{
"query":
{
"bool":
{
"must":
{
"match":
{
"last_name":"smith"
}
},
"filter":
{
"range": {
"age": {
"gt": 30
}
}
}
}
}
}
7. elasticsearch根据相关性返回文档,这跟关系型数据库有很大差别
GET/megacorp/employee/_search
{
"query":
{
"match":
{
"about":"rockclimbing"
}
}
}
8. 短语搜索
GET/megacorp/employee/_search
{
"query":
{
"match_phrase":
{
"about":"rockclimbing"
}
}
}
9. 高亮显示短语搜索匹配的结果
GET/megacorp/employee/_search
{
"query":
{
"match_phrase":
{
"about":"rockclimbing"
}
},
"highlight":
{
"fields":
{
"about":{}
}
}
}
10. 聚合分析 按照兴趣进行分组统计
直接执行查询,则显示如下异常:"Fielddata is disabled on text fieldsby default. Set fielddata=true on”,执行如下PUT命令后,就可以直接操作了。
PUTmegacorp/_mapping/employee/
{
"properties":
{
"interests":
{
"type":"text",
"fielddata":true
}
}
}
GET /megacorp/employee/_search
{
"aggs":
{
"all_interests":
{
"terms":
{
"field":"interests"
}
}
}
}
11. 对满足条件的就进行分组统计 查询名称为smith的员工的兴趣分组统计
GET/megacorp/employee/_search
{
"query":
{
"match": {
"last_name": "smith"
}
},
"aggs":
{
"all_interests":
{
"terms":
{
"field":"interests"
}
}
}
}
12. 对分组聚合查询所得结果求平均值 各个兴趣关注员工的平均年龄
GETmegacorp/employee/_search
{
"aggs":
{
"all_interests":
{
"terms":
{
"field":"interests"
}
, "aggs": {
"avg_age": {
"avg": {
"field": "age"
}
}
}
}
}
}
13. 分布式特性
Elasticsearch自动进行如下操作:
a. 分配文档到不同的容器或者分片中,文档可以存储在一个或者多个节点中
b. 按照集群节点均衡分配这些分片,从而对索引和搜索进行负载均衡
c. 复制每个分片以支持数据冗余,从而方式硬件故障导致的数据丢失
d. 将集群中任一节点的请求路由到存有数据的节点
e. 集群扩容时无缝整合新节点,重新分配分片以便从离群节点恢复
1. 集群节点:一个运行中Elasticsearch实例就是一个节点;每个节点都能够将接收到的请求发送到拥有相关数据的节点并成功返回查询结果。
2. 主节点:当一个节点被选择为主节点时,它将负责管理集群范围内的所有变更,例如增加、删除索引或者增加删除节点等,主节点并不涉及文档级别的变更和搜索等操作;任何节点都可以成为主节点。
3. 集群健康:查询:GET /_cluster/health
查询结果中的status字段:
green:所有主分片和副分片都正常
yellow:所有主分片都运行正常,部分副分片运行不正常
red:部分主分片未正常运行
4. 添加索引
向Elasticsearch中添加数据时需要用到索引——保存相关数据的地方。索引是指向一个或者多个物理分片的逻辑命名空间。
一个分片是一个底层的工作单元,它仅保存了全部数据的一部分,一个分片是一个lucene实例,其本身就是一个完整的搜索引擎,文档会被存储和索引到分片内,但是应用程序是直接与索引而不是与分片交互。
分片是容器,文档保存在分片内,而分片又被分配在不同的节点内;当集群伸缩时,Elasticsearch会自动在各个节点中进行节点迁移,使数据均匀分布在集群里。
一个分片可以时主分片或者副分片,索引内任意一个文档都属于主分片,所以主分片的数量决定了索引能够保存的最大数据量。
一个副分片是一个主分片的拷贝,副分片作为主分片的数据冗余备份以防硬件故障引起的数据丢失,并为搜索和返回文档等读操作提供服务。
主分片数在建立索引时已经确定,但是副分片数可以随时修改。
创建索引:
PUT/blogs
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
5. 添加故障转移
添加节点,可在同一台机器启动多个Elasticsearch实例,这样就会有多个节点;同一台机器上启动多个实例时,Elasticsearch会根据cluster.name自动发现同一集群节点,自动加入;如果在不同机器上启动节点,则需要配置单播主机列表,以便让此节点加入集群。
6. 水平扩容
增加节点,Elasticsearch会自动将分片在各个节点直接重新分配,以充分利用新加入的硬件资源。
可以通过调整副分片数目实现扩容:
PUT/blogs/_settings
{
"number_of_replicas": 2
}
7. 应对故障
分片的提升和恢复。
一个对象是基于特定语言的内存数据结构,JSON是一种以人可读的文本表示对象的方法。
1. 对象和文档
对象:类似于hash、hashmap、字典或者关联数组的JSON对象,对象中也可以嵌套其他对象。
文档:指最顶层或者根对象,这个根对象被序列化成JSON并存储在Elasticsearch中,并制定了唯一ID。
2. 文档元数据
一个文档不仅仅包含它的数据,也包含元数据——有关文档的信息,三个必须的元数据如下:
_index 文档存在在哪里
一个索引应该是因为拥有共同特性而被分在一起的文档集合。索引名称要求:必须小写,不能以下划线开头,不能包含逗号。
_type 文档表示的对象类别
索引中数据的逻辑分区,不同的type内的文档可能有不同的字段,但最好是相似的。Type命名要求:可以是大写或者小写,不能以下划线开头,不能包含逗号,长度不能超过256个字符。
_id 文档唯一标识
_id与_index,_type组合就可以确定唯一一个文档,可自行提供,也可自动生成。
_version 文档版本号
每个文档都有一个版本号,文档的任何修改(包括删除),文档的版本号都会递增。
3. 索引文档 使用index API,存储或者使文档可被搜索
A.自定义ID
PUT/{index}/{type}/{id}
{
"field": "value",
...
}
B.自动生成ID
POST/website/blog/
{
"title":"My second blogentry",
"text":"Still trying thisout",
"date":"2014/01/01"
}
4. 取回文档
GET /website/blog/1?pretty
获取部分字段:
GET /website/blog/1?_source=title,text
只获取source:
GET/website/blog/1/_source
提问:如果需要显示source中的一部分字段呢?
5. 检查文档是否存在
如果不需要返回内容,仅仅是确认文档是否存在,则可以使用HEAD
curl-i -XHEAD http://localhost:9200/website/blog/124
6. 更新整个文档
在Elasticsearch中文档是不可变的,不能修改它们。如果需要更新现有文档,就需要重新创建索引或者进行替换,可以使用index API实现。
PUT /website/blog/1
{
"title":"My first blogentry",
"text":"I am starting to getthe hang of this ...",
"date":"2014/01/02"
}
使用update API 可以完成文档部分更新,但是实质根上述操作完全一致,唯一的区别是不需要单独发送get和index请求:
A. 从旧文档构建JSON
B. 更改该JSON
C. 删除旧文档
D.索引一个新文档
7. 创建新文档
索引一个文档时,我们需要确认时在覆盖一个文档还是在创建一个文档。
a. 使用post让es自动生成唯一ID
POST/website/blog/
{
"title":"My third blogentry",
"text":"I am starting to getthe hang of this ...",
"date":"2014/01/02"
}
b. 使用op_type查询字符串 当指定index/type/id的文档不存在时才接受请求,否则异常
POST/website/blog/1?op_type=create
{
"title":"My third blogentry",
"text":"I am starting to getthe hang of this ...",
"date":"2014/01/02"
}
c. 在URL末端使用/_create 当指定index/type/id的文档不存在时才接受请求,否则异常
POST/website/blog/1/_create
{
"title":"My third blogentry",
"text":"I am starting to getthe hang of this ...",
"date":"2014/01/02"
}
8. 删除文档 逻辑删除,然后自动在后台物理清除
DELETE /website/blog/1
9. 处理冲突
悲观并发控制:
乐观并发控制:
10. 乐观并发控制
Elasticsearch通过使用_version(版本号)来避免新的版本被覆盖;在搜索返回结果中,包含有文档当前版本号,在对文档内容做修改后,提交时会检查库中文档的当前版本号与提交内容中的版本号是否一致,如果不一致,则请求失败,如果一致,则执行请求。
PUT/website/blog/1?version=1
{
"title":"My first blogentry",
"text":"Starting to get thehang of this"
}
11. 通过外部系统使用版本控制
如果主数据库中已经存在一个可以作为版本号的字段值比如timestamp,就可以在Elasticsearch中通过增加version_type=external到查询字符串的方式重用这些版本号,版本号必须是大于零的整数,且小于9.2e+18.
处理方式:检查当前_version是否小于指定的版本号,如果请求成功,外部的版本号作为文档新的版本号进行存储。版本号在文档创建/索引/删除时都可以指定。
PUT/website/blog/2?version=10&version_type=external
{
"title":"My first externalblog entry",
"text":"Starting to get thehang of this"
}
12. 文档的部分更新
使用update API部分更新文档。
检索-修改-重建索引发生在分片内部,减少了多次请求的网络开销,降低了冲突的可能性。
POST/website/blog/1/_update
{
"doc" : {
"tags" : [ "testing"],
"views": 0
}
}
13. 使用脚本更新文档
POST/website/blog/1/_update
{
"script":"ctx._source.views+=1"
}
Elasticsearch允许使用脚本编写自定义的逻辑。可以在集群中的所有节点的config/elasticsearch.yml 中禁用动态Groovy脚本:
Script.groovy.sandbox.enabled:false
以下脚本执行失败:
POST/website/blog/1/_update
{
"script" :"ctx._source.tags+=new_tag",
"params" : {
"new_tag" : "search"
}
}
14. 更新的文档可能不存在
Upsert参数,指定如果所要更新的文档不存在则创建。
POST/website/blog/1/_update
{
"script":"ctx._source.viess+=1",
"upsert":
{
"viess":1
}
}
第一次运行上述请求时,upsert值作为新文档被索引,初始化viess字段值为1,在后续的运行中,由于文档已经存在,script更新操作将替代upsert进行应用,对viess计数器进行累加。
15. 更新和冲突
如果版本冲突,更新失败,可以通过retry_on_conflict来自动完成重试操作。
POST/website/blog/1/_update?retry_on_conflict=5
{
"script":"ctx._source.viess+=1",
"upsert":{
"viess":0
}
}
16. 取回多个文档
GET /_mget
{
"docs":[
{
"_index":"website",
"_type":"blog",
"_id":"2"
},{
"_index":"website",
"_type":"pageviews",
"_id":"1",
"_source":"viess"
}
]
}
如果检索的数据在相同的_index或者_type中,则可以在URL中指定默认的/_index或者默认的/_index/_type
GET /website/blog/_mget
{
"docs": [
{
"_id": 2
},
{
"_type": "pageviews",
"_id": 1
}
]
}
GET/website/blog/_mget
{
"ids" : [ "2", "1" ]
}
17. 代价较小的批量操作
bulk API 允许在单个步骤中多次create、index、update或delete请求。
{action:{metadata}}\n
{request body}\n
{action:{metadata}}\n
{request body}\n
…
注意点:a.每行以\n结束,包括最后一行 b.不能包含未转义字符,避免对解析造成干扰
Action/metadata指定做什么操作
Action 必须是一下选项之一:
Create
Index
Update
Delete
Metadata应该指定被索引、创建、更新或者删除的文档的_index,_type和_id.
Request body 行由文档的_source本身组成,它是index、update和create操作所必需的,delete不需要。
Bulk请求不是原子的,不能用它来实现事务控制。
整个批量请求都需要由接收到请求的节点加载到内存中,所以存在最佳请求大小,可以通过尝试获得该值。
POST/website/log/_bulk
{"delete":{"_index":"website","_type":"blog","_id":"123"}}
{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"Myfirst blog post"}
{"update":{"_index":"website","_type":"blog","_id":"123","_retry_on_conflict":3}}
{"doc":{"reviss":"Myupdated blog post"}}
{"index":{"_index":"website","_type":"blog"}}
{"title":"Mysecond blog post"}
1. 路由一个文档到一个分片中
shard =hash(routing) % number_of_primary_shards
routing 是一个可变值,默认是文档的id,也可以设置自定义值;number_of_primary_shards主分片的数量。上述公式所得结果分布在0到number_of_primary_shards之间。
所有的API都接受routing的路由参数,通过此参数我们可以自定义文档到分片的映射。
2. 主分片和副分片如何交互
相同分片的副本不会放在同一节点上;协调节点(coordinating node)
3. 新建、索引、删除文档
新建、索引、删除请求都是写操作,必须在主分片上面完成之后才能被复制到相关的副分片。
操作顺序:
a. 客户端向node1发送新建、索引、删除请求
b. 节点使用文档的_id确定文档输入分片0.请求会被转发到node3,因为分片0的主分片在node3上。
c. Node3在主分片上执行请求,若成功,则同时将请求转发到node1和node2的扶分片上,一旦副分片上请求报告成功,node3将向node1(协调节点)报告成功,协调节点向客户端报告成功。
一些额外参数:
Consistency 默认设置向,当主分片数大于1时,执行请求签主分片会要求必须要有规定数据量的分片副本处于活跃可用状态,可会执行请求。
Int((primary+number_of_replicas)/2)+1
值:one all quorum
number_of_replicas指的时在索引设置中的设定副本分片数,而不是指当前处理活动状态的副本分片数。
Timeout 如果没有到达规定数量的分片副本处于活跃可用状态,则会等待一定时间,超过等待时间仍未满足条件,则超时。
4. 取回单个文档
在处理读取请求时,协调节点在每次请求时都会通过轮询所有的副本分片来达到负载均衡。
5. 局部更新文档
从主分片检索文档,修改_source字段中的JSON,重新索引主分片文档;若版本冲突,则重试;如果索引成功,则将完成文档的新版本并行转发到拥有副本分片的节点,重新建立索引;副本分片返回成功,则向协调节点返回成功,协调节点向客户端返回成功。
6. 多文档模式
Mget和bulk API的模式类似于单文档模式,区别在于协调节点知道每个文档存在于哪个分片中;它将整个多文档请求分解成每个分片的多文档请求,并且将这些请求并行转发到每个参与节点。协调节点一旦受到来自每个节点的应答,就将每个节点的响应收集整理成单个响应,返回给客户端。