架构师系列-搜索引擎ElasticSearch(五)- 索引设计

索引创建后,要非常谨慎,创建不好后面会出现各种问题。

索引设计的重要性

        索引创建后,索引分片只能通过_split和_shrink 接口对其进行成倍的增加和缩减。

        ES的数据是通过_routing分配到各个分片上的,所以本质上不推荐区改变索引的分片数量的,因为这样都会对数据进行重新移动。还有就是索引只能新增字段,不能对字段进行修改和删除,缺乏灵活性,所以每次都只能通过_reindex重建索引了,还有就是一个分片的大小以及所以分片数量的多少严重影响到了索引的查询和写入性能,所以可想而知,设计一个好的索引能够减少后期的运维管理和提高不少性能,所以前期对索引的设计是相当的重要的。

基于时间的索引设计

Index设计时要考虑的第一件事,就是基于时间对Index进行分割,即每隔一段时间产生一个新的Index。

因为现实世界的数据是随着时间的变化而不断产生的,切分管理可以获得足够的灵活性和更好的性能。

         如果数据都存储在一个Index中,很难进行扩展和调整,因为Elasticsearch中Index的某些设置在创建时就设定好了,是不能更改的,比如Primary Shard的个数。而根据时间来切分Index,则可以实现一定的灵活性,既可以在数据量过大时及时调整Shard个数,也可以及时响应新的业务需求。
        大多数业务场景下,客户对数据的请求都会命中在最近一段时间上,通过切分Index,可以尽可能的避免扫描不必要的数据,提高性能。

时间间隔

        根据上面的分析,自然是时间越短越能保持灵活性,但是这样做就会导致产生大量的Index,而每个Index都会消耗资源来维护其元信息的,因此需要在灵活性、资源和性能上做权衡。
        1)常见的间隔有小时、天、周和月:先考虑总共要存储多久的数据,然后选一个既不会产生大量Index又能够满足于定灵活性的间隔,比如你需要存储6个月的数据,那么一开始选择“周“这个间隔就会比较合适。

        2)考虑业务增长速度:假如业务增长的特别快,比如上周产生了1亿数据,这周就增长到了10亿,那么就需要调低这个间隔来保证有足够的弹性能应对变化。  

如何实现分割

        切分行为是由客户端(数据的写不端)发起的,根据时间间隔与数据产生时间将数据写入不同的Index中,为了易于区分,会在Index的名字中加上对应的时间标识。
        创建新Index这件事,可以是客户端主动发起一个创建的请求,带上具体的Settings、Mappings等信息,但是可能会有一个时间错位,即有新数据写入时新的ndex还没有建好,Elasticsearch提供了更优雅的方式来实现这个动作,即Index Template  (索引模板)

使用索引模板

         就是把已经创建好的某个索引的参数设置(settings)和索引映射(mapping)保存下来作为模板,在创建新索引时,指定要使用的模板名,就可以直接重用已经定义好的模板中的设置和映射。


        Elasticsearch基于与索引名称匹配的通配符模式将模板应用于新索引,也就是说通过索引进行匹配,看看新建的索引是否符合索引模板,如果符合,就将索引模板的相关设置应用到新的索引,如果同时符合多个索引模板呢,这里需要对参数priority进行比较,这样会选择priority大的那个模板进行创建索引。
        在创建索引模板时,如果匹配有包含的关系,或者相同,则必须设置priority为不同的值,否则会报错,索引模板也是只有在新创建的时候起到作用,修改索引模板对现有的索引没有影响,同样如果在索引中设置了一些设置或者mapping都会覆盖索引模板中相同的设置或者mapping。

索引模板的用途

      如果你需要每间隔一定的时间就建立一次索引,你只需要配置好索引模板,以后就可以直接使用这个模板中的设置,不用每次都设置settings和mappings。

创建索引模板

PUT _index_template/logstash-village
{"index_patterns": ["logstash-village-*"  // 可以通过"logstash-village-*"来适配创建的索引],"template": {"settings": {"number_of_shards": "3", //指定模板分片数量"number_of_replicas": "2"  //指定模板副本数量},"aliases": {"logstash-village": {}  //指定模板索引别名},"mappings": {   //设置映射"dynamic": "strict", //禁用动态映射"properties": {"@timestamp": {"type": "date","format": "strict_date_optional_time||epoch_millis||yyyy-MM-dd HH:mm:ss"},"@version": {"doc_values": false,"index": "false","type": "integer"},"name": {"type": "keyword"},"province": {"type": "keyword"},"city": {"type": "keyword"},"area": {"type": "keyword"},"addr": {"type": "text","analyzer": "ik_smart"},"location": {"type": "geo_point"},"property_type": {"type": "keyword"},"property_company": {"type": "text","analyzer": "ik_smart"},"property_cost": {"type": "float"},"floorage": {"type": "float"},"houses": {"type": "integer"},"built_year": {"type": "integer"},"parkings": {"type": "integer"},"volume": {"type": "float"},"greening": {"type": "float"},"producer": {"type": "keyword"},"school": {"type": "keyword"},"info": {"type": "text","analyzer": "ik_smart"}}}}
}

模板参数

分片设计

        所谓分片设计,就是如何设定主分片的个数。看上去只是一个数字而已,也许在很多场景下,即使不设定也不会有问题(ES7默认是1个主分片一个副本分片),但是如果不提前考虑,一旦出问题就可能导致系统性能下降、不可访问、甚至无法恢复,换句话说,即使使用默认值,也应该是通过足够的评估后作出的决定,而非拍脑袋定的。

限制分片大小

        单个Shard的存储大小不超过30GB。Elastic专家根据经验总结出来大家普遍认为30GB是个合适的上限值,实践中发现单个Shard过大(超过30GB)会导致系统不稳定。 ​

        为什么不能超过30GB?主要是考虑Shard Relocate过程的负载,我们知道,如果Shard不均衡或者部分节点故障,Elasticsearch会做Shard Relocate,在这个过程中会搬移Shard,如果单个Shard过大,会导致CPU、IO负载过高进而影响系统性能与稳定性。

 评估分片数量

单个Index的Primary Shard个数 = k * 数据节点个数

在保证第一点的前提下,单个Index的Primary Shard个数不宜过多,否则相关的元信息与缓存会消耗过多的系统资源,这里的k,为一个较小的整数值,建议取值为1,2等,整数倍的关系可以让Shard更好地均匀分布,可以充分的将请求分散到不同节点上。

 小索引设计

对于很小的Index,可以只分配1~2个Primary Shard的

​有些情况下,Index很小,也许只有几十、几百MB左右,那么就不用按照第二点来分配了,只分配1~2个Primary Shard是可以的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/619299.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络篇06 | 应用层 自定义协议

网络篇06 | 应用层 自定义协议 01 固定协议设计(简化版)1)总体设计2)值设计 02 可变协议设计(进阶版)1)固定头(Fixed Header)2)可变头(Variable H…

Android ParcelFileDescriptor实现进程间通信

需求 一个通信通道,实现跨进程的的Socket网络通信。 具体的通信通道的图如下。 需求分析 我们需要一个进程一直做通信通道的事情,业务进程把数据通过进程间通信交给通信进程。通信进程通过Socket通道将数据发给网络另外一端的通信进程。接收端的通信进…

二百三十一、ClickHouse——DBeaver连接ClickHouse中时间戳字段的时区差了8小时

一、目的 在用kettle把MySQL中的数据同步到ClickHouse中,发现kettle里的数据显示正常、DataGrip查询ClickHouse中的数据显示正常,但是DBeaver中显示的ClickHosue中的时间字段晚8个小时 二、错误原因 DBeaver的数据库时区设置有问题 三、解决办法 右…

ansible创建用户账户和更新ansible库的密钥

1.创建⽤户帐户 从 http://materials/user_list.yml 下载要创建的⽤户的列表,并将它保存到 /home/greg/ansible 在本次考试中使⽤在其他位置创建的密码库 /home/greg/ansible/locker.yml 。创建名为 /home/greg/ansible/users.yml 的 playbook ,从⽽…

大数据深度学习:基于Tensorflow深度学习卷积神经网络CNN算法垃圾分类识别系统

文章目录 大数据深度学习:基于Tensorflow深度学习卷积神经网络CNN算法垃圾分类识别系统一、项目概述二、深度学习卷积神经网络(Convolutional Neural Networks,简称CNN)三、部分数据库架构四、系统实现系统模型部分核心代码模型训…

计算机网络 Cisco虚拟局域网划分

一、实验内容 1、分别把交换机命名为SWA、SWB 2、划分虚拟局域网 valn ,并将端口静态划分到 vlan 中 划分vlan 方法一:在全局模式下划分vlan,在SWA交换机上创建三个vlan,分别为vlan2,vlan3,vlan4。 方…

JavaScript流文件下载实现详解

文章的更新路线:JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScript基础知识-网络基础知识-浏览器基础知识-项目优化知识-项目实战经验-前端温习题(HTML基础知识和CSS基础知识已经更新完毕) 正文 前端web、h5实现方式 if (!res) retur…

深入探索 RabbitMQ:功能丰富的消息中间件一

在现代分布式系统的构建中,消息中间件扮演着至关重要的角色。作为这一领域的佼佼者,RabbitMQ以其独特的特性和强大的功能,为应用程序提供了高效可靠的消息传递解决方案。以下是对RabbitMQ及其显著特点的更详细探讨。 什么是 RabbitMQ&#x…

Unity 2D让相机跟随角色移动

相机跟随移动 最简单的方式通过插件Cinemachine 在窗口/包管理器选择全部找到Cinemachine,导入。然后在游戏对象/Cinemachine创建2D Camera。此时层级中创建一个2D相机。选中人物拖入检查器Follow。此时相机跟随人物移动。 修改相机视口距离 在检查器中Lens下调正…

LabVIEW直流稳定电源自动化校准系统

LabVIEW直流稳定电源自动化校准系统 直流稳定电源正向着智能化、高精度、多通道、宽量程的方向发展。基于LabVIEW开发环境,设计并实现了一种直流稳定电源自动化校准系统,以提升校准过程的整体效能,实现自动化设备替代人工进行电源校准工作。…

数据可视化基础与应用-04-seaborn库人口普查分析--如何做人口年龄层结构金字塔

总结 本系列是数据可视化基础与应用的第04篇seaborn,是seaborn从入门到精通系列第3篇。本系列主要介绍基于seaborn实现数据可视化。 参考 参考:我分享了一个项目给你《seaborn篇人口普查分析–如何做人口年龄层结构金字塔》,快来看看吧 数据集地址 h…

基于飞浆paddle的Mv3驾驶员行为识别

“其实一开始并没有想学深度学习” ! pip install --upgrade pip ! pip install paddlex ! pip install --user --upgrade pyarrow11.0.0 # 配置环境 train_list格式(test同理):图片路径\t标签 newLabels格式:标签 训练代码 impo…