elasticsearch 索引的字段类型和设置字段常见的参数 性能调优
索引的创建需要配置mapping与setting两部分。
索引的mapping
常用数据类型
text、keyword、number、array、range、boolean、date、geo_point、ip、nested、object。
text:默认会进行分词,支持模糊查询(5.x之后版本string类型已废弃,请大家使用text)。
keyword:不进行分词,默认开启doc_values来加速聚合排序操作,占用了大量磁盘io 如非必须可以禁用doc_values。
number:如果只有过滤场景 用不到range查询的话,使用keyword性能更佳,另外数字类型的doc_values比字符串更容易压缩。
range:对数据的范围进行索引,目前支持 number range、date range 、ip range。
array:es不需要显示定义数组类型,只需要在插入数据时用’[]‘表示即可。[]中的元素类型需保持一致。
boolean: 只接受true、false,也可以是字符串类型的“true”、“false”。
date:支持毫秒、根据指定的format解析对应的日期格式,内部以long类型存储。
geo_point:存储经纬度数据对。
ip:将ip数据存储在这种数据类型中,方便后期对ip字段的模糊与范围查询。
nested:嵌套类型,一种特殊的object类型,存储object数组,可检索内部子项。
object:嵌套类型,不支持数组。
建个索引
PUT /tvs
{
"mappings": {
"properties": {
"price": {
"type": "long"
},
"color": {
"type": "keyword"
},
"brand": {
"type": "keyword"
},
"sold_date": {
"type": "date", // 使用date类型时要指定format,否则在使用range查询+时间表达式now/d等时,会特别坑爹
"format":"yyyyMMdd"
}
}
}
}
其他参数
我工作常用的是
-
type:field的类型。
-
index:该field是否会被索引。
-
analyzer:指定的分词器。
-
doc_values:开启后对聚合入分组或排序有增益,默认开启。
"field": {
"type": "text", //文本类型 ,指定类型
"index": "false"// ,设置成false,字段将不会被索引
"analyzer":"ik"//指定分词器
"boost":1.23//字段级别的分数加权
"doc_values":false//对not_analyzed字段,默认都是开启,analyzed字段不能使用,对排序和聚合能提升较大性能,节约内存,如果您确定不需要对字段进行排序或聚合,或者从script访问字段值,则可以禁用doc值以节省磁盘空间:
"fielddata":{"loading" : "eager" }//Elasticsearch 加载内存 fielddata 的默认行为是 延迟 加载 。 当 Elasticsearch 第一次查询某个字段时,它将会完整加载这个字段所有 Segment 中的倒排索引到内存中,以便于以后的查询能够获取更好的性能。
"fields":{"keyword": {"type": "keyword","ignore_above": 256}} //可以对一个字段提供多种索引模式,同一个字段的值,一个分词,一个不分词
"ignore_above":100 //超过100个字符的文本,将会被忽略,不被索引
"include_in_all":ture//设置是否此字段包含在_all字段中,默认是true,除非index设置成no选项
"index_options":"docs"//4个可选参数docs(索引文档号) ,freqs(文档号+词频),positions(文档号+词频+位置,通常用来距离查询),offsets(文档号+词频+位置+偏移量,通常被使用在高亮字段)分词字段默认是position,其他的默认是docs
"norms":{"enable":true,"loading":"lazy"}//分词字段默认配置,不分词字段:默认{"enable":false},存储长度因子和索引时boost,建议对需要参与评分字段使用 ,会额外增加内存消耗量
"null_value":"NULL"//设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词
"position_increament_gap":0//影响距离查询或近似查询,可以设置在多值字段的数据上火分词字段上,查询时可指定slop间隔,默认值是100
"store":false//是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值
"search_analyzer":"ik"//设置搜索时的分词器,默认跟ananlyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能
"similarity":"BM25"//默认是TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效
"term_vector":"no"//默认不存储向量信息,支持参数yes(term存储),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用
}
索引的参数Setting
setting为ES索引的配置属性,索引的配置项按是否可以更改分静态(static)属性与动态配置
静态配置即索引创建后不能修改,静态配置只能在创建索引时或者在状态为 closed index的索引(闭合的索引)上设置。
下面介绍一下索引的静态配置和动态配置
索引静态配置
-
index.number_of_shards 主分片数,默认为5。只能在创建索引时设置,不能修改。
-
index.shard.check_on_startup 是否在索引打开前检查分片是否损坏,当检查到分片损坏将禁止分片被打开。可选值:false:不检测;checksum:只检查物理结构;true:检查物理和逻辑损坏,相对比较耗CPU;fix:类同与false,7.0版本后将废弃。默认值:false。
-
index.codec 数据存储的压缩算法,默认算法为LZ4,也可以设置成best_compression,best_compression压缩比较好,但存储性能比LZ4差
-
index.routing_partition_size 路由分区数,默认为 1,只能在索引创建时设置。此值必须小于index.number_of_shards,如果设置了该参数,如果设置了该参数,其路由算法为: (hash(_routing) + hash(_id) % index.routing_parttion_size ) % number_of_shards。如果该值不设置,则路由算法为 hash(_routing) % number_of_shardings,_routing默认值为_id。
PUT /test_setting { "settings": { "number_of_shards": "3", "number_of_replicas": "1" } }
索引动态配置
从上到下,是我从常用到不常用的排序。
-
index.refresh_interval 执行刷新操作的频率,这使得索引的最近更改可以被搜索。默认为 1s。可以设置为 -1 以禁用刷新。
-
index.max_result_window 用于索引搜索的 from+size 的最大值。默认为 10000。
-
index.max_docvalue_fields_search 一次查询最多包含开启doc_values字段的个数,默认为100。
-
index.number_of_replicas 每个主分片的副本数,默认为 1,该值必须大于等于0
-
index.auto_expand_replicas 基于可用节点的数量自动分配副本数量,默认为 false(即禁用此功能)
-
index.blocks.read_only 设置为 true 使索引和索引元数据为只读,false 为允许写入和元数据更改。
-
index.max_rescore_window 在搜索此索引中 rescore 的 window_size 最大值
-
index.blocks.read_only_allow_delete 与index.blocks.read_only基本类似,唯一的区别是允许删除动作。
-
index.blocks.write 设置为 true 可禁用对索引的写入操作。
-
index.blocks.read 设置为 true 可禁用对索引的读取操作
-
index.blocks.metadata 设置为 true 可禁用索引元数据的读取和写入。
-
index.max_refresh_listeners 索引的每个分片上可用的最大刷新侦听器数。
对于已存在的索引,我们想要修改它的动态配置,可以使用_settings方法。
PUT /test_setting/_settings
{
"number_of_replicas": "0"
}
写translog过程 以及 translog的参数配置
虽然translog是用来防止数据丢失,但是也有数据丢失的风险。
写translog,并不是每个写操作或者更新操作,都立刻写入到磁盘。因为写translog也是有同步和异步两种模式的,在异步模式下translog只有被fsync才会被写入到磁盘。正是“index.translog.sync_interval”这个配置参数,决定了多久出发一次fsync,默认是5s,这意味着,在这5s内发生断电,数据也是回被丢失的。
“index.translog.durability”这配置参数,可以控制translog是同步还是异步。决定了是否在每次写数据或者修改数据就触发一次fsync。es的默认是index.translog.durability=request。也就是每次都触发fsync。
如果制定index.translog.durability=async 那么就要面临丢数据的风险了。
translog日志的大小也不能是无限大的,因为它的大小,则决定了集群崩溃后恢复的时间长短。如果太大,则会面临集群恢复很久的问题。“index.translog.flush_threshold_size” 这个参数就是指定translog日志最大的大小的。默认为512M。意思是当translog日志大于512M,就一定会触发一次flush,将数据从文件系统落到磁盘上,并将translog清理掉。
关于参数调优-translog可以影响到写入的性能
translog能够修改的参数基本上也列出来了。这是我在官网上能看到的参数。
针对上边的分析,其实我们有个点可以平衡。如果我们可以接受一定的数据丢失的话,我们可以用异步写translog日志的方式来写入数据。因为一次成功的写,是要等待写translog成功的。如果我们用异步,则不用等写traslog成功,就可以返回了。
关于这个优化的点,其实很多文章都没有提到的,官网也没有说。全靠我们自己悟。
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。