Elasticsearch笔记

Elasticsearch 7.11.X 笔记
1.1 新部署启动前需设置部分属性参数如文件句柄数进程数等,可通过启动日志WARN字段进行对应修改。

设计优势:
1.采用补充索引以及分段思路解决倒排索引不变性导致的改变的多次IO以及索引重建的消耗;
2.删除操作采用逻辑删除。采用合并机制解决索引积压多以及逻辑删除。
3.准实时原因:主分片延时+副本并行写入延时,需从性能与数据安全角度考虑延时思路
4.通过Translog 进行双写缓冲设计,与Mysql不同的是先入内存再入log,原因是入内存计算复杂,出错的可能性较大,避免log记录出错记录消耗资源。
5.Disk与ES内存中间设计OSCache,将缓存进行二次缓存,提高实时性。

水平扩容:
数据重分配原则:
1.主分片及副本不同机;
2.平衡优先。
3.数据重分配采用Allocation Decider组件进行以下是相关参数:
cluster.routing.allocation.enable: 控制分配器是否允许分配。
cluster.routing.allocation.cluster_concurrent_rebalance: 控制集群并发重分配的分片数。
cluster.routing.allocation.node_concurrent_recoveries: 控制每个节点并发恢复(数据移动)的分片数。
cluster.routing.allocation.node_initial_primaries_recoveries: 控制初始化恢复过程中的主分片并发恢复数。
cluster.routing.allocation.balance.shard: 控制分片平衡的权重。
cluster.routing.allocation.balance.index: 控制索引平衡的权重。
cluster.routing.allocation.balance.threshold: 控制平衡阈值。
故障处理
1.选举算法
ES会在集群中选取一个节点成为主节点,只有Master节点有资格维护全局的集群状态,在有节点加入或者退出集群的时候,它会重新分配分片,并将集群最新状态发送给集群中其它节点,主节点会以周期性ping的方式以验证其它节点是否存活。Elasticsearch的选举算法基于Bully选举算法,简单的说,在bully算法中,每个节点都有一个编号,只有编号最大的存活节点才能成为master节点。

  1. 选举时间点
    选举的时间点有两个
    某个新节点加入了集群或者某个节点从宕机中恢复
    集群中的某个节点检测到leader崩溃
  2. 选举流程
    节点node向所有比自己大的节点发送选举消息(选举为election消息)
    如果节点node得不到任何回复(回复为alive消息),那么节点node成为master,并向所有的其它节点宣布自己是master(宣布为Victory消息)
    如果node得到了任何回复,node节点就一定不是master,同时等待Victory消息,如果等待Victory超时那么重新发起选举
    3.Elasticsearch编号比较的判断依据有两个,首先是ClusterState版本号的比较,版本号越大优先级越高,然后是节点id的比较,id越小优先级越高。ClusterState是Master向集群中各个节点发送的集群状态,这个状态有一个版本号码,如果集群状态发生了变化,比如集群新增了节点成员或者有节点成员退出了,那么这个版本号就会加一,比对这个版本号的目的是让拥有最新状态的节点成为Master的优先级最高。
    问题:
    1.Master假死。解决思路是通知其余成员通报Master状态,如过半鉴定存活即等待,避免重新选举。
    2.脑裂可能,通过参数discovery.zen.minimum_master_nodes 调整数量为过半节点数量。
    数据保存及查询设计
    1.保存数据需保存至主分片,因此需要进行路由,其路由算法是通过hash(id)%分片数
    2.查询路由因有副本,获取主分片及所有副本的机子进行查询负载均衡算法为轮询算法
    3.路径:生产者——》任一节点——》转发至协调节点进行路由计算——》转发至对应主分片节点——》主分片节点保存后通知其余副本节点进行保存—》一路回馈至生产者
    4.查询者——》任一节点——》计算分片及副本位置——》轮询计算路由——》选择查询区域——》回馈
    5.存储参数:consistency参数:all 全保存成功确保强一致性 one只需主分片保存成功确保高可用 quorm过半成功

ES操作
ES严格遵守RESTFul规范设计接口
1.构建客户端

JAVASpringData备注
RestHighLevelClient(RestClient.builder)RestHighLevelClient(RestClient.builder)SpringData需通过ESTemplate注解注入使用

2.索引模块

功能方式参数URLAPI实现
创建索引PUT{“settings”:{“number_of_shards”:3,“number_of_replicas”:1}}${ES_URL}/${indexName}CreateIndexResponse=RestHighLevelClient#indices#create(CreateIndexRequest(${indexname},RequestOptions.DEFAULT))
查询GETURL传参${ES_URL}/${indexName}GetIndexResponse=RestHighLevelClient#indices#get(GetIndexRequest(${indexname},RequestOptions.DEFAULT))
查询所有索引GETUrl传参${ES_URL}/_cat/indices?未研究,具体参数细节待研究
删除索引库DELETEUrl传参${ES_URL}/${indexName}AcknowledgedIndexResponse=RestHighLevelClient#indices#delete(DeleteIndexRequest(${indexname},RequestOptions.DEFAULT))

3.文档模块

功能方式参数URLAPI实现批量操作备注
添加POST{${Field}:${INFO},${Field}:${INFO}}${ES_URL}/${indexName}/_doc/${id} IndexRequest(${indexname}).id(${id}).source(ObjectMapper#writeValueAsString(${data}),XContentType.JSON)IndexResponse=RestHighLevelClient#Index(IndexRequest,RequestOptions.DEFAULT)BulkRequest()#add(IndexRequest[])BulkResponse=RestHighLevelClient#bulk(BulkRequest,RequestOptions.DEFAULT)_doc后衔接为Id值,如不衔接则自动生成
主键查询GETURL传参 ${ES_URL}/${indexName}/_doc/${id}GetRequest(${indexname}).id(${id})GetResponse=RestHighLevelClient#get(GetRequest,RequestOptions.DEFAULT)
全量查询GETURL传参${ES_URL}/${indexName}/_search SearchRequest.indices(${indexname})SearchSourceBuilder.query(QueryBuilders.matchAllQuery) SearchResponse=RestHighLevelClient#search(SearchRequest,RequestOptions.DEFAULT)
3.条件查询:
	(1URL传参查询:GET请求方式 `${ES_URL}/${indexName}/_search?q=${field}:newinfo`2)请求体传参:GET请求方式 `${ES_URL}/${indexName}/_search` 数据格式于请求体 JSON格式为: 
	
		{ 
		   "query":  {
			 "match${method}"{
						"${field}": "${newInfo}"     
			 } 
		},
		   "from":${startNum},
		   "size":${size},
		   "_source":[*]
		   "sort":{
			${field}:{
				"order":asc/desc
			}		
		},
		"highlight":{
			"fields":{
				${field}:{}
			}
			
		}
	}

	注:${method}=_all->全量查询,[字段选择] ,${method}=_phrase->全匹配不采用分词,highlight设置高亮
	(3)条件查询:GET请求方式${ES_URL}/${indexName}/_search 数据格式于请求体 JSON格式为: 
		{ 
		   "query":  {
			"bool":{
				"must/should":[
					 "match"{
							"${field}": "${newInfo}"     
						 } 	
					],
				"filter":{
					"range":{
						${field}:{
							"gt/lt":${number}	
							}
						}
					}
			}
		},
		   "from":${startNum},
		   "size":${size},
		   "_source":[*]
		   "sort":{
			${field}:{
				"order":asc/desc
			}		
		}
	}
		注:bool:{} 条件查询 must:[] AND should:[] OR4)聚合操作:GET请求方式${ES_URL}/${indexName}/_search 数据格式于请求体 JSON格式为: 
		{
			"aggs":{
				 ${aggsName}:{
					"terms(count)/avg(avg)""{
						"field":${field}	
					}
				}
			}"size":0//取消原始数据		
	
		}
SearchRequest.indices(${indexname})
QueryBuilders.termQuery()//字段查询
HightLightQueryBuilder.hightLight().preTages().postTags().field;//高亮查询
QueryBuilders.BoolQuery//条件查询 内部must等方法 QueryBuilder.matchQuery()
QueryBuilder.RangeQuery(${field})//范围查询
QueryBuilder.fuzzyQuery(${field},"").fuzziness()//模糊查询 及误差范围
SearchSourceBuilder.query().from().size().sort(${field},asc/desc).fetchSource();//分页,排序,过滤字段
SearchResponse=RestHighLevelClient#search(SearchRequest,RequestOptions.DEFAULT)
AggregationBuilders.${METHOD}.field(${field})//聚合查询
AggregationBuilders.terms()//分组

更新操作:
1.全量修改:PUT 请求方式 ${ES_URL}/${indexName}/_doc/${id}  数据存储于请求体JSON格式
2.局部修改:POST 请求方式 ${ES_URL}/${indexName}/_update/${id} 数据格式于请求体 JSON格式为 { "doc"{"${field}": "${newInfo}"    }    }
API:
UpdateRequest(${indexname}).id(${id}).doc(XContentType.JSON,${field},${newInfo})
UpdateResponse=RestHighLevelClient#update(UpdateRequest,RequestOptions.DEFAULT)
备注:通过MVCC机制进行并发解决(携带,if_seq_no && if_primary_term)

3.删除:DELETE 请求方式 ${ES_URL}/${indexName}/_doc/${id}  
DeleteRequest(${indexname}).id(${id})
DeleteResponse=RestHighLevelClient#delete(DeleteRequest,RequestOptions.DEFAULT)
BatchCreate:
BulkRequest()#add(DeleteRequest[])
BulkResponse=RestHighLevelClient#bulk(BulkRequest,RequestOptions.DEFAULT)

mappingDoc:
1. 设置字段结构 PUT 请求方式 ${ES_URL}/${indexName}/_mapping 数据存储于请求体JSON格式
	{ "properties":{
		${filed}:{
			"type":"text/keyword",(text可分词查询keyword不可分词查询)
			"index":"true/false"(是否可根据字段查询)
	}
	}
}
分词模块
GET 请求方式${ES_URL}/_analyze 分词 
{"type":"",text:}

扩展词典
IK/config/custom.dic
IKAnalyzer.cfg.xml 配置 <entry key="ext_dict">custom.dic </entry>

自定义分词器:
{
"settings":{
	"analysis":{
		"char_filter":{ //后文中括号内容
			"&_to_and":{
				"type":"mapping""mapping":["&=>and"] //字符修改
				}
			}
		},
	"filter":{
		"my_stopwords":{//后文中括号内容
			"type":"stop",
			"stopwords":["",""] //过滤词汇
			}	
		},
	"analyzer":{
	   "${analyzerName}":{
			type:"custom",//自定义 custom
			char_filter:["html_strip","&_to_and"], 
			tokenizer:"standard",//标准
			filter:["lowercase","my_stopwords"]
		}
	}
}
}

KIBANA集成配置
配置文件:kibana.yml
server.port:对外暴露端口
elasticsearch.hosts:["http://localhost:9200"] //ES服务器地址
kibana.index:索引名
i18.locale:"zh-CN"

集成框架SpringData

1.配置 AbstractElasticserachConfiguration 继承子类 返回JAVA API一致的客户端类
2.Dao层继承ElasticserachRepository接口
3.索引entity @Document @Id @Field
4.字段搜索 
QueryBuilders.termQuery()//字段查询
HightLightQueryBuilder.hightLight().preTages().postTags().field;//高亮查询
QueryBuilders.BoolQuery//条件查询 内部must等方法 QueryBuilder.matchQuery()
QueryBuilder.RangeQuery(${field})//范围查询
QueryBuilder.fuzzyQuery(${field},"").fuzziness()//模糊查询 及误差范围

ES优化部分:
1.1.使用SSD
1.2使用RAID硬盘阵列
1.3多硬盘多path.data
2.1多分片降低匹配度消耗资源
2.2 分片不超过最大JVM设置
2.3 分片不超过节点数3倍
2.4 节点数>=主分片数(副本+1)
3.1推迟分片分配 避免出现瞬时中断导致的无效重分配行为 /_all/_settings { settings:{index.unassigned.node_left.delayed_timeout:5m}}
4.1 路由计算
1.无ID查询 先分发再聚合
2.有ID可分片查询
5.1 加大TranslogFlush 降低Iops、Writeblock。 index.translog.flush_threshold_size
5.2增加IndexRefresh 减少 SegmentMerge 次数
5.3 调整Bulk线程池队列
6.1 Bulk批量插入
6.2大批量数量写如今 先关闭副本 写入完成后修改副本 index.numbers_of_replcate
7.1 JVM 内存不超过50% 尽量不超过32G
8.1
transport.tcp.compress 压缩传输数据
discovery.zen.minimum_master_nodes 最小候选Master节点 默认可能出现脑裂
评分机制
9.1 查询评分详情:GET请求方式 ${ES_URL}/${indexName}/_search?explain=true 数据格式于请求体 JSON格式为:

	{ 
	   "query":  {
		 "match${method}" :{
					"${field}": "${newInfo}"     
		 } 
	}

9.1.2 评分公式 score=boosttfidf
9.2 TF公式 :词频,词条在文本中出现次数
tf=freq/(freq+k1*(1-b+b * dl/avgdl))=freq/(freq+1.2*(1-0.75+0.75*dl/avgdl))
freq:关键词在当前文档中出现次数
k1:默认 1.2
b:默认0.75
dl:分词个数
avgdl:总字段数/文档数
9.3 IDF公式:逆文档频率,词条在所有文档中出现多少次,出现的越多越不相关得分比较底。(普遍性越高越低分)

idf=log(1+(N-n+0.5)/(n+0.5))
n:关键词在所有文档出现总数(${newInfo}N:字段在所有文档出现的文档数量(${field}

9.4 boost:权重值默认2.2
-修改权重 ${“query”:“newInfo”,“boost”:“boostNum”}

10 8.xAPI变动
10.1 需要处理证书
10.2 ClientConnect:

10.2.1

 CredentialsProvider credentialsProvider=new BasicCredentialsProvider()
		=CredentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCreedentials("ESUSERNAME","USERPASSWORD"))
		=Path credentialsProviderPath=Paths.get("证书路径")
		=CertificateFactory factory= CertificateFactory.getInstance(证书算法);
		=Certificate certificate =factory.generateCertificate(Files.newInputStream(credentialsProviderPath=Paths.get));
		=KeyStore trustStore=KeyStore.getInstance(证书算法)
		=》trustStore.load
		=》trustStore.setCertificateEntry("ca",certificate )=SSLContextBuilder sslContextBuilder =SSLContexts.custom().loadTrustMaterial(trustStore);
		=SSLContext sslContext=sslContextBuilder.build();
		=》证书装载结束
		=RestClientBuilder  builder=RestClient.builder(new HttpHost(hostName,port,"https")).setHTTPClientConfigCallback(  HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder   httpAsyncClientBuilder ){return  httpAsyncClientBuilder.setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setDefaultCredentialsProvider( credentialsProvider) })
		=RestClient  restClient=builder.build();
		=ElasticsearchTransport tp=new RestClientTransport(restClient,new JacksonJsonpMapper())
		=ElasticsearchClient=new ElasticsearchClient(tp)

10.3 增查删 INDEX
10.3.1 获取针对索引客户端
=》ElasticsearchIndicesClient=client.indices();
=》各类Request转为构建器模式,不细写
10.4 增改删 DOCUMENT
10.4.1 普通客户端
=》各类Request转为构建器模式,不细写 Entity需实现序列化
=》bulkRequest.operations(List) 批量操作
=》Operation.Builder .build() 批量操作的Entity构建
10.5 查 Document
10.5.1 普通客户端
=》查询条件在构建器链中处理
=》如 Query query=new Query.Builder().match(new MatchQuery.Builder().field().query().build()).build();
10.6 异步客户端
10.6.1 XXX.thenApply() 后续处理
10.6.2 XXX.whenComplete() 回调方法

11 EQL 
11.1 地址 GET ${ES_URL}/${indexName}/_eql/search
11.2 EQL是基于事件机制
11.3 EQL 搜索必须拥有 @timestamp event:{category:"${info}"} 两个字段 
	query : any where XXX==XX (any 时间无关)
	query: sequence by XXX [${category} where zzz==yyy] sequence 统计XXX字段相同并将字段相同的统计在一起 
12 SQL
12.1 POST ${ES_URL}/_sql?format=${type} 

	{"query":"""${SQL} """,
	${DSL}	
	}
	type:
		1.txt:文本格式与命令行查询MySql显示相似
		2.csv:逗号分隔数据
		3.json:JSON格式
		4.tsv:tab分割数据
		5.yaml:yaml格式
	SQL:MySql语法风格相似 举特殊例子
		1.类型转换 "info"::type 类似  CAST(INFO AS TYPE)
		2.RLike: 采用正则
		3.first():第一个
		4.last():最后一个
		5.kuriosis():量化峰值分布
		6MAD()
	DSL:可与DSL组合使用
	.../_sql/translate =>修改为DSL风格
	
	cursor: json风格 存在cursor游标. 在下次查询的时候使用将获取到下一个元素 使用完成后需关闭
	{"cursor":"${cursor}"} 
12.2 可通过DataGrid 操作图形化界面(注意版本是否支持)

13 NLP对接
 13.1下载对应插件"elasticsearch-ingest-opennlp" 该插件需版本一致
 13.2 elasticsearch.yml配置模型
	1.ingest.opennlp.model.file.XX:XX.bin
	2.ingest.opennlp.model.file.YY:YY.bin
	3.ingest.opennlp.model.file.ZZ:ZZ.bin
	...
 13.3 创建支持NLP的预处理管道
	13.3.1 PUT ${ES_URL}/pipeline/${pipelineName} { "description":"XXXx","processors":[{ "opennlp":{"filed":"
${field}"} }]} 
	13.3.2 新增数据使用指定管道 PUT ${ES_URL}/${indexName}/_doc/${id}?pipeline=${pipelineName} {XXXXXXX}
	


  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值