Elasticsearch 为什么能做到快速检索?

举报
张谱继 发表于 2025/01/15 12:01:20 2025/01/15
469 0 0
【摘要】 倒排索引:文档 doc ——>关键词 term建立关键词的文档索引,term ——> postings list, 对postings list(整数数组) 做 FOR:Frame of Reference 压缩,增量编码——>block分区——> 对每个block做位压缩建立term的字典,term dictionary ——> term,term dictionary在磁盘上分block...

倒排索引:

文档 doc ——>关键词 term

建立关键词的文档索引,term ——> postings list, 对postings list(整数数组) 做 FOR:Frame of Reference 压缩,增量编码——>block分区——> 对每个block做位压缩

建立term的字典,term dictionary ——> term,term dictionary在磁盘上分block,一个block内利公共前缀压缩

字典过大,继续建索引,term index ——> term dictionary 。index 是Trie树,字典树(在内存中存储是FST数据结构,Finite State Transducers),通过对term的公共前缀,构建Trie树,快速找到 term dictionary的offset,在做顺序查找。

学习:ElasticSearch (ES从入门到精通一篇就够了):https://www.cnblogs.com/buchizicai/p/17093719.html


Elasticsearch 的索引思路

将磁盘里的东西尽量搬进内存,减少磁盘随机读取次数 (同时也利用磁盘顺序读特性),结合各种压缩算法,用及其苛刻的态度使用内存。

最后说一下,技术选型永远伴随着业务场景的考量,每种数据库都有自己要解决的问题(或者说擅长的领域),对应的就有自己的数据结构,而不同的使用场景和数据结构,需要用不同的索引,才能起到最大化加快查询的目的。

参考:https://cloud.tencent.com/developer/article/1922613


本地使用流程

到Elasticsearch官网下载Zip包,本地cmd或powerShell(可以看报错信息)运行,

  1. es的 bin下elasticsearch.bat 以及kibana的bin下的kibana.bat
  2. 注意点:elasticsearch与kibana的版本需要一致。
#elasticsearch.yml 简易配置样例
network.host: 10.58.xx.xx # 本地IP
http.port: 9200
node.name: node-1
cluster.initial_master_nodes: ["node-1"]
xpack.sql.enabled: true

#kibana.yml  简易配置样例
server.port: 5602
server.host: "localhost"
elasticsearch.hosts: ["http://10.58.xx.xx:9200/"] #本地IP,对应es服务的配置信息
kibana.index: ".kibana"
i18n.locale: "zh-CN"

查询样例

#查看具体索引的各分片doc数量、大小
GET _cat/shards/{index}?v&s=prirep,docs
#查看索引的doc数量其他方法
GET /sd_supplier/_count

POST /sd_supplier/_search
{"track_total_hits":true,"size": 0}

#查看join类型索引下relation下各层级大小
GET /{index}/_search
{
    "size": 0,    			// 不显示命中(hits)的所有文档信息
    "aggs": {
        "group_by_tags": {	// 聚合结果的名称, 需要自定义(复制时请去掉此注释)
            "terms": {
                "field": "{relationName}"
            }
        }
    }
}

#查看帮助信息,可以看到该命令可以输出那些列,列的解释,如果有些列默认不显示,可结合v参数指定显示
GET _cat/indices?help

#命令后加参数v可以显示具体的列头名,h指定显示的列、s指定排序列
##如:
GET _cat/indices?v 
GET _cat/plugins?v //查看所有插件,ES有哪些功能和安装的插件强相关,比如有xpack-sql,也有opendistro-sql。
GET _cat/indices?h=index,docs.count,store.size&v&s=docs.count,store.size

###GET /_cat API提供了一系列的命令来获取集群的各种信息,如节点、索引、健康状况等###
GET /_cluster/health
GET /_cluster/stats
GET /_cat/thread_pool?v&h=node_name,name,type,active,size,queue,queue_size,rejected,largest,completed,min,max&s=node_name,name

定位负载问题

#线程池情况,专门看search线程池
GET /_cat/thread_pool/search?v&h=node_name,name,type,active,size,queue,queue_size,rejected,largest,completed,min,max&s=node_name,name&s=active:desc,name,node_name
#参考热线程
GET /_nodes/hot_threads

#查看索引的各分片dco数量、大小
GET _cat/shards/indexname?v&s=prirep,docs,shard,store,ip

#查看任务执行情况,清晰明了
GET _cat/tasks?v&h=id,action,task_id,parent_task_id,type,start_time,timestamp,running_time_ns,running_time,ip,node&s=node,start_time

#查看活跃的慢查询任务,比较详细
GET _tasks?detailed=true&actions=*search*

#清理缓存
POST /_cache/clear

#查看节点的执行search查询统计情况
# 部分指标解释https://help.aliyun.com/zh/es/user-guide/metrics-and-exception-handling-suggestions#section-seh-zlh-ffp
GET _cat/nodes?v&h=name,ip,load_1m,load_5m,load_15m,search.fetch_total,search.query_total,master,heap.percent,ram.percent,cpu&s=name

#查看索引下各relation大小
GET /cso_order_s6/_search
{
    "size": 0,    			// 不显示命中(hits)的所有文档信息
    "aggs": {
        "group_by_tags": {	// 聚合结果的名称, 需要自定义(复制时请去掉此注释)
            "terms": {
                "field": "relation"
            } } }
}
##查看指定指定列信息 看分词器效果
get  {indexname}/_analyze
{
  "field": "{fieldname}",
  "text": "这是一个测试文档,用于测试IK分词器。"
}

#analyzer 就是选择分词器模式,查看分词效果
GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "这是一个测试文档,用于测试IK分词器"
}
#移动分片到其他节点
POST /_cluster/reroute
{
  "commands": [
    {"move": {
      "index": "{indexname}",
      "shard": 3,#shard号
      "from_node": "{nodename}",
      "to_node": "{nodename}"
    }}
  ]
}
##查看结果的指定列信息,可拼接多个
GET zzz_supplier_s6_3/_search?filter_path=hits.hits._score,hits.hits._source.supplier_name
{
	"query" : {}
}

样例SQL

#SQL 转query
POST /_opendistro/_sql/_explain
{
  "query":"select * from indexname where filedname1='zzzz' and filedname2='xxx' "
}
#复杂父子join,默认has_parent的score是1
//query 与filter结合
//POST /sd_supplier_s6/_search
{
	"query" : {
		"bool" : {
			"must" : [{
					"term" : {
						"filed1.keyword" : "xxx" //条件1,term条件时,一定要指定keyword,否则可能不相等。因为text是分词内容
					}
				}, {
					"has_parent" : {
						"parent_type" : "parent_level_name",
						"query" : {
							"bool" : {
								"must" : [{
										"match" : {
											"filed2" : "xxx" //条件2
										}
									}, {
										"wildcard" : {
											"filed3.keyword" : {
												"value" : "*xx*" //条件3 wildcard的是用来通用模糊匹配,query_string支持的场景更复杂,并且只是用来模糊,存在AND、OR等导致结果不可信
											}
										}
									}
								],
								"filter" : [{
										"bool" : {
											"should" : [{
													"bool" : {
														"must_not" : {
															"exists" : {
																"field" : "delete_flag"
															}
														}
													}
												}, {
													"term" : {
														"delete_flag.keyword" : "N"
													}
												}
											],
											"minimum_should_match" : "1"
										}
									}
								]
							}
						},
						"inner_hits" : {}, //"boost":100.0
						"score" : true //has_parent的score参与相关性计算
					}
				}
			],
			"filter" : [{
					"terms" : {
						"source_object_type.keyword" : ["Meta CCS", "SRM"]
					}
				}
			]
		}
	},
	"size" : 5,
	"sort" : [{
			"_score" : {
				"order" : "desc"
			}
		}
	]
}

通用参数

  1. format: 指定输出的格式(默认为 text),可以是 text、json、yaml 等。

    GET /_cat/nodes?format=json
    
  2. h: 指定输出的列(字段)。

    GET /_cat/nodes?h=id,ip
    
  3. help: 显示命令的帮助信息。

    GET /_cat/nodes?help
    
  4. v: 使输出包含列头(字段名)。

    GET /_cat/nodes?v
    
  5. s: 指定排序字段,可以是单个字段或多个字段(多个字段用逗号分隔),可以加后缀 asc  desc 指定排序方向。

    GET /_cat/nodes?s=id:desc
    
  6. ts: 控制是否显示时间戳。默认为 true

    GET /_cat/nodes?ts=false

    特定命令的参数

    _cat/indices

    1. bytes: 指定文件大小的单位,可以是 b(字节)、k(千字节)、m(兆字节)、g(吉字节)等。

      GET /_cat/indices?v&bytes=m
      
    2. health: 指定索引的健康状态过滤条件,可以是 green、yellow、red

      GET /_cat/indices?v&health=green
      
    3. pri: 仅显示主分片的信息。

      GET /_cat/indices?v&pri
      
    4. rep: 仅显示副本分片的信息。

      GET /_cat/indices?v&rep
      

    _cat/nodes

    1. full_id: 显示完整的节点ID。

      GET /_cat/nodes?v&full_id
      
    2. ip: 仅显示节点的IP地址。

      GET /_cat/nodes?v&ip
      
    3. master_timeout: 设置等待选举新的主节点的超时时间。

      GET /_cat/nodes?v&master_timeout=1m
      

    _cat/shards

    1. index: 指定索引名称。

      GET /_cat/shards/my_index?v
      
    2. shard: 指定分片ID。

      GET /_cat/shards?v&shard=0
      
    3. state: 指定分片的状态,可以是 STARTED、INITIALIZING、RELOCATING。

      GET /_cat/shards?v&state=STARTED
      

    _cat/health

    1. local: 优先使用本地节点获取信息,而不是从主节点获取。

      GET /_cat/health?v&local
      
    2. master_timeout: 设置等待选举新的主节点的超时时间。

      GET /_cat/health?v&master_timeout=1m
      

    _cat/aliases

    1. alias: 指定别名。

      GET /_cat/aliases?alias=my_alias
      
    2. index: 指定索引名称。

      GET /_cat/aliases?index=my_index
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。