咸阳网站建设推广装修工人
咸阳网站建设推广,装修工人,国家工商网站查询,新闻稿件代发平台ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Quer…ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Query DSLhttps://blog.csdn.net/zhenghuishengq/article/details/134159587【四】ElasticSearch的聚合查询操作https://blog.csdn.net/zhenghuishengq/article/details/134159587【五】SpringBoot整合elasticSearchhttps://blog.csdn.net/zhenghuishengq/article/details/134212200【六】Es集群架构的搭建以及集群的核心概念https://blog.csdn.net/zhenghuishengq/article/details/134258577【七】ES的开发场景和索引分片的设置及优化https://blog.csdn.net/zhenghuishengq/article/details/134302130 ES的开发场景和索引分片的设置及优化 一ES的开发场景和索引分片的设置及优化1ES应用场景1.1信息搜索库1.2时间序列库 2分片的设计和管理2.1单个分片2.2多个分片2.2.1算分不准原因 2.3分片的设计2.3.1分片类型选择以及优缺点2.3.2主分片设计与案例2.3.3副本分片设计 3ElasticSearch底层读写原理3.1数据的写入3.1.1数据写入的流程3.2.2数据存储文件形式 3.2数据的读取3.2.1根据id查询3.2.2根据关键字查询 3.3数据读写优化 一ES的开发场景和索引分片的设置及优化
在上一篇中讲解了Es集群的搭建以及一些索引分片副本等的概念接下来这篇主要讲解在实际开发中ElasticSearch的一些应用场景
1ES应用场景
在实际开发中es主要有两种应用场景一种是基于数据量大但是数据增长量慢的应用场景如订单查询商品查询等一种是基于数据量大数据增长量快的应用场景如每天都会有大量的日志信息通过时间序列对日志进行存储和查询等。
1.1信息搜索库
这就是第一种情况针对于数据量大但是增长量慢的应用场景。如在一个商城app中其商品的信息、订单的信息等在数据加入到es之后可以选择通过商品的类型或者名称进行分片存储在查询时只需要根据商品类型或者名称查询对应的分片结点即可
这种场景更加需要考虑的是搜索的相关度如涉及算分权重这些与时间的范围无关。 如上图中搜索框中输入的家电下面会展示所有的家电信息品牌等那么在es中做索引分片时就可以根据品牌进行分片存储等。需要注意的是单个分片最好不要数据量太大如不要超过20g如果数据量太多可以通过增加副本分片的数量从而提高吞吐量
如果是单个索引的数据量太大可以通过reindex进行索引拆分可以根据某种枚举字段进行拆分如订单可以根据区域进行拆分商品根据品牌进行拆分等。
1.2时间序列库
根据时间序列进行统计容日志的查询等一般每条数据都会有一条时间戳并且每条文档基本上都不会更新主要是为了查询因此对数据的写入要求会比较高。如每天有几万条数据插入到es数据库中
在创建索引时可以直接根据时间进行创建索引如每天或者每周或者每月的方式进行划分如每天有上万条日志信息那么就可以直接根据时间进行创建索引每天晚上可以开启一个定时任务去创建索引随后今天一天的数据全部存储在这个索引中后续作统计时只需要定位到这个索引片即可
PUT /logs_2023-11-07也可以直接选择使用这个Date Math表达式其语法如下
static_name{date_math_expr{date_format|time_zone}}使用这个Date Math的官网https://www.elastic.co/guide/en/elasticsearch/reference/7.16/date-math-index-names.html
如官方文档给的实例显示的结果就是创建今天的日期的索引前缀就是my-index
# PUT /my-index-{now/d}
PUT /%3Cmy-index-%7Bnow%2Fd%7D%3E上面的百分号在官网中也有对应的值只需要根据这些值进行修改即可 官网提供的转义表达式有这些如now/d等等从、-、{、}、/ 等一一的按照上面的值进行替换即可 如果是需要查询最近的数据也可以采用冷热分离的架构将最近几天的数据加入到hot热点数据中并且在存储日志这种信息是丢失几条数据也是没事的因此在设置副本的数量时可以直接设置为0
如果前端是要固定的查询一个索引那么可以通过别名的方式去新增索引先将原索引删除然后将创建的新索引的别名设置为原索引的名称
2分片的设计和管理
2.1单个分片
在es7开始在创建一个索引时默认是只有一个分片和一个副本的。如下例子本人就是使用的7.7的版本在创建一个索引之后其默认的分片数和副本数就是1。因为直接使用单个分片可以避免很多问题如算分问题聚合问题等
number_of_shards : 1,
number_of_replicas : 1,但是单个分片也存在一些缺点如在集群中单个分片不能很好的实现水平扩展除非要手动reindex增加分片将数据进行拆分
2.2多个分片
多个分片和单个分片的优缺点刚好相反多个分片是有利于实现节点的水平扩展的在性能上会高于单分片的索引。但是多分片也会出现一些问题如算分不准聚合查询等问题
2.2.1算分不准原因
当数据量大的时候一般数据都是均分分布在各个节点的因此不会出现这种算分不准的情况一般是会出现在数据量小的情况如每个分片的数据量都比较小举个例子
先创建一个索引并设置分片数为3
PUT /zhs_db
{settings:{number_of_shards : 3}
}随后往文档中插入数据这里不使用_bulk批量插入因为批量插入会在一个分片中。往里面插入三条数据根据hash规则那么三条数据就会分别落在三个分片中一个分片中一条数据
POST /zhs_db/_doc/1?routingzhenghuisheng
{content:Cross Cluster elasticsearch Search
}POST /zhs_db/_doc/2?routingzhenghuisheng2
{content:elasticsearch Search
}POST /zhs_db/_doc/3?routingzhenghuisheng3
{content:elasticsearch
}
随后进行match查询这个content并且value为elasticSearch
GET /zhs_db/_search
{query: {match: {content: elasticsearch}}
}在执行上面的查询之后其结果如下本来是所占文档比率越高算分的值越大就是id为3的占百分百因此按理来说是算分最高的然而实际在查询出来的是id为1的算分最高实际id为1的算分是最低的因此综合来看这个算分就是不准的 主要原因是每个分片都有自己打分的标准每个分片都是基于自己分片上的数据的相关度来进行计算的其最主要原因是数据量少因此如果是数据量少的情况下还是建议设置这个分片数为1
当然在数据量小的时候也有对应的解决方案就是使用DFS Query Then Fetch 其原理就是将所有的数据全部搜索出来然后统一放在一个协调结点中通过协调节点再进行一次完整的算分。但是在实际开发中这种方式并不推荐使用因为其性能相对是较低的
GET /zhs_db/_search?search_typedfs_query_then_fetch
{query: {match: {content: elasticsearch}}
}2.3分片的设计
2.3.1分片类型选择以及优缺点
上面说了单个分片和多个分片使用的优缺点接下来谈谈在实际开发中是如何设计这个分片的。
往往来说分片的数量是需要大于结点数的那么这样基本都是优选考虑多分片数据这样有利于在新增数据节点时可以进行自动的分配并且如果一个索引的数据分布在不同的节点这样就可以并行的执行并且在数据写入时也可以分散到多个机器。
但是分片过多也会带来一些副作用因为每一个分片就是一个Lucene索引其实就是一个进程如果过多的分片就会占用机器的资源导致带来额外的开销并且所有的分片都是需要Master主节点进行维护和管理这样就会导致master主节点承受更大的负担因此分片需要控制在10W之内
2.3.2主分片设计与案例
在实际开发中日志类的数据只需要设置主分片数但是不需要设置副本数而其他的数据增长量慢的需要设置主分片数和副本数接下来谈谈主分片数需要如何设计
当数据为搜索类时如商品信息类那么单个分片不要超过20个G的数据当数据为日志类时如订单类、流水类那么单个分片不要超过50G的数据
搜索类设计如根据品牌进行设计一个品牌对应一个索引一个索引对应一个主分片和一个副本分片
日志类设计每天创建一个日志索引每个日志索引创建10个分片一个月需要创建300个分片不需要副本
2.3.3副本分片设计
一般在实际开发中副本都是设置为0或者1日志类数据不需要副本可以直接设置为0搜索类数据一般设置为1副本就是类似于主分片的一个从分片有主分片中的全部数据。
副本分片数据就是数据在住分片中插入完成之后再在副本分片中再保存一份如果副本分片数过多那么在存入副本数据时就会花费更多的时间在写性能上会有一定的影响
但是副本分片也有好处首先就是可以提高查询的效率并且可以防止数据丢失保证数据的安全性因此副本分片是需要的但是也不能设计太大日志类除外。并且可以通过不断的调整副本分片的个数来是整个系统的查询率和响应率达到最佳状态
为了避免分配的不均衡分片数的调整如下
index.routing.allocation.total_shards_per_node表示在索引中每个Node的最大分片数量-1表示无穷大cluster.routing.allocation.total_shards_per_node表示在集群中每个Node结点最大分片的数量-1表示无穷多个
3ElasticSearch底层读写原理
上面谈到了分片和副本的一些概念和设计接下来通过es写入数据的流程来分析分片和副本的功能到底是什么。
3.1数据的写入
3.1.1数据写入的流程
在前面谈到了通过不同的数据节点实现不同的功能写入请求是需要先通过协调节点在转发到data数据节点存储随后先将数据存储到主分片上面然后再将数据同步到副本分片上面其具体的流程实现如下
1在用户发起写请求之后首先该请求会先到协调节点2协调结点接收到这个请求之后会通过route路由的方式将请求转发给对应的节点3随后会将数据同步到该节点的主分片上如果有副本分片则将数据给副本分片也同步一份4当master主分片和副本分片都同步完数据之后协调节点再给客户端一个存入成功的响应
3.2.2数据存储文件形式
segment file 在mysql中mysql是以页为单位存储在磁盘中在ElasticSearch中是通过这个Segment file的方式存储每一个文件的本质就是一个倒排索引一个大的分片中都是由各个小的Segment file文件合并成的。文件过多时会自动合并各个小文件也可以手动强制合并在合并时会将被标记删除的文档给物理删除
commit point 当将某个文档删除时ElasticSearch不会立马删除而是先通过这个commit point文件做一个标志每个文件中都有.del的一个标志如果设置了被删除的状态那么在查询数据时默认会将这个文档给过滤掉。这个也有点类似于mysql的行格式里面有字段用于标记是否被删除
translog文件 类似于mysql的redolog文件防止因为宕机造成数据丢失用于做数据恢复
os cache 缓存每隔一s会进行一个刷盘操作也可以通过refresh强制刷盘
3.2数据的读取
数据的查询主要有两种方式一种是直接根据id进行查询一种是直接根据关键字进行匹配
3.2.1根据id查询
根据id查询的方式是比较简单的首先也是先由客户端发起请求随后将请求发送到协调者结点协调者节点通过这个id进行hash取模定位到Data数据节点数据节点上有主分片和副本分片这两种分片都可以进行数据的查询会通过随机的方式选择副本还在主分片如下面的P0和R0会在这两个分片中选择一个分片作为数据查询的依据随后将响应结果返回给协调者分片分片最后再通过协调者分片将数据返回给用户
当然如果副本分片和主分片之间也可以做一个负载均衡来提高整个系统的高性能 3.2.2根据关键字查询
其流程大致和上面的一样先将请求给协调者节点随后定位到Data数据节点但是在查询数据再到返回数据的过程中需要经历过两个阶段的操作。
因为es底层使用的是倒排索引因此第一步是先将需要查询带有关键字的数据全部查询出来随后携带那一行数据的id再通过id查询这就是相当于要查询两次用mysql来解释就是通过一个加了索引的字段进行数据查询随后将携带的id进行回表操作
query phase第一步就是这个先将全部的数据返回给协调者节点再协调者节点中进行过滤、排序等操作fetch phase第二步就是根据第一步所确定的结果通过数据的id再进行一次查询工作将数据返回
3.3数据读写优化
上面了解了读写的底层原理在知道原理之后那么就可以根据原理进行优化操作。
读取数据优化
如在读取数据时减少这种通配符查询、前缀查询等需要全文检索的查询如不需要算分的字段可以使用精确查询使用Filter Context利用内部的缓存机制减少不必要的算分结合profile、explain分析查询慢的问题等
写入数据优化
在写入数据时可以使用批量插入数据来增加系统的吞吐量或者使用多线程的方式插入数据
分片优化
除了在查询优化也可以在分片上做优化数据量不大的情况可以使用单分片数据量大使用多分片时需要防止分片过多带来的开销。对于这种时间序列的查询可以强制的force merge将不需要的文档删除从而减少这种segment的数量。
除了上面的几中优化之外还可以对服务端硬件设备等进行优化还可以调节这个refresh的频率进行优化、调整translog写入磁盘的频率进行调整等。如下面的这个模板设置refresh刷新时间translog刷盘等
DELETE myindex
PUT myindex
{settings: {index: {refresh_interval: 30s, #30s一次refreshnumber_of_shards: 2},routing: {allocation: {total_shards_per_node: 3 #控制分片避免数据热点}},translog: {sync_interval: 30s,durability: async #降低translog落盘频率},number_of_replicas: 0},mappings: {dynamic: false, #避免不必要的字段索引必要时可以通过update by query
索引必要的字段properties: {}}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/87947.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!