ElasticSearch使用最佳实践-集群规划
1. 集群合理的规格
从业务侧来看,主要是控制集群的shard数量,数据存储量,segment数量在合理的范围内。
1.单EsNode Shard数 |
以单EsNode实例31GB为例,管理500个shard为合理范围。基于单EsNode数据量不超过15T及集群整体shard数不超过50000考虑。 |
2.Shard大小 |
每个分片大小20~30GB,最多不超过50G |
3. 单集群数据实例数 |
推荐300以内,否则主节点管理压力很大,集群稳定性和性能下降明显 |
3.单集群支持的最大shard数 |
推荐50000以内,否则主节点管理压力很大,集群稳定性和性能下降明显 |
4.单EsNode实例,最大数据存储量 |
推荐5TB以内,存储数据过多会导致段文件占用过大内存 |
5.Segment数 |
segment个数合理范围是分片数的1至5倍,段文件过多可以通过执行段文件合并命令 |
6.EsNode磁盘使用率 |
不允许超过85%,到达80%需要引起注意,及时扩容或老化数据 |
每个规格对应查看方式:
1.查看第1列shards:curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cat/allocation?v&s=disk.used:desc'
2.查看第6列store: curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cat/shards?v&s=store'
3.查看number_of_data_nodes: curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cluster/health?pretty'
4.查看active_shards:curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cluster/health?pretty'
5.查看第2列disk.indices:curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cat/allocation?v&s=disk.used:desc'
6.列出所有索引的segement数量:curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cat/segments?v'
段文件合并:
curl -XPOST --negotiate -k -u : https://ip:port/{index_name}/_forcemerge?max_num_segments=1
注意:segment merging要消耗CPU以及大量的I/O资源,建议在业务低峰期执行。
1. 查看第6列disk.percent:curl -XGET --tlsv1.2 --negotiate -k -u : 'https://ip:port/_cat/allocation?v&s=disk.used:desc'
2. 内存配置及实例个数建议
资源允许的情况下,单个实例分配的最大堆内存不要超过31GB,同时需要预留一半的物理内存作为Lucene缓存使用。以256GB内存为例,建议预留128GB内存供Lucene使用,剩余128GB内存可分配4个ES实例,每个实例分配31GB内存。
3. 创建索引建议
1)为了减少索引数量并避免非常庞大的映射,请考虑将相同索引结构的数据存储在相同的索引中。
2)避免将不相关的数据放在同一个索引中,以避免稀疏,将这些文件放在不同的索引中通常会更好。
3)针对数据量比较大的索引,建议按周期进行分表,比如按天进行索引划分。
4. 合理的mapping设置建议
写入数据前进行合理的mapping设置是必须的:
1)Elasticsearch可以对数据做动态mapping,但请不要这么做,尽量在创建index时便赋予index固定的mapping配置。设置动态mapping,当大量数据写入的同时伴随着新的字段的增加,会造成大量的put_mapping操作,从而造成EsMaster阻塞,影响整个ES集群的运行。不建议使用动态mapping,如果需要使用动态mapping,建议尽量使用较为精准的匹配规则,杜绝*通配符等暴力操作。
创建索引时指定动态mapping为false:
curl -XPUT --tlsv1.2 --negotiate -k -u : "https://127.0.0.1:24100/myindex" -H 'Content-Type: application/json' -d ' { "mappings": { "my_type": { "dynamic": "false", "properties": { "title": { "type": "text"}, "stash": { "type": "object", "dynamic": true } } } } }' |
如上条命令,指定dynamic策略时可以针对type和字段分别指定,且只能创建索引时指定。
2)如果数据量巨大,可以分的字段个数太多,如超过1000个字段,最好给字段赋予不同的级别索引到不同的index中。例如,常用的查询字段可以写入到一个index中,字段长度较长且不常用的索引到另一个index中。
3)合理的设计Mapping,根据实际的业务数据去设置优化Mapping,根据具体的字段和需求去选择对应的类型设置,可参考如下几点:
- string类型默认分成:text和keyword两种类型。需要分词:text,否则keyword。
- 枚举类型,基于性能keyword,即便是整形。
- 数值类型,尽量选择贴近大小的类型。
- 日期类型,如果需要基于时间轴做分析,必须date类型,如果仅需秒级返回,建议使用keyword。
- 其他类型,布尔、日期、地理位置,使用对应的类型即可。
- 如果某个字段不需要被检索,将“index”参数设置为“false”。
curl -XPUT --tlsv1.2 --negotiate -k -u : "https://127.0.0.1:24100/myindex" -H 'Content-Type: application/json' -d '
{
"mappings": {
"my_type": {
"properties": {
"content": {
"type":"keyword",
"index": false
}
}
}
}
}'
- “_all”字段,默认将写入的字段拼接成一个大的字符串,并对该字段进行分词,用于支持整个doc的全文检索,“_all”字段能让你在不知道要查找的内容是属于哪个具体字段的情况下进行搜索,“_all”字段在查询时占用更多的CPU,同时占用更多的磁盘存储空间,默认为“false”,不建议开启该字段。
curl -XPUT --tlsv1.2 --negotiate -k -u : "https://127.0.0.1:24100/myindex" -H 'Content-Type: application/json' -d '
{
"mappings": {
"my_type": {
"_all": {
"enable": false
}
}
}
}'
-
norms字段,norm是索引评分因子,如果不用按评分对文档进行排序,设置为“false”,默认是“true”。
curl -XPUT --tlsv1.2 --negotiate -k -u : "https://127.0.0.1:24100/myindex" -H 'Content-Type: application/json' -d '
{
"mappings": {
"my_type": {
"properties": {
"content": {
"type":"keyword",
"norms": false
}
}
}
}
}'
-
_source字段,默认是开启的,如果不需要update、reindex和高亮操作,可以禁止“_source”,节省更多的磁盘空间。
curl -XPUT --tlsv1.2 --negotiate -k -v -u : 'https://ip:httpport/myindex?pretty' -H 'Content-Type: application/json' -d'
{
"mappings": {
"tweet": {
"_source": {
"enabled": false
}
}
}
}'
5. 合理的setting设置建议
(1) 修改索引刷新时间:默认为1s,即每1s都会将写入到内存里面的数据刷新到磁盘里面,可修改为60s或者120s,减轻磁盘的IO压力;
"refresh_interval" : "60s" |
(2) 修改Translog策略参数,默认translog的持久化策略默认为request,即每个请求都进行flush,影响ES写入速度。将持久化策略改成async,表示按设置的sync_interval周期性进行刷新,同时调大translog刷盘间隔时间,默认为5s,调大至120s或者180s。调大translog flush的大小为3G,即大小超过3GB进行刷新操作;
"translog. durability ":" async " |
"sync_interval": "180s" |
"translog.flush_threshold_size":"3gb" |
(3) 设置index.type.store为niofs模式,可以减轻集群的IO负载;
"index.type.store" : "niofs" |
(4) 针对于5机器节点以上,为了让各个实例上的分片均匀分布,添加如下参数,设置每个索引在单个实例上的分片个数,如下所示为每个索引在每个实例上的分片为2个。
"index.routing.allocation.total_shards_per_node":"2" |
6. 数据的生命周期
ES中的open状态的索引都会占用堆内存来存储倒排索引,过多的索引会导致集群整体内存使用率多大,甚至引起内存溢出。所以需要根据自身业务管理历史数据的生命周期,如近3个月的数据open用于快速查询;过去3-6月的数据索引close以释放内存,需要时再开启;超过6个月的可以删除索引。
可以使用索引模板的方式按照一定时间创建新的索引,例如按天创建索引,索引的命名可能是index-yyyy-mm-dd,每天生成不同的索引,清除历史数据时可直接关闭或删除。
- 点赞
- 收藏
- 关注作者
评论(0)