赞
踩
(1)分布式的搜索引擎和数据分析引擎 搜索:百度,网站的站内搜索,IT系统的检索 数据分析:电商网站,最近7天牙膏这种商品销量排名前10的商家有哪些;新闻网站,最近1个月访问量排名前3的新闻版块是哪些 分布式,搜索,数据分析 (2)全文检索,结构化检索,数据分析 全文检索:我想搜索商品名称包含牙膏的商品,select * from products where product_name like "%牙膏%" 结构化检索:我想搜索商品分类为日化用品的商品都有哪些,select * from products where category_id='日化用品' 部分匹配、自动完成、搜索纠错、搜索推荐 数据分析:我们分析每一个商品分类下有多少个商品,select category_id,count(*) from products group by category_id (3)对海量数据进行近实时的处理 分布式:ES自动可以将海量数据分散到多台服务器上去存储和检索 海联数据的处理:分布式以后,就可以采用大量的服务器去存储和检索数据,自然而然就可以实现海量数据的处理了 近实时:检索个数据要花费1小时(这就不要近实时,离线批处理,batch-processing);在秒级别对数据进行搜索和分析 跟分布式/海量数据相反的:lucene,单机应用,只能在单台服务器上使用,最多只能处理单台服务器可以处理的数据量
国外 (1)维基百科,类似百度百科,牙膏,牙膏的维基百科,全文检索,高亮,搜索推荐 (2)The Guardian(国外新闻网站),类似搜狐新闻,用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析,给到每篇新闻文章的作者,让他知道他的文章的公众反馈(好,坏,热门,垃圾,鄙视,崇拜) (3)Stack Overflow(国外的程序异常讨论论坛),IT问题,程序的报错,提交上去,有人会跟你讨论和回答,全文检索,搜索相关问题和答案,程序报错了,就会将报错信息粘贴到里面去,搜索有没有对应的答案 (4)GitHub(开源代码管理),搜索上千亿行代码 (5)电商网站,检索商品 (6)日志数据分析,logstash采集日志,ES进行复杂的数据分析(ELK技术,elasticsearch+logstash+kibana) (7)商品价格监控网站,用户设定某商品的价格阈值,当低于该阈值的时候,发送通知消息给用户,比如说订阅牙膏的监控,如果高露洁牙膏的家庭套装低于50块钱,就通知我,我就去买 (8)BI系统,商业智能,Business Intelligence。比如说有个大型商场集团,BI,分析一下某某区域最近3年的用户消费金额的趋势以及用户群体的组成构成,产出相关的数张报表,**区,最近3年,每年消费金额呈现100%的增长,而且用户群体85%是高级白领,开一个新商场。ES执行数据分析和挖掘,Kibana进行数据可视化 国内 (9)国内:站内搜索(电商,招聘,门户,等等),IT系统搜索(OA,CRM,ERP,等等),数据分析(ES热门的一个使用场景)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
(1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
(2)Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
(3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
(4)数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;Elasticsearch作为传统数据库的一个补充,提供了数据库所不不能提供的很多功能
lucene,最先进、功能最强大的搜索库,直接基于lucene开发,非常复杂,api复杂(实现一些简单的功能,写大量的java代码),需要深入理解原理(各种索引结构)
elasticsearch,基于lucene,隐藏复杂性,提供简单易用的restful api接口、java api接口(还有其他语言的api接口)
(1)分布式的文档存储引擎
(2)分布式的搜索引擎和分析引擎
(3)分布式,支持PB级数据
开箱即用,优秀的默认参数,不需要任何额外设置,完全开源
关于elasticsearch的一个传说,有一个程序员失业了,陪着自己老婆去英国伦敦学习厨师课程。程序员在失业期间想给老婆写一个菜谱搜索引擎,觉得lucene实在太复杂了,
就开发了一个封装了lucene的开源项目,compass。后来程序员找到了工作,是做分布式的高性能项目的,觉得compass不够,就写了elasticsearch,让lucene变成分布式的系统。
(1)Near Realtime(NRT):近实时,两个意思,从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于es执行搜索和分析可以达到秒级 (2)Cluster:集群: 包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常 (3)Node: 节点,集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群 (4)Document&field: 文档,es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。 product document { "product_id": "1", "product_name": "高露洁牙膏", "product_desc": "高效美白", "category_id": "2", "category_name": "日化用品" } (5)Index: 索引,包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。一个index包含很多document,一个index就代表了一类类似的或者相同的document。比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。 (6)Type: 类型,每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field,比如博客系统,有一个索引,可以定义用户数据type,博客数据type,评论数据type。 商品index,里面存放了所有的商品数据,商品document 但是商品分很多种类,每个种类的document的field可能不太一样,比如说电器商品,可能还包含一些诸如售后时间范围这样的特殊field;生鲜商品,还包含一些诸如生鲜保质期之类的特殊field type,日化商品type,电器商品type,生鲜商品type 日化商品type:product_id,product_name,product_desc,category_id,category_name 电器商品type:product_id,product_name,product_desc,category_id,category_name,service_period 生鲜商品type:product_id,product_name,product_desc,category_id,category_name,eat_period 每一个type里面,都会包含一堆document { "product_id": "2", "product_name": "长虹电视机", "product_desc": "4k高清", "category_id": "3", "category_name": "电器", "service_period": "1年" } { "product_id": "3", "product_name": "基围虾", "product_desc": "纯天然,冰岛产", "category_id": "4", "category_name": "生鲜", "eat_period": "7天" } (7)shard ************************************************: 单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行, 提升吞吐量和性能。每个shard都是一个lucene index。 (8)replica ************************************************: 任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失, 多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个), 默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。
Elasticsearch 数据库
-----------------------------------------
Document 行
Type 表 (type将在8.x版本弃用)
Index 库
Elasticsearch是一套分布式的系统,分布式是为了应对大数据量
隐藏了很多复杂的分布式机制:
1.分片机制(我们之前随随便便就将一些document插入到es集群中去了,我们有没有care过数据怎么进行分片的,数据到哪个shard中去)
2.cluster discovery(集群发现机制,我们之前在做那个集群status从yellow转green的实验里,直接启动了第二个es进程,那个进程作为一个node自动就发现了集群,并且加入了进去,还接受了部分数据,replica shard)
3.shard负载均衡(举例,假设现在有3个节点,总共有25个shard要分配到3个节点上去,es会自动进行均匀分配,以保持每个节点的均衡的读写负载请求)
shard副本,请求路由,集群扩容,shard重分配
垂直扩容:采购更强大的服务器, 成本非常高昂,而且会有瓶颈,假设世界上最强大的服务器容量就是10T,但是当你的总数据量达到5000T的时候,你要采购多少台最强大的服务器啊
水平扩容:业界经常采用的方案,采购越来越多的普通服务器,性能比较一般,但是很多普通服务器组织在一起,就能构成强大的计算和存储能力
普通服务器:1T,1万,100万
强大服务器:10T,50万,500万
扩容对应用程序的透明性
保持负载均衡
master节点
(1)创建或删除索引
(2)增加或删除节点
(1)节点对等,每个节点都能接收所有的请求
(2)自动请求路由
(3)响应收集
1.一个index可以包含一个或多个shard
2.每个shard都是一个最小的单元,承载部分数据,底层就是个lucene实例,完整的建立索引和处理请求的能力
3.增减节点时, shard会自动在nodes中负载均衡
4.primary shard和replica shard,每个document肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard中
5.replica shard是primary shard 的副本,负责容错,以及承担读请求负载
6.primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
7.(7.x版本)primary shard的默认数量为1,replica默认是1
8.primary shard是不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard 的 replica shard放在同一个节点上
1.单node环境下,创建一个index,有3个primary shard,3个replica shard
2.集群status是yellow
3.这个时候,会将三个primary shard 分配到仅有的一个node上,另外3个replica shard是无法分配的
4.集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承接任何请求
PUT /test_index
{
"settings":{
"number_of_shards": 3,
"number_of_replicas": 1 ---->每个shard一个replica副本
}
}
1.replica shard分配:3个primary shard,3个replica shard,1node
2.primary-----> replica 同步
3.读请求: primary/replica 两者都可以承接读请求
1.primary&replica自动负载均衡
2.每个node有更少的shard,IO/CPU/Memory资源给每个shard分配更多,每个shard性能更好
3.扩容的极限,6个sahrd(3 primary,3 replica),最多扩容到6台机器,每个shard可以占用单台服务器的所有资源,性能最好
4.超出扩容极限,动态修改replica的数量,9个shard(3primary 6 replica)扩容到9台机器,比3台机器时,拥有3倍的读吞吐量
5.3台机器小,9个shard(3 primary,6 replica)资源更少,但是容错性更好,最多容纳两台机器宕机,6个shard只能容纳1台机器宕机
步骤:
1.9 shard,3node
2.master宕机,自动master选举,red
3.replica容错,新master将replica提升为primary shard,yellow
4.重启宕机node,新master 会 copy relica到该node,使用原有的shard并同步宕机后的修改,green
1._index元数据 (1).代表一个document存在哪个index中 (2).类似的数据放在一个索引,非类似的数据放不同的索引,例: product_index(商品数据) sales_index(销售数据) (3).index中包含吗了很多类似的document (4).索引名称必须是小写的,不能用下划线开头,不能包含逗号 2._type元数据(已过时) (1).代表document属于index中的哪个分类 (2).一个索引通常会划分多个type,逻辑上对index中有些许不同的几类数据进行分类 (3).type名称可以使大小或者小写,但是同时不能用下划线开头,不能包含逗号 3._id元数据 (1).代表document的唯一标识,与index和type一起,可以唯一标识和定位一个document (2).我们可以动手指定document的id,也可以不指定,由es自动为我们创建一个ID 手动指定document的id: 1.根据应用情况来说,是否满足手动指定document id 的前提 如果是导入已有数据(例如从数据库中导入),建议手动指定id 自动生成document的id: 如果是es作为主要存储数据源,那么数据生成后便可以通过es自动来生成id 自动生成的id,长度为20个字符,URL安全,base64编码,GUID,分布式系统并行生成时不可能会发生冲突
1._source元数据: 我们写入的json数据,默认情况下原封不动的在_source结构中响应回来
GET product/_search
{
"query": {
"match": {
"name": "yagao"
}
},
"_source": ["name","desc"]
}
如果写入数据时,document的ID不存在则是新增,存在则是全量替换(es的修改操作其实就是全量替换)
而es做全量替换时,是先将老数据标记为deleted,还并没有物理删除,当内存空间不足时,才会将标记为deleted的数据进行物理删除
强制创建:
PUT test_index/_doc/id/_create
{
"name":"erlv"
}
见图
悲观锁与乐观锁两种并发控制方案 悲观锁:(优点:方便,直接加锁,不需要额外的操作 缺点:并发能力低) 任何情况下,都会对数据上锁,上锁之后,只有持有锁的线程能够操作该条数据,其他线程阻塞,操作完释放锁,此时其他线程读到的一定是最新数据,当然锁的种类有很多,(行锁,表锁,读锁,写锁) 乐观锁:(优点:并发能力高 缺点:代码侵入性高一些) 不加锁,但是每条数据都会有version的概念,两条线程读取同一条数据,版本号皆为 1,但是A线程先修改完数据并将版本号+1,此时B线程提交修改时,发现此时的version已经和他读取数据数据的version不同了,那么B需要重新读取最新数据,再次对数据进行操作,然后再提交 那么ES如何基于_version使用乐观锁进行并发控制的呢? 1.第一次创建document的时候,_version=1,每次对该document做增删改时,version都会+1 2.写入es的数据会由primary shard同步至replica shard中,es内部是多线程异步去改的,那么如果前后两个用户的写入请求乱序了,es内部是会自动把顺序错误的请求抛弃掉,以至于最终修改成功的数据一定是最后发出的请求 (这个用的是version_type=external的方式,这种是可以用外部的版本号来实现乐观锁控制的,每次都请求给出的版本号必须要大于当前_version) PUT test_index/_doc/9?version=5&version_type=external { "name":"tiancheng" } 如果发送的版本号没有大于当前版本号,则报错 { "error": { "root_cause": [ { "type": "version_conflict_engine_exception", "reason": "[9]: version conflict, current version [6] is higher or equal to the one provided [5]", "index_uuid": "nXU59-OnR8afmwK0_b75aw", "shard": "2", "index": "test_index" } ], "type": "version_conflict_engine_exception", "reason": "[9]: version conflict, current version [6] is higher or equal to the one provided [5]", "index_uuid": "nXU59-OnR8afmwK0_b75aw", "shard": "2", "index": "test_index" }, "status": 409 } 在乐观锁成功阻止并发问题之后,尝试正确的完成更新 再次去get 最新的版本号,然后重新发出修改请求携带正确的版本号参数 7.x版本乐观锁实现---------------------------------------------- PUT test_index/_doc/9?if_seq_no=6&if_primary_term=1 { "name":"tiancheng_dzt" } 使用的是seq_no 和 primary_term
什么是partial update? 其实就是传参传局部字段,es实现document数据的局部字段更新,并非之前的全量替换实现数据的修改(这是表象)
但是es内部其实也是生成一个新的document,然后将field进行更新,再将老的document标记为deleted
优点:减少了网络数据传输的开销
POST test_index/_update/9
{
"doc": {
"price": 7891
}
}
es,其实是有个内置的脚本支持的,可以基于grovy脚本实现各种各样的复杂操作
POST test_index/_update/9
{
"script": "ctx._source.nums+=1" -----> 把test_index中的document的id=9的数据的nums字段的值+1
}
Groovy存在内存泄露+安全漏洞问题,,7.x版本使用的是painless脚本
document路由到shard是什么意思? 在es中,1个index会分布在多个shard上,那么当你添加一条数据(也就是document)时,es会将该数据放在index的 哪个shard上呢?这个过程,就称之为document routing,数据路由 路由算法:shard =hash(routing)& number_of_primary_shards 有公式可看出,决定一个document在哪个shard上,最重要的一个值就是routing值,默认是_id,也可以手动指定,相同的routing值,每次过来,从hash函数中产出的hash值一定是相同的,无论hash值是几,无论是什么数字,对number_of_primary_shards求余数,结果一定是在0~number_of_primary_shards-1之间这个范围内的 _id or custom routing value 默认的routing就是id 也可以在发送请求的时候,手动指定一个routing value,比如说put /index/type/id?routing=user_id 手动指定routing value是很有用的,可以保证说,某一类document一定被路由到一个shard上去,那么在后续进行 应用级别的负载均衡,以及提升批量读取的性能的时候,是很有帮助的 primary shard为什么不可变? 就是上述的那样,数据存储到哪个具体的shard上是根据路由算法决定的,同时起到决定性因素的是routingid 和 primary shard的个数,作为同一个数据,如果shard增加了一个后,那么路由算法得出的结果和之前的很可能会不一样,会导致es去错误的shard上取数据,从而也取不到
1. 客户端发送请求至es,会先任意选择一个node,这个node就是coordinating node(协调节点)
2.coordinating node,对document进行路由,将请求转发给对应的 node(有primary shard)(根据2.7所述路由算法转发)
3.实际的node上的primary shard处理请求,然后将数据同步到replica shard
4.coordinating node,如果发现primary shard 和 replica shard都搞定之后,就返回响应给客户端
document的搜索
截止到第2步骤,和增删改的内部处理都是一样的,但是转发到具体shard时,他会两次发到primary shard,两次发到replica shard,均匀的让这两种shard处理所有读请求,以提升吞吐量
1.consistency: one(primary shard) all(all shard) quorum(default) 在发送任何增删改操作时,都可以带上一个consistency参数,指明我们想要的写一致性是什么? post /index/_doc/id?consistency=quorm one:要求写操作,只要有一个primary shard 是active的,就可以执行这个写操作 all:要求写操作,必须所有的primary shard和replica shard都是活跃的,才可以执行这个写操作 quorum: 要求所有的shard中大部分shard是活跃的,int((primary+number_of_replicas) /2 )+1,当number_of_replicas >1 才生效 2.如果节点少于quorum数量,可能导致quorum不齐全,进而导致无法执行任何写操作 但是在es中,只有number_of_replica>1时,quorum才会生效 3.quorum不齐全时,wait,默认1分钟,timeout,100,30s post /index/_doc/id?timeout=30(默认毫秒,可以加单位,例:30s) ,可以自定义超时时间 bulk api的奇特json格式与底层性能优化关系大解密 如果用正常的json格式: 例: { "":"" } 1.bulk中的每个操作都可能要转发到不同node的shard去执行 2.如果采用比较良好的json数组格式 (1). 将json数组解析为JSONArray对象(这个时候在内存中会发生拷贝) (2). 对每个请求中的document进行路由 (3). 为路由到同一个shard上的多个请求,创建一个请求数组 (4). 将这个请求数组序列化 (5). 将序列化后的数据发送到对应的节点上去 3.耗费更多内存,更多的jvm gc开销 如果使用es规定的json格式: {"action":{"":""}}\n 1.直接按照换行符切割json 2.对每两个一组的json,读取meta,进行document路由 3.直接将对应的json发送到node上去 4.不需要将json数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,尽可能的保证性能
当from +size > max_result_window时,es将返回错误 解决方案 1: 1.可以通过设置max_result_window的值来调整es的最大返回记录数(会影响性能,不推荐) [root@dnsserver ~]# curl -XPUT "127.0.0.1:9200/custm/_settings" -d '{ "index" : { "max_result_window" : 50000 } } 解决方案 2: 游标 解决方案 3: search_after (推荐,但不能跳页) GET asset_test1/_search { "query": { "match_all": {} }, "sort": [ { "reportDate": "desc", "id":"desc" } ] } GET asset_test1/_search { "query": { "match_all": {} }, "size": 2, "search_after":[1611100800000,"*001755D30AC84BC449753AA9FBCC0A93E73285A8"], "sort": [ { "reportDate": "desc", "id":"desc" } ] }
1.query String的基础用法
GET asset_test1/_search?q=address:120.202.101.81
GET asset_test1/_search?q=-address:120.202.101.81 field中必须不能包含关键词的数据被搜索出来
GET asset_test1/_search?q=+address:120.202.101.81 field中必须包含关键词的数据被搜索出来
2._all metadata的原理和作用
all元数据,document all fields at index time,支持all fields search
直接可以搜索所有的field,任意一个field包含指定的关键字就可以被搜索出来,
那么难道是对每一个field都进行一次搜索吗?
不是的,利用es中的_all元数据,插入数据时,es会自动将多个field的值全部用字符串的方式串联起来,变成一个长的字符串,作为_all的值,同时建立索引
GET asset_test1/_search?q=120.202.101.81 q后面直接跟字段的值
如果没有设置field的mapping,es会dynamic设置filed的mapping
mapping包含了每个field对应的数据类型,以及如何分词等设置
字符类型 | 说明 |
---|---|
text | ⽤于全⽂索引,搜索时会自动使用分词器进⾏分词再匹配。字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项 |
keyword | 不分词,搜索时需要匹配完整的值 |
整数类型 | 说明 (1byte(字节)=8bit(位、比特)) |
---|---|
byte | (1字节)-128 到127(- 2^7 到 2^7– 1) |
short | (2字节)-32,768到32,767 (- 2^15 到 2^15– 1) |
integer | (4字节)-2,147,483,648到2,147,483,647 (- 2^31 到 2^31– 1) |
long | (8字节)(- 2^63 到 2^63– 1) |
浮点类型 | 说明 |
---|---|
float | 32位单精度IEEE 754浮点类型 |
double | 64位双精度IEEE 754浮点类型 |
half_float | 16位半精度IEEE 754浮点类型 |
scaled_float | 缩放类型的的浮点数(比如价格只需要精确到分,price为57.34的字段缩放因子为100,存起来就是5734) |
日期类型 | 说明 |
---|---|
date |
JSON中没有日期类型,所以在ELasticsearch中,日期类型可以是以下几种:
日期格式的字符串:e.g. “2015-01-01” or “2015/01/01 12:10:30”.
long类型的毫秒数( milliseconds-since-the-epoch)
integer的秒数(seconds-since-the-epoch)
日期纳秒类型 | 说明 |
---|---|
date_nanos |
布尔类型 | 说明 |
---|---|
boolean | true/false |
二进制类型 | 说明 |
---|---|
binary | 该binary类型接受二进制值作为 Base64编码的字符串 |
范围类型 | 说明 |
---|---|
integer_range | 一个带符号的32位整数范围,最小值为,最大值为。 -2^31到 2^31-1 |
float_range | 一系列单精度32位IEEE 754浮点值 |
long_range | 一系列带符号的64位整数,最小值为,最大值为。 -2^63 到 2^63-1 |
double_range | 一系列双精度64位IEEE 754浮点值 |
date_range | 自系统时代以来经过的一系列日期值,表示为无符号的64位整数毫秒 |
ip_range | 支持IPv4或 IPv6(或混合)地址的一系列ip值 |
对象类型 | 说明 |
---|---|
object | 对象,用于单个JSON对象 |
对象类型 | 说明 |
---|---|
array | 嵌套JSON对象数组 |
地理位置数据类型 | 说明 |
---|---|
geo_point | geo_point为纬度/经度点 |
地理形状数据类型 | 说明 |
---|---|
geo_shape | geo_shape映射将geo_json几何对象映射到geo_shape类型,用于多边形等复杂形状 |
专用的数据类型 | 说明 |
---|---|
ip | ip用于IPv4和IPv6地址 |
Completion data type | 提供自动完成建议 |
Token count | 计算字符串中令牌的数量 |
mapper-murmur3 | 在索引时计算值的哈希并将其存储在索引中 |
mapper-annotated-text | annotated-text 索引包含特殊标记的文本(通常用于标识命名实体) |
Percolator | 接受来自query-dsl的查询 |
Join | 为同一索引内的文档定义父/子关系 |
Rank feature | 记录数字功能以提高查询时的点击率 |
Rank features | 记录数字功能以提高查询时的点击率 |
Dense vector | 记录浮点值的密集向量 |
Sparse vector | 记录浮点值的稀疏向量 |
Search-as-you-type | 针对查询进行优化的类文本字段,以实现按需输入完成 |
Alias | 为现有字段定义别名。 |
Flattened | Allows an entire JSON object to be indexed as a single field |
Shape | shape 对于任意笛卡尔几何 |
Histogram | histogram 用于百分位数聚合的预聚合数值。 |
Constant keyword | keyword当所有文档具有相同值时的情况的 专业化。 |
1.exact value
搜索的字段值必须完全相等才能搜索出来
2.full text
(1)缩写 vs 全程:cn vs china
(2)格式转化: like liked likes
(3)大小写: Tom vs tom
(4)同义词: like vs love
可以对值进行拆分后匹配,也可以通过 缩写,时态,大小写,同义词进行匹配
normalization 建立倒排索引的时候,会执行一个操作,也就是说对拆分出的各个单词进行相应的处理,以提升后面搜索的时候能够搜索到相关联的文档的概率
什么是分词器?
filter ,仅仅只是按照搜索条件过滤出需要的数据而已
query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序
一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query,如果你只是想根据一些条件筛选出
一部分数据,不关注其排序,那么用filter
两者性能对比:
filter:不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常用filter的功能
query: 相反,要计算相关度分数,按照分数进行排序,而且无法cache结果
如果对一个string field进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了, 通常解决方案是,将一个string field建立两次索引,一个分词,用来进行搜索,一个不分词,用来排序 我们可以对这个字段创建映射的时候,建两个索引,一个正常的倒排索引,一个正排索引,并且如果想对string字段进行排序,需要将filedata设置为true 例如: { mappings:{ properties:{ "name":"text aa bb", "fields":{ "raw":{ "type":"keyword" } }, "filedata": true } } } 然后排序的时候,就可以用name.row来进行排序,可以看到name的值有可能会被分词,那么name.row就是用整个字段在排序 GET XXX/_search { "query":{ "match_all":{} }, "sort":[ { "name.row": "desc" } ] }
算法介绍:
ES使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法
term frequency:搜索本文中的各个词条在field中出现了多少次,出现次数越多,就越相关
(按搜索内容出现的次数加分)
Inverse document frequency:搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的次数越多,就越不相关
()
Field-length norm:field 长度,field越长,相关度越弱
_score是如何被计算出来的
get /idnex/_search?explain 可以查看评分是如何算出来的
搜索的时候,要依靠倒排索引,排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是doc values在建立索引的时候,一方面会建立倒排索引,以供搜索用;一方面会建立正排索引,也就是
doc values,以供排序,聚合,过滤等操作使用.
doc value 是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高,如果内存不足够,os
会将其写入磁盘上.
面向文档的搜索分析引擎
(1)应用系统的数据结构都是面向对象的,复杂的
(2)对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相当麻烦
(3)ES是面向文档的,文档中存储的数据结构,与面向对象的数据结构是一样的,基于这种文档数据结构,es可以提供复杂的索引,全文检索,分析聚合等功能
(4)es的document用json数据格式来表达
总结一句话: es面向文档,复杂的数据结构可以直接以复杂的形式存进es中
(1)快速检查集群的健康状况
es提供了一套api,叫做cat api,可以查看es中各种各样的数据
green:每个索引的primary shard和replica shard都是active状态的
yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了
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 1488006741 15:12:21 elasticsearch yellow 1 1 1 1 0 0 1 0 - 50.0% epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent 1488007113 15:18:33 elasticsearch green 2 2 2 1 0 0 0 0 - 100.0% epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent 1488007216 15:20:16 elasticsearch yellow 1 1 1 1 0 0 1 0 - 50.0% 如何快速了解集群的健康状况?green、yellow、red? green:每个索引的primary shard和replica shard都是active状态的 yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态 red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了 为什么现在会处于一个yellow状态? 我们现在就一个笔记本电脑,就启动了一个es进程,相当于就只有一个node。现在es中有一个index,就是kibana自己内置建立的index。由于默认的配置是给每个index分配5个primary shard和5个replica shard,而且primary shard和replica shard不能在同一台机器上(为了容错)。现在kibana自己建立的index是1个primary shard和1个replica shard。当前就一个node,所以只有1个primary shard被分配了和启动了,但是一个replica shard没有第二台机器去启动。 做一个小实验:此时只要启动第二个es进程,就会在es集群中有2个node,然后那1个replica shard就会自动分配过去,然后cluster status就会变成green状态。 (2)快速查看集群中有哪些索引 GET /_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open .kibana rUm9n9wMRQCCrRDEhqneBg 1 1 1 0 3.1kb 3.1kb (3)简单的索引操作(7.4.2版本 创建索引默认shard和replica 都是1个) 创建索引:PUT /test_index?pretty health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .monitoring-kibana-7-2021.01.23 c33ZPct_STeNqsZbUQ1qqA 1 0 8638 0 2.5mb 2.5mb yellow open cmdi D0EfxtOMSI2Ok8PQIE1S3g 1 1 2 0 12.7kb 12.7kb 删除索引:DELETE /test_index?pretty health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open .kibana rUm9n9wMRQCCrRDEhqneBg 1 1 1 0 3.1kb 3.1kb
PUT product { "mappings": { "properties": { "desc" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "price" : { "type" : "long" }, "producer" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "tags" : { "type": "text", "fielddata": true } } } }
PUT test1 { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "properties": { "name":{ "type": "text" }, "age":{ "type": "long" }, "address":{ "type":"keyword" } } } }
修改原本已存在的字段的映射是不被允许的,但是新增一个字段的映射是允许的 PUT test_index/_mapping { "properties": { "new_field": { "type": "text" } } } 1.先创建一个新的索引及映射 xxx 2.使用reindex将老索引里的数据迁移至新索引中 POST _reindex { "source": { "index": "product" }, "dest": { "index": "product_new" } }
1)新增商品:新增文档,建立索引
es会自动建立index和type,不需要提前创建,而且es默认会对document每个field都建立倒排索引,让其可以被搜索
PUT /index/type/id { "json数据" } POST /product/_doc/1 { "_index": "ecommerce", "_type": "product", "_id": "1", "_version": 1, (************涉及到es的乐观锁的并发控制策略) "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "created": true } POST /product/_doc/2 { "name" : "jiajieshi yagao", "desc" : "youxiao fangzhu", "price" : 25, "producer" : "jiajieshi producer", "tags": [ "fangzhu" ] } POST /product/_doc/3 { "name" : "zhonghua yagao", "desc" : "caoben zhiwu", "price" : 40, "producer" : "zhonghua producer", "tags": [ "qingxin" ] }
GET /product/_doc/id
DELETE /product/_doc/id
query DSL
DSL: Domain Specifield Language 特定领域的语言
GET product/_search
结果: took:耗费了几毫秒 timed_out:是否超时,这里是没有 _shards:数据拆成了1个分片,所以对于搜索请求,会打到所有的primary shard(或者是它的某个replica shard也可以) hits.total:查询结果的数量,3个document hits.max_score:score的含义,就是document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高 hits.hits:包含了匹配搜索的document的详细数据 { "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "product", "_type" : "_doc", "_id" : "3", "_score" : 1.0, "_source" : { "name" : "zhonghua yagao", "desc" : "caoben zhiwu", "price" : 40, "producer" : "zhonghua producer", "tags" : [ "qingxin" ] } } ] } }
GET product/_search { "query": { "match": { "name": "yagao" } }, "sort": [ { "price": { "order": "desc" } } ], "from": 1, "size": 1 }
GET product/_search
{
"query": {
"match": {
"name": "yagao"
}
},
"_source": ["name","desc"]
}
range 可以放在query里,也可以放在filter里,区别是filter查的话不会计算相关度的评分
如果直接使用filter不用bool的话,可以用constant_score
GET product/_search { "query": { "bool": { "must": [ { "match": { "name": "yagao" } } ], "filter": { "range": { "price": { "gte": 32, "lte": 40 } } } } } } GET /test1/_search { "query": { "constant_score": { "filter": { "term": { "address": "dzt is good" } }, "boost": 1.2 } } }
结果:
通过name搜索值为 “yagao”,文档中本身所有数据的name都包含 “yagao”,所以看见结果每条数据的评分都差不多
但通过 producer搜索 值为 “yagao producer”,可以发现ID为4的数据评分明显最高,因为其匹配程度最高,因为他的
producer字段 能够匹配上搜索条件中的两个词,其他只能匹配到一个
GET product/_search { "query": { "match": { "name": "yagao" } } } "hits" : [ { "_index" : "product", "_type" : "_doc", "_id" : "3", "_score" : 0.105360515, "_source" : { "name" : "zhonghua yagao", "desc" : "caoben zhiwu", "price" : 40, "producer" : "zhonghua producer", "tags" : [ "qingxin" ] } }, { "_index" : "product", "_type" : "_doc", "_id" : "2", "_score" : 0.105360515, "_source" : { "name" : "jiajieshi yagao", "desc" : "youxiao fangzhu", "price" : 25, "producer" : "jiajieshi producer", "tags" : [ "fangzhu" ] } }, { "_index" : "product", "_type" : "_doc", "_id" : "4", "_score" : 0.105360515, "_source" : { "name" : "dzt yagao", "desc" : "dzt fangzhu", "price" : 99, "producer" : "dzt yagao producer", "tags" : [ "meibai" ] } }, { "_index" : "product", "_type" : "_doc", "_id" : "1", "_score" : 0.105360515, "_source" : { "name" : "gaolujie yagao", "desc" : "gaoxiao meibai", "price" : 30, "producer" : "gaolujie producer", "tags" : [ "meibai", "fangzhu" ] } } ] GET product/_search { "query": { "match": { "producer": "yagao producer" } } } "hits" : [ { "_index" : "product", "_type" : "_doc", "_id" : "4", "_score" : 1.1522135, "_source" : { "name" : "dzt yagao", "desc" : "dzt fangzhu", "price" : 99, "producer" : "dzt yagao producer", "tags" : [ "meibai" ] } }, { "_index" : "product", "_type" : "_doc", "_id" : "3", "_score" : 0.110377684, "_source" : { "name" : "zhonghua yagao", "desc" : "caoben zhiwu", "price" : 40, "producer" : "zhonghua producer", "tags" : [ "qingxin" ] } },
GET test_index/_search
{
"query": {
"multi_match": {
"query": "erlv",
"fields": ["name","hobby"]
}
}
}
解释:跟全文检索相反,全文检索会将输入的搜索串拆解开来,去倒排索引里一一匹配,只要匹配上搜索串中任意一个单词,就可以作为结果返回,
而短语搜索要求 输入的搜索串必须完整的存在于结果集的查询字段中,才可以算匹配,可以看到下方只有一个结果匹配上了
GET product/_search { "query": { "match_phrase": { "producer": "yagao producer" } } } 结果: "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 1.1522135, "hits" : [ { "_index" : "product", "_type" : "_doc", "_id" : "4", "_score" : 1.1522135, "_source" : { "name" : "dzt yagao", "desc" : "dzt fangzhu", "price" : 99, "producer" : "dzt yagao producer", "tags" : [ "meibai" ] } } ] }
GET product/_search { "query": { "match": { "producer": "producer" } }, "highlight": { "fields": { "producer": { "pre_tags": "<b style='color:red'>", "post_tags": "</b>" } } } } 还可以在高亮之后的结果继续对某个字段的某个值进行高亮 GET product/_search { "query": { "match": { "producer": "producer" } }, "highlight": { "fields": { "producer": { "pre_tags": "<b style='color:red'>", "post_tags": "</b>", "highlight_query":{ "xxxx":"xxx" } } } } }
terms:多值检索 GET asset_test1/_search { "query": { "bool": { "filter": { "terms": { "address": [ "111.44.212.39", "111.8.210.52" ] } } } } } term:单值检索 GET asset_test1/_search { "query": { "bool": { "filter": { "term": { "address": "111.11.70.13" } } } } }
GET test_index/_validate/query?explain
{
"query": {
"multi_match": {
"query": "erlv",
"fields": ["name","hobby"]
}
}
}
不同索引的批量查询: GET /_mget { "docs": [ { "_index":"test_index", "_id" : "7SZwV3cBOZpjf8ZFfV8Q" }, { "_index":"test_index", "_id" : "XiZwV3cBOZpjf8ZF-mBR" } ] } 同索引的批量查询: GET /test_index/_mget { "ids": ["7SZwV3cBOZpjf8ZFfV8Q","XiZwV3cBOZpjf8ZF-mBR"] } 结果: { "docs" : [ { "_index" : "test_index", "_type" : "_doc", "_id" : "7SZwV3cBOZpjf8ZFfV8Q", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true, "_source" : { "name" : "zhangsan" } }, { "_index" : "test_index", "_type" : "_doc", "_id" : "XiZwV3cBOZpjf8ZF-mBR", "_version" : 4, "_seq_no" : 3, "_primary_term" : 1, "found" : true, "_source" : { "name" : "erlv" } } ] }
3.3.2批量操作->bulk
POST /_bulk {"delete":{"_index":"test_index","_id":"7SZwV3cBOZpjf8ZFfV8Q"}} {"create":{"_index":"test_index","_id":"12"}} {"name":"qqq","price":99} {"index":{"_index":"test_index","_id":"2"}} {"test_field":"replaced test2"} {"update":{"_index":"test_index","_id":"9"}} {"doc":{"test_field2":"bulk test1"}} 发送请求时,每个json整体必须在同一行 bulk操作中,任意一个操作失败是不会影响其他操作的,响应体中会返回错误响应 bulk size 最佳大小 如果太大的话,性能反而会下降,因此需要反复测试一个最佳的bulk size,一般从1000-5000条数据开始,尝试逐步添加, 另外大小的话,最好是在5-15mb
GET /test1/_search
{
"query": {
"fuzzy": {
"name": {
"value": "welcomm",
"fuzziness": 1 #表示对查询的值做几次调整,值不能大于2
}
}
}
}
#默认情况下,如果搜索的内容在es中是存在的那么es就不会推荐内容出来, suggest_mode=missing #建议模式设置为always,代表即便你输入的内容已经在es中存在,还是会把他的相应推荐给推荐出来 #suggest_mode=popular 推荐和我们搜索内容更像的比较常见的 GET test1/_search { "suggest": { "title_suggest": { "text": "welco", "term": { "field": "name", "suggest_mode":"always" } } } }
自动补全的功能对性能的要求比较高,用户每发送输入一个字符就要发送一个请求去查找匹配项,ES采取了不同的数据结构来实现,并不是通过倒排索引来实现的,需要将对应的数据类型设置为 "completion", 所以在将数据索引引进ES之前需要先定义mapping信息 get xxx/_search { "suggest":{ "xxxx_suggest":{ "prefix": "小", "completion":{ "field":"title", "skip_duplicates": true #有时es返回的补全数据可能会有重复的,此配置设置为true,去重 } } } }
(bool复合查询,must里面套should) GET /infomation/_search { "query": { "bool": { "must": [ { "bool": { "should": [ { "match_phrase": { "content": "奥特曼" } }, { "match_phrase": { "label": "奥特曼" } }, { "match_phrase": { "title": "奥特曼" } } ] } } ], "filter": { "term": { "status": 0 } } } } }
#tags为数组,那么需要该字段的filedata=true才可以通过该字段进行聚合分析 GET product/_search { "size": 0, "aggs": { "tag_proCount": { "terms": { "field": "tags" } } } } 结果: "aggregations" : { "tag_proCount" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "fangzhu", "doc_count" : 2 }, { "key" : "meibai", "doc_count" : 2 }, { "key" : "qingxin", "doc_count" : 1 } ] } }
GET product/_search { "size": 0, "aggs": { "tag_proCount": { "terms": { "field": "tags", "order": { "avg_price": "desc" } }, "aggs": { "avg_price": { "avg": { "field": "price" } } } } } } 结果: "aggregations" : { "tag_proCount" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "meibai", "doc_count" : 2, "avg_price" : { "value" : 64.5 } }, { "key" : "qingxin", "doc_count" : 1, "avg_price" : { "value" : 40.0 } }, { "key" : "fangzhu", "doc_count" : 2, "avg_price" : { "value" : 27.5 } } ] } }
GET product/_search { "size": 0, "aggs": { "range_price": { "range": { "field": "price", "ranges": [ { "from": 0, "to": 30 }, { "from": 30, "to": 40 }, { "from": 40, "to": 100 } ] }, "aggs": { "groupby_tags": { "terms": { "field": "tags" }, "aggs": { "avg_price": { "avg": { "field": "price" } } } } } } } }
##################大屏态势感知######################## GET asset_test1/_search { "size": 0 } #大屏资产安全监测 GET asset_test1/_search GET asset_test1/_search { "size": 0, "query": { "match_all": {} }, "aggs": { "level_normal": { "filter": { "term": { "cntLoophole": 0 } } }, "level_high":{ "filter": { "nested": { "path": "cveEsModelList", "query": { "term": { "cveEsModelList.serverity": { "value": "高" } } } } } }, "level_medium":{ "filter": { "nested": { "path": "cveEsModelList", "query": { "bool": { "must_not": [ { "term": { "cveEsModelList.serverity": { "value": "高" } } } ], "should": [ { "term": { "cveEsModelList.serverity": { "value": "中" } } }, { "term": { "cveEsModelList.serverity": { "value": "低" } } } ] } } } } } } } #上报资产/稽核资产/总资产数 统计 GET asset_test1/_search { "size": 0, "query": { "match": { "status": 1 } }, "aggs": { "assetByReported": { "filter": { "term": { "source": 3 } } }, "assetNum": { "cardinality": { "field": "id" } }, "assetByAudit":{ "filter": { "term": { "source": 1 } } } } } #上报/稽核资产近一年折线图 GET /asset_test1/_search { "size": 0, "query": { "bool": { "must": [ { "range": { "reportDate": { "gte": "2020-01-01", "lte": "2020-12-31" } } } ] } }, "aggs": { "all_report": { "filter": { "term": { "source": 3 } }, "aggs": { "reportAmountList": { "date_histogram": { "field": "reportDate", "calendar_interval": "month", "format": "yyyy-MM-dd", "min_doc_count": 0, "extended_bounds": { "min": "2020-01-01", "max": "2020-12-31" } } } } }, "all_audit":{ "filter": { "term": { "source": 1 } }, "aggs":{ "auditAmuountList": { "date_histogram": { "field": "reportDate", "calendar_interval": "month", "format": "yyyy-MM-dd", "min_doc_count": 0, "extended_bounds": { "min": "2020-01-01", "max": "2020-12-31" } } } } } } }
#查询年龄最大的两位员工的信息 GET employee/_search { "size": 0, "aggs":{ "order_agg":{ "top_hits":{ "size": 2, "sort":[ { "age":{ "order":"desc" } } ] } } } } #查询不同工资区间的员工工资的统计信息 GET /test1/_search { "size": 0, "aggs": { "range_sal_agg": { "range": { "field": "sal", "ranges": [ { "key": "0 <= sal <10001", "to": 10001 }, { "key": "10001 <= sal 20001", "from": 10001, "to": 20001 } ] } } } } #以直方图的方式以每5000元为一个区间查询员工工资信息 GET /test1/_search { "size": 0, "aggs": { "range_sal_agg": { "histogram": { "field": "price", "interval": 5000, "extended_bounds": { #设置区间的最大最小值 "min": 0, "max": 50000 } } } } } #查询平均工资最低的工种 GET /test1/_search { "size": 0, "aggs": { "range_sal_agg": { "terms": { "field": "gongzhong" }, "aggs": { "avg_agg": { "avg": { "field": "sal" } } } }, "min_avg_sal":{ "min_bucket": { "buckets_path": "range_sal_agg>avg_agg" #得出range_sal_agg>avg_agg聚合结果汇总值最小的桶 } } } }
#################资产检索实现深度分页########################################## GET asset_test1/_search { "query": { "match_all": {} }, "sort": [ { "reportDate": "desc", "id":"desc" } ] } GET asset_test1/_search { "query": { "match_all": {} }, "size": 2, "search_after":[1611100800000,"*001755D30AC84BC449753AA9FBCC0A93E73285A8"], "sort": [ { "reportDate": "desc", "id":"desc" } ] }
启动命令:
242
docker run -d --name es01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx128m" -v /opt/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /opt/es/data:/usr/share/elasticsearch/data -v /opt/es/plugins:/usr/share/elasticsearch/plugins --restart=always elasticsearch:7.4.2
243 231
docker run -d --name es01 -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms4g -Xmx4g" -v /opt/nssa/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /opt/nssa/es/data:/usr/share/elasticsearch/data -v /opt/nssa/es/plugins:/usr/share/elasticsearch/plugins --restart=always elasticsearch:7.4.2
报错:
bound or publishing to a non-loopback or non-link-local address, enforcing bootstrap checks ERROR: [2] bootstrap checks failed**
切换到root用户修改配置sysctl.conf
vi /etc/sysctl.conf
添加配置:
vm.max_map_count=655360
执行命令:
sysctl -p
yml文件说明:
参数 | 说明 |
---|---|
cluster.name | 集群名称,相同名称为一个集群 |
node.name | 节点名称,集群模式下每个节点名称唯一 |
node.master | 当前节点是否可以被选举为master节点,是:true、否:false |
node.data | 当前节点是否用于存储数据,是:true、否:false |
path.data | 索引数据存放的位置 |
path.logs | 日志文件存放的位置 |
bootstrap.memory_lock | 需求锁住物理内存,是:true、否:false |
bootstrap.system_call_filter | SecComp检测,是:true、否:false |
network.host | 监听地址,用于访问该es |
network.publish_host | 可设置成内网ip,用于集群内各机器间通信 |
http.port | es对外提供的http端口,默认 9200 |
discovery.seed_hosts | es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点 |
cluster.initial_master_nodes | es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master |
http.cors.enabled | 是否支持跨域,是:true,在使用head插件时需要此配置 |
http.cors.allow-origin | “*” 表示支持所有域名 |
配置文件:
cluster.name: nssa_elasticsearch
node.name: es243
network.bind_host: 0.0.0.0
network.publish_host: 192.168.182.243
http.port: 9200
transport.tcp.port: 9300
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: false
node.data: true
discovery.seed_hosts: ["192.168.182.242:9300","192.168.182.243:9300","192.168.182.231:9300"]
cluster.initial_master_nodes: ["192.168.182.242:9300"]
安装kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.124.15:9200 -p 5601:5601 -d kibana:7.4.2
安装logstash
1.配置文件 (新建文件 /xxx/logstash.conf )
input { tcp { mode => "server" host => "0.0.0.0" # 接收服务发送过来的日志端口,随意改,别重复就好 port => 5000 codec => json_lines } } output { elasticsearch { # 自己es装的地方 hosts => ["192.168.182.243:9200"] action => "index" # 索引 kibana创建索引时使用,根据自己心情来,最好有意义,我是我的网站服务名log+时间节点 index => "dscnlog-%{+YYYY.MM.dd}" } stdout { codec => rubydebug } }
启动命令
docker run --name logstash -p 5000:5000 \
-v /data/logstash/logstash.conf:/etc/logstash.conf \
--link es01:elasticsearch \
-d logstash:7.4.2 \
logstash -f /etc/logstash.conf
微服务中
<!-- 日志集中管理 --> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>5.2</version> </dependency> 创建logback.xml <?xml version="1.0" encoding="UTF-8"?> <configuration debug="false" scan="true" scanPeriod="1 seconds"> <!-- 作用域就是spring的上下文环境中,后面是服务名,defaultValue不填就可以了,之后就是打印对应的服务名 --> <springProperty scope="context" name="applicationName" source="spring.application.name" defaultValue=""/> <include resource="org/springframework/boot/logging/logback/base.xml" /> <appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <!-- logstash远程主机 --> <destination>192.168.182.243:5000</destination> <!-- encoder必须配置,有多种可选 --> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" /> </appender> <!-- 日志输出级别 --> <root level="info"> <appender-ref ref="stash" /> </root> </configuration>
在kibana中创建index patterns(索引模式)
初步检索
1._cat
GET /_cat/nodes; 查看所有节点
GET /_cat/health; 查看es健康状况
GET /_cat/master;查看主节点
GET /_cat/indlices; 查看所有索引 ==== show databases;
PUT infomation { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "status":{ "type":"integer" }, "label":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "publish": { "type": "date", "format": [ "yyyy-MM-dd" ] } } } } #研报 PUT report { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "status":{ "type":"integer" }, "label":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "publish": { "type": "date", "format": [ "yyyy-MM-dd" ] } } } } #视频 PUT media { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "mediaStatus":{ "type":"integer" }, "label":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "publish": { "type": "date", "format": [ "yyyy-MM-dd HH:mm:ss" ] }, "image":{ "type":"keyword" }, "category":{ "type": "integer" }, "startTime":{ "type": "date", "format": [ "yyyy-MM-dd HH:mm:ss" ] }, "vid":{ "type": "keyword" } } } }
temp
GET _search { "query": { "match_all": {} } } PUT demo1 { "mappings": { "properties": { "name":{ "type": "text" } } } } PUT demo1/_doc/1 { "name":"zhangsan" } GET demo1/_search PUT /test { "mappings": { "properties": { "title":{"type": "text"}, "name":{"type": "text"}, "age":{"type": "integer"}, "created":{ "type": "date", "format": "strict_date_optional_time||epoch_millis" } } }, "settings": { "index":{ "number_of_shards":1, "number_of_replicas":0 } } } PUT /test/_doc/5 { "name":"zw", "title":"张五", "age":28, "created":"2020-11-01" } GET test/_search PUT infomation { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "status":{ "type":"integer" }, "label":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "publish": { "type": "date", "format": [ "yyyy-MM-dd" ] } } } } #研报 PUT report { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "status":{ "type":"integer" }, "label":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "publish": { "type": "date", "format": [ "yyyy-MM-dd" ] } } } } #视频 PUT media { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "mediaStatus":{ "type":"integer" }, "label":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "publish": { "type": "date", "format": [ "yyyy-MM-dd HH:mm:ss" ] }, "image":{ "type":"keyword" }, "category":{ "type": "integer" }, "startTime":{ "type": "date", "format": [ "yyyy-MM-dd HH:mm:ss" ] }, "vid":{ "type": "keyword" } } } } POST /infomation/_doc/888 { "id": "888", "title":"疫情反弹持续引发担忧 成品油价23日下跌,来了", "content": "奥特曼", "status": 0, "label":"sad", "publish":"2020-06-24" } POST /infomation/_doc/77711 { "id": "77711", "title":"新冠疫情反弹持续引发担忧 国际油价23日下跌", "status": 0, "label":"奥特曼", "content": "天成集团", "publish":"2020-06-24" } GET /infomation/_search { "query": { "multi_match": { "query": "奥特曼", "fields": ["title","content","label"] } }, "track_total_hits": true } #研报 POST /report/_doc/gdfterte { "id": "gdfterte", "title":"研报天然气下跌亏损 国际油价23日下跌", "status": 0, "label":"aaaa", "content": "奥特曼", "publish":"2020-06-24" } GET /report/_search { "query": { "multi_match": { "query": "奥特曼", "fields": ["title","content","label"] } }, "track_total_hits": true } ##视频 POST /media/_doc/56756875 { "id": "56756875", "title":"视频天然气下跌亏损 国际油价23日下跌奥特曼", "status": 1, "label":"dsfs", "content": "aaa", "publish":"2020-06-24 18:17:17", "image":"dsadasdasdasdad", "category":2, "startTime": "2021-01-01 19:19:19", "vid": "342423", "mediaStatus": 1 } GET /report/_search { "query": { "multi_match": { "query": "奥特曼", "fields": ["title","content","label"] } }, "track_total_hits": true } GET /infomation/_search GET /report/_search GET /media/_search DELETE /infomation DELETE /report DELETE /media PUT _cluster/settings { "persistent": { "indices": { "breaker": { "fielddata.limit": "60%" } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。