Elasticsearch系列---简单入门实战
概要
本篇主要介绍一下Elasticsearch Document的数据格式,在Java应用程序、关系型数据库建模的对比,介绍在Kibana平台编写Restful API完成基本的集群状态查询,Document最基本CRUD操作示例以及bulk批处理示例。
Document数据格式
Java应用系统的数据模型都是面向对象的,有些对象比较复杂,传统的业务系统,数据需要落地到关系型数据库,在数据库领域模型设计时,会把复杂的POJO对象设计成一对一或一对多的关系,进行扁平化处理,查询的时候,需要多表查询并还原回POJO对象的格式。
Elasticsearch是文档数据库,Document存储的数据结构,可以和POJO保持一致,并且使用JSON格式,这样查询数据时比较方便。
Document文档数据示例:
{
"fullname" : "Three Zhang",
"text" : "hello elasticsearch",
"org": {
"name": "development",
"desc": "all member are lovely"
}
}
Restful API让请求更容易
前面文章有提及Elasticsearch与Kibana搭配使用,Kibana界面的Dev Tools菜单,可以发送Elasticsearch的Restful请求。后续的Restful API请求,如无例外,均是在Kibana平台上执行的。
我们先拿几个查询集群信息的请求来试试
- 检查集群的健康状况
GET /_cat/health?v
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1573626290 14:24:50 hy-application yellow 1 1 1 1 0 0 1 0 - 50.3%
从上面能看出node、shard的数量等,还有一个是集群的状态,上面显示的是yellow,为什么是yellow?
集群的状态有green、yellow、red三种,定义如下:
- green:每个索引的primary shard和replica shard都是active状态的
- yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
- red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了
我们的示例只启动了一个elasticsearch实例,只有一个node,由于索引默认会使用5个primary shard和5个replica shard,并且同一个node下面的primary shard和replica shard不能分配在一台机器上(容错机制),所有只有1个primary shard被分配和启动了,replica shard没有第二台node去启动,因而是yellow状态。如果想变成green判断,另外启一台node即可。
- 查看集群中有哪些索引
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open location 48G_CgE7TiWomlYsyQW1NQ 5 1 3 0 11kb 11kb
yellow open company_mem s9DKUeyWTdCj2J8BaFYXRQ 5 1 3 0 15kb 15kb
yellow open %{[appname]} ysT9_OibR5eSRu19olrq_w 5 1 32 0 386.5kb 386.5kb
yellow open .kibana 4yS67TTOQGOD7l-uMtICOg 1 0 2 0 12kb 12kb
yellow open tvs EM-SvQdfSaGAXUADmDFHVg 5 1 8 0 16.3kb 16.3kb
yellow open company_org wIOqfx5hScavO13vvyucMg 5 1 3 0 14.6kb 14.6kb
yellow open blog n5xmcGSbSamYphzI_LVSYQ 5 1 1 0 4.9kb 4.9kb
yellow open website 5zZZB3cbRkywC-iTLCYUNg 5 1 12 0 18.2kb 18.2kb
yellow open files _6E1d7BLQmy9-7gJptVp7A 5 1 2 0 7.3kb 7.3kb
yellow open files-lock XD7LFToWSKe_6f1EvLNoFw 5 1 1 0 8kb 8kb
yellow open music i1RxpIdjRneNA7NfLjB32g 5 1 3 0 15.1kb 15.1kb
yellow open book_shop 1CrHN1WmSnuvzkfbVCuOZQ 5 1 4 0 18.1kb 18.1kb
yellow open avs BCS2qgfFT_GqO33gajcg_Q 5 1 0 0 1.2kb 1.2kb
- 查看node信息
GET /_cat/nodes?v
响应:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.17.137 38 68 0 0.08 0.03 0.05 mdi * node-1
我们可以看到node的名称。
- 创建索引命令
创建名称为"location"的索引
PUT /location?pretty
响应:
{
"acknowledged": true,
"shards_acknowledged": true
}
查看索引,能看到刚刚创建的索引location
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open location 48G_CgE7TiWomlYsyQW1NQ 5 1 3 0 11kb 11kb
yellow open .kibana 4yS67TTOQGOD7l-uMtICOg 1 0 2 0 12kb 12kb
- 删除索引命令
删除名称为"location"的索引
DELETE /location?pretty
再查看索引,刚刚创建的索引location已经删除掉了
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open .kibana 4yS67TTOQGOD7l-uMtICOg 1 0 2 0 12kb 12kb
是不是很简单,交互界面挺友好吧?
入门CRUD操作
介绍document最基本的CRUD操作,以儿童英文歌曲为背景
- 新增歌曲
我们设计的儿歌结构包含四个字段:歌名name,歌词content,语言种类language,歌曲时间长length,单位是秒,放在JSON字符串里。
PUT语法:
<REST Verb> /<Index>/<Type>/<ID>
REST Verbs可以是PUT、POST、DELETE,后斜杠后的内容分别是索引名、类型名、ID。
请求如下:
PUT /music/children/1
{
"name": "gymbo",
"content": "I hava a friend who loves smile, gymbo is his name",
"language": "english",
"length": "75"
}
响应内容包含索引名、类型名、ID值,version版本号(乐观锁控制),结果类型(created/updated/deleted三种),shard信息等,如果新增时该索引不存在,会自动创建索引,索引名即请求时指定的那个,document里面的field类型,就根据elasticsearch定义的自动映射类型,并且每个field都会建立倒排索引,让其可以被搜索到。
total和successful为什么数据不相等?
新增document时,会往primary shard和replica shard分别写入document,但由于只有一个node,replica未启动,所以总共写入2次,primary shard成功,数量是1。failed只记录primary shard写入失败的情况。
响应如下:
{
"_index": "music",
"_type": "children",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
- 修改歌曲
修改document有两种方式,一种是增量修改,只修改指定的field,另一种是全量替换文档,原有的信息全部被替换掉
- 增量修改length的值,注意是POST请求,并且尾部有_update,doc是固定写法,请求如下:
POST /music/children/1/_update
{
"doc": {
"length": "76"
}
}
响应:
{
"_index": "music",
"_type": "children",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
- 全量替换文档,请求如下:
PUT /music/children/1
{
"name": "gymbo",
"content": "I hava a friend who loves smile, gymbo is his name",
"language": "english",
"length": "77"
}
响应:
{
"_index": "music",
"_type": "children",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
细心的童鞋可以,全量替换文档的语法和创建索引是一样的,对!就是同一个语法 ,是创建还是更新取决于上面的ID存不存在,不存在做创建,存在做更新,更新成功version+1,但这种全量替换有个不好的地方,必须带上完整的属性,否则未声明属性就没有了。
想想要使用这个语法的场景:先GET所有的属性,然后把要更新的属性更新上,再调用全量替换的更新语法。实际上这种做法不多,原因不外乎两个:操作复杂,要先查询后更新;报文过大(相对于增量更新)。所以企业研发一般使用增量方式做document更新。
- 查询歌曲
查询语句:GET /music/children/1
_source即为JSON的内容,查询结果:
{
"_index": "music",
"_type": "children",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"name": "gymbo",
"content": "I hava a friend who loves smile, gymbo is his name",
"language": "english",
"length": "75"
}
}
- 删除歌曲
删除语句:DELETE /music/children/1
响应结果:
{
"_index": "music",
"_type": "children",
"_id": "1",
"_version": 4,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
bulk批处理
上一节提及的增删改操作,是针对单个document的,Elasticsearch还有一个批处理命令,可以批量执行这些操作。
- bulk的基本语法示例
还是以上面的儿歌为案例背景
POST /music/children/_bulk
{"index":{"_id":"1"}}
{"name": "gymbo", "content": "I hava a friend who loves smile, gymbo is his name", "language": "english", "length": "75"}
{"create":{"_id":"2"}}
{"name": "wake me, shark me", "content": "don't let me sleep too late", "language": "english", "length": "55"}
{ "update": {"_id": "2", "retry_on_conflict" : 3} }
{ "doc" : {"content" : "don't let me sleep too late, gonna get up brightly early in the morning"} }
{ "delete": {"_id": "3" }}
可以把多条命令放在一起执行,如果一个bulk请求内有不同的index和type,可以把index和type也可以写在body json里,每一个操作要两个json串:
{"action": {"metadata"}}
{"data"}
delete例外,它只需要1个json串就可以了
action的类型有以下几种:
- index:普通的PUT操作,ID不存在时创建document,ID存在时做全量替换
- create:强制创建,等同于PUT /index/type/id/_create命令
- update:执行的增量修改操作
- delete:删除document操作
bulk注意事项
bulk api有严格的语法要求,每个json串内不能换行,同时每个json串之间必须要有一个换行,否则会报语法错误。
bulk既然是多条命令批量执行,遇到错误怎么办?会中断吗?
如果bulk请求内有命令执行错误,会直接跳过,继续执行下一条,同时在响应报文里会对每条命令的结果分别展示,正确的就展示正确的结果,错误的会相应提示错误日志。bulk的性能问题
bulk既然是批处理,那bulk size与最佳性能肯定存在一定的联系,bulk请求的内存会先加载到内存里,bulk的请求取决于命令的条数和每个命令内容的多少,与性能的关系示例图(表达概念,数据不具备参考性)如下:
bulk性能优化的目标就是找到这个拐点,需要反复尝试一个最佳的size,跟具体的业务数据特性,并发量有关,常见的设置范围一般是1000-5000之间,bulk请求的大小控制在5-15MB之间(仅供参考)。
小结
本篇简单介绍了一下document的数据格式,并顺带讲解了一下Elasticsearch集群红黄绿三种状态的判定标准,重点是在kibana平台演示的CRUD小案例和bulk批处理示例,最为基础,可以多花一些时间熟悉熟悉。
专注Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区
Elasticsearch系列---简单入门实战的更多相关文章
- ElasticSearch搜索引擎的入门实战
1.ElasticSearch简介 引用自百度百科: ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elas ...
- 1. VIM 系列 - 简单入门,拾起兴趣
目录 1. 认识模式 1.1 正常模式 1.2 插入模式 1.3 命令模式 1.4 可视模式 2. 常用快捷键 1. 认识模式 vim 一共有四种模: 1. 正常模式 2. 插入模式 3. 命令模式 ...
- Elasticsearch系列(一)--入门
Elasticsearch基于Lucene构建的开源搜索引擎,Java编写,提供restful API,支持横向拓展,能够完成海量数据处理. 应用场景: 1.海量数据分析引擎 2.站内搜索引擎 3.数 ...
- Elasticsearch系列---补充几个知识点
概要 bulk api有趣的json格式 前面<简单入门实战>一节中,有介绍bulk的使用示例,大家一定很奇怪,还有这么有趣的JSON格式,必须严格照他的换行来做,我想把JSON搞得美观可 ...
- 初学者都能学会的ElasticSearch入门实战
大家好,我是咔咔 不期速成,日拱一卒 项目中准备使用ElasticSearch,之前只是对ElasticSearch有过简单的了解没有系统的学习,本系列文章将从基础的学习再到深入的使用. 咔咔之前写了 ...
- Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...
- Spark入门实战系列--1.Spark及其生态圈简介
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .简介 1.1 Spark简介 年6月进入Apache成为孵化项目,8个月后成为Apache ...
- Spark入门实战系列--4.Spark运行架构
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1. Spark运行架构 1.1 术语定义 lApplication:Spark Appli ...
- Spark入门实战系列--5.Hive(上)--Hive介绍及部署
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Hive介绍 1.1 Hive介绍 月开源的一个数据仓库框架,提供了类似于SQL语法的HQ ...
随机推荐
- json::rapidjson工具
源码地址: https://github.com/Tencent/rapidjson 可跨平台使用.将 rapidjson-master\include\rapidjson 中的 rapidjson ...
- Arduino学习笔记④ 经典按键实验
1.前言 我们讲了数字IO口介绍以及做了流水灯演示(主要用到IO口的输出功能),这节课我们讲解一下IO口的输入功能,说到输入功能,最经典的例子莫过于按键实验.废话少说,赶紧上车. 2.实验材料 ...
- 百万年薪python之路 -- HTML基础
一. Web标准 web标准: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web标准规范的分类:结构标准.表现标准.行为标准. 结构:html.表示:c ...
- Linux命令比较文件内容
文件准备 创建两个文件,分别为a.txt和b.txt,它们所含内容分别为: a.txt b.txt 1-wfhune2-chdamnsbchj3-uyr92fiubkqw5-cgvdnsb 2-djy ...
- 【构建工具】《Maven实战》读书笔记
Maven是我们在做Java开发过程中用经常用到的一个辅助工具.本篇博客是我学习Maven的一个记录博客,学习过程主要参考<Maven实战>这本书.同时也参考了Maven的官方文档. 1. ...
- Java多线程编程(六)单例模式与多线程
在使用多线程技术的单例模式时会出现一些意想不到的情况,这样的代码如果在生产环境中出现异常,有可能造成灾难性的后果. 一.立即加载/“饿汉模式” 立即加载就是使用类的时候已经将对象创建完毕,常见的实现方 ...
- vuex状态管理详细使用方法
1安装:vue ui或cnpm install vuex 2/使用import vuex from 'vuex' vue.use(vuex) var store = new Vuex.store({ ...
- php+js实现一个简单的用户管理系统
php + js 实现一个简单的用户管理系统 说实话,我对PHP是抵触的,但是我们的WEB课程刚好学的就是这个,不得已看了看,下面是用PHP实现的一个简单的用户管理系统. 我们首先来看一下目录结构 a ...
- kaldi中CD-DNN-HMM网络参数更新公式手写推导
在基于DNN-HMM的语音识别中,DNN的作用跟GMM是一样的,即它是取代GMM的,具体作用是算特征值对每个三音素状态的概率,算出来哪个最大这个特征值就对应哪个状态.只不过以前是用GMM算的,现在用D ...
- app消息推送
Mui + 个推 实现消息推送 1.首先去个推 注册一个账号,新建一个消息推送应用 2.配置Mui配置文件 3.使用HBuilder 打包 app 4.然后在到个推后台 发送数据 后台Java代码(官 ...