本篇主要介绍一下Elasticsearch Document的数据格式,在Java应用程序、关系型数据库建模的对比,介绍在Kibana平台编写Restful API完成基本的集群状态查询,Document最基本CRUD操做示例以及bulk批处理示例。java
Java应用系统的数据模型都是面向对象的,有些对象比较复杂,传统的业务系统,数据须要落地到关系型数据库,在数据库领域模型设计时,会把复杂的POJO对象设计成一对一或一对多的关系,进行扁平化处理,查询的时候,须要多表查询并还原回POJO对象的格式。
Elasticsearch是文档数据库,Document存储的数据结构,能够和POJO保持一致,而且使用JSON格式,这样查询数据时比较方便。node
Document文档数据示例:web
{ "fullname" : "Three Zhang", "text" : "hello elasticsearch", "org": { "name": "development", "desc": "all member are lovely" } }
前面文章有说起Elasticsearch与Kibana搭配使用,Kibana界面的Dev Tools菜单,能够发送Elasticsearch的Restful请求。后续的Restful API请求,如无例外,均是在Kibana平台上执行的。数据库
咱们先拿几个查询集群信息的请求来试试json
GET /_cat/health?v
api
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三种,定义以下:性能优化
咱们的示例只启动了一个elasticsearch实例,只有一个node,因为索引默认会使用5个primary shard和5个replica shard,而且同一个node下面的primary shard和replica shard不能分配在一台机器上(容错机制),全部只有1个primary shard被分配和启动了,replica shard没有第二台node去启动,于是是yellow状态。若是想变成green判断,另外启一台node便可。restful
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
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
是否是很简单,交互界面挺友好吧?
介绍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 }
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 }
上一节说起的增删改操做,是针对单个document的,Elasticsearch还有一个批处理命令,能够批量执行这些操做。
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的类型有如下几种:
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架构社区