首页 文章 精选 留言 我的

精选列表

搜索[Elasticsearch],共4100篇文章
优秀的个人博客,低调大师

ElasticSearch Tune for search speed Translation

1.给文件系统缓存提供更多的内存 es严重依赖文件系统缓存来提高搜索速度。通常,为了使es将搜索保持在物理内存的热区域中,需要确保至少一般的可用内存提供给文件系统缓存 2.使用更快的硬件 如果索引速度受到I/O制约,你需要提供为文件系统缓存提供更多的内存或者升级更快的硬件设备。一般固态比机械硬盘性能更好。始终使用本地文件系统,远程文件系统像NFS以及SMB都应该避免。对例如亚马逊的EBS(elastic block storage)也要留意,es在虚拟存储上表现更好,由于更快以及易于安装使得它变得越来越受欢迎。但是不幸的是相比于本地存储虚拟存储还是有一些差距。如果你要使用EBS请注意要使用提供的IOPS否则会被限流。 如果索引速度受到CPU制约,你需要购买更快的CPU 3.文档建模 文档需要建模这样能够使得索引操作变得更快。 尤其是joins操作应该尽量避免,而嵌套(nested)会降低几倍查询速度,而父子关系(parent-child relations)查询更会使得查询以数百倍的速度下降。所以如果可以使用不规范的文档而不是使用joins也能达到同样的效果,尽量使用这些来提高速度 4.尽量使用更少的字段 query_string和multi_match的字段越多,查询越慢。提高多字段查询速度中普遍使用的一项技术就是将多个字段值拷贝到一个字段,查询的时候只需要查询这个字段即可。这可以使用映射中的copy_to 指令来做到并且该指令不会改变文档源,下面是一个例子 PUT movies { "mappings": { "_doc": { "properties": { "name_and_plot": { "type": "text" }, "name": { "type": "text", "copy_to": "name_and_plot" }, "plot": { "type": "text", "copy_to": "name_and_plot" } } } } } 5.预索引数据 你应该使用查询模式优化数据索引方式。例如,如果所有文档都有price字段,并且大多数查询都会使用固定的price 范围查询,那么我们可以事先将该范围映射到索引中来加快聚合此字段,看下面例子: 使用前: PUT index/_doc/1 { "designation": "spoon", "price": 13 } GET index/_search { "aggs": { "price_ranges": { "range": { "field": "price", "ranges": [ { "to": 10 }, { "from": 10, "to": 100 }, { "from": 100 } ] } } } } 使用后: PUT index { "mappings": { "_doc": { "properties": { "price_range": { "type": "keyword" } } } } } PUT index/_doc/1 { "designation": "spoon", "price": 13, "price_range": "10-100" } GET index/_search { "aggs": { "price_ranges": { "terms": { "field": "price_range" } } } } 6.考虑将标识符映射为关键字 事实上一些数值型字段并不一定会被映射为数值型,es在term的数值型范围查询中使用关键字会更好。典型的,字段存储的例如ISBN或者来自另一个数据库的数值型标识符号会很少被用在范围查询或聚合中,这是因为将它们映射为关键字而不是integer或long更好。 7.避免脚本 通常情况下,脚本尽量避免使用,不得已时最好也要使用painless和expressions引擎 8.搜索边界数据 使用now作为日期范围查询一般不会被缓存这是因为now一直在变化。然而就用户体验而言使用边界数据会更好,而且还有利于查询缓存。 使用前: PUT index/_doc/1 { "my_date": "2016-05-11T16:30:55.328Z" } GET index/_search { "query": { "constant_score": { "filter": { "range": { "my_date": { "gte": "now-1h", "lte": "now" } } } } } }使用后: GET index/_search { "query": { "constant_score": { "filter": { "range": { "my_date": { "gte": "now-1h/m", "lte": "now/m" } } } } } } 在这个案例中我们四舍五入到分钟,如果当前时间是16:31:29,这个查询会查询 15:31:00到 16:31:59之间的所有数据。此时如果很多用户进行包含该范围的查询,查询缓存会帮助加快速度。四舍五入的间隔越大,查询缓存越能起到作用。但是太大范围的四舍五入会影响用户体验。 我们也可以使用更大和更小的范围来四舍五入从而提高查询缓存效率 GET index/_search { "query": { "constant_score": { "filter": { "bool": { "should": [ { "range": { "my_date": { "gte": "now-1h", "lte": "now-1h/m" } } }, { "range": { "my_date": { "gt": "now-1h/m", "lt": "now/m" } } }, { "range": { "my_date": { "gte": "now/m", "lte": "now" } } } ] } } } } } 但是需要注意的是,有些情况下这种方式会适得其反,因为bool查询(在不同的时间分段中搜索)带来的开销可能会超过查询缓存带来的效率。 9.合并只读索引 将只读索引合并到单个分片中会更好,这种情况在时间索引中尤为明显,因为只有当前时间的索引才会需要写入,过时的索引只需要只读状态。 注意:对于需要写入的索引不要将其合并,另外合并可以作为一个后台进程运行 10.备份全球序数 全球序数是一个作为关键字段被用于terms聚合的数据结构。由于es并不知道哪些字段会被用于terms聚合以及哪些字段不会被用于terms聚合,所以它们一般是被懒加载到内存中。那么你可以使用es在刷新时间通过配置映射来指定某个属性是否被es以全球序数的饥渴状态来加载 PUT index { "mappings": { "_doc": { "properties": { "foo": { "type": "keyword", "eager_global_ordinals": true } } } } } 11.备份文件系统缓存 如果机器重启,文件系统缓存会被清空。这会导致操作系统加载索引到热区域之前话费一定的时间。你可以通过index.store.preload配置指定哪些被马上缓存到内存中 注意:如果文件系统缓存不足以装下所有的索引数据,立马加载大量数据到文件系统缓存中会导致查询变慢。 12.使用索引排序加快连接速度 索引排序会牺牲较少的索引速度来加快连接速度 13.使用preference来优化缓存使用率 有很多可以提高查询性能的缓存,例如文件系统缓存,请求缓存或者查询缓存。目前这些缓存都是节点级别的,这意味着连续发送两个相同的请求,在1个或多个副本的情况下,使用round-robin分布式负载均衡策略以及默认的算法,这两个请求会被路由到不同的分片,这会导致节点级别的缓存无法起到作用。 因为对于用户来说一个接一个发送相同请求是很普遍的,所以为了分析索引的较窄子集,使用标识当前用户或会话的偏好值可以帮助优化高速缓存的使用 14.复制可以帮助提高高吞吐但是有条件的 一个节点上分片越少也就意味着为该分片分配的内存越多从而提高吞吐的能力,但是这是以牺牲高可用为前提的,因为缺少了副本分片作为灾备。在这两者之间最好保持平衡,副本分片的最优数量一般是max(max_failures, ceil(num_nodes / num_primaries) - 1) max_failures:每次最多有这么多节点去处理失败。具体见官网 15.打开自适应副本选择 当存在多个副本分片时,es会使用一组称为自适应副本选择的标准,根据包含每个分片副本的节点的响应时间,服务时间和队列大小来选择最佳数据副本。这可以提高查询吞吐量并减少搜索量大的程序的延迟

优秀的个人博客,低调大师

ElasticSearch Tune for indexing speed Translation

1.使用块查询 块查询一般来说比单文档查询表现出更好的性能。为了获取快查询最佳新能,你可以在单节点地单分片上运行一个基准,第一次100个文档,第二次200个文档,然后400个,以此类推。每次基准运行的数量都是两倍于前一次的数量。当索引速度达到峰值的时候你就知道你的数据索引最佳的块文档数量。如果峰值存在于两个数量上,最好还是以最少的数量去索引。块查询数量越大也就意味着在进行同步查询的时候对内存压力也就越大。建议大家每次发送请求时不要超过几十兆尽管有时更大的请求表现地更好。 2.使用多线程发送数据到es中 使用单个线程不可能将es集群的索引性能最大化。为了充分利用es集群的资源,你应该使用多线程或进程发送数据。除了最大化集群的资源使用,这也会帮助减少非同步的成本。 注意TOO_MANY_REQUESTS(429)返回码(在java客户端中报EsRejectedExecutionException错误),这是告诉你es目前无法跟上你的索引速率。当这种情况发生时,你应该在下次发送请求之前先暂停下。理想情况下,它会自动恢复。 跟确定最佳bulk请求数量类似,只有通过测试才能知道最佳的调用者数量是多少。这可以通过增加调用者数量来测试并在I/O或CPU饱和的情况下得到结果 3.提高刷新间隔 默认情况下,index.refresh_interval是1s,意味着es会每秒创建一个新的分片,但是你可以通过增加这个值(例如30s)来增大在每个刷新间隔中创建更多的分片并能够减少未来合并的压力 4.在进行初始加载的时候禁用索引刷新和索引复制 如果你要一次性进行大量的数据加载操作,你应该通过设置index.refresh_interval为-1并设置index.number_of_replicas为0.这会让你的索引暂时处于危险之中,因为丢失任何分片都会使数据丢失,但是同时也会导致索引更快因为文档只会被索引一次。一旦初始化加载结束,应该把上面两个参数设置为原来的值 5.禁用交换机制 确保操作系统不会因为禁用交换机制来交换java进程 6.给文件系统缓存留有足够的内存空间 文件系统的缓存会被使用到因为需要缓冲I/O操作。你应当确保运行es的机器还有一般的内存留给文件系统用作缓存 7.使用自动生成的ids 当索引一个有具体id的文档时,es需要检查同一分片中是否存在匹配到该id的文档,这会花费很多时间并且在id越大的时候成本越高。通过使用自动生成的id,es会调过这些检查,这将会使得索引变得更加快速 8.使用更快的硬件 如果索引速度被I/O制约,你需要提供为文件系统缓存提供更多的内存或者升级更快的硬件设备了。一般固态比机械硬盘性能更好。始终使用本地文件系统,远程文件系统像NFS以及SMB都应该避免。对例如亚马逊的EBS(elastic block storage)也要留意,es在虚拟存储上表现更好,由于更快以及易于安装使得它变得越来越受欢迎。但是不幸的是相比于本地存储虚拟存储还是有一些差距。如果你要使用EBS请注意要使用提供的IOPS否则会被限流 通过配置RAID为一个空数组,可以让索引分配在多个SSD上,但是要注意它会增加故障风向因为任意一个SSD故障都会导致索引损坏。然而这通常是一个正确的做法:优化单个分片以获得最大性能,并且在不同的节点上添加副本分片以提高可用性。你也可以使用snapshot和restore备份索引来获得进一步的保险 9.索引缓冲区大小 如果你的节点只做高负荷的索引,确保indices.memory.index_buffer_size大到足以为每个分片提供最多512MB的索引缓冲区进行大量索引(超过512MB索引性能也不会得到显著的提升)。es会采用这个配置(java堆的百分比或者绝对值),然后使用它在所有活跃的分片中作为公用缓冲区。非常活跃的分片自然会使用更多的缓冲区空间而那些轻量级查询的分片用得更少。 默认10%足够了,例如:如果你给JVM10G的内存,它会给索引缓存区1G,这将对于两个高负荷分片提供足够的内存空间。 10.禁用_field_names _field_names字段会带来额外的索引开销,所以如果你不用运行esists查询就可以禁用它

优秀的个人博客,低调大师

ElasticSearch Tune for disk usage Translation

1.禁用不需要的属性 index:默认情况下,es会对大多数字段进行索引并添加doc值,以便可以直接索引和聚合它们,但是对于一个必须要使用的字段eg:你需要使用foo这个数值型字段展示直方图,那么这个字段永远不会被过滤掉,那么你可以安全地禁用映射中此字段的索引。 PUT index { "mappings": { "_doc": { "properties": { "foo": { "type": "integer", "index": false } } } } }text:该属性在索引中存储了作为文档计分所需要的基本的因素,如果你索引的只是文本而不关注文本分数,那么你可以配置该索引不使用norms参数 PUT index { "mappings": { "_doc": { "properties": { "foo": { "type": "text", "norms": false } } } } }text:默认情况下该属性还存储了frequencies和positions两个属性,第一个属性在积分系统中被使用到,第二个在短语查询中使用到。如果你不需要执行短语查询,那么你可以禁用positions属性 PUT index { "mappings": { "_doc": { "properties": { "foo": { "type": "text", "index_options": "freqs" } } } } } 另外,如果你不关心计分系统,你可以配置es在每个查询中仅仅索引文档。当然你也可以索引这个字段,但是短语查询将会报错并且计分系统会假定每次查询在每个文档中只会出现一次 PUT index { "mappings": { "_doc": { "properties": { "foo": { "type": "text", "norms": false, "index_options": "freqs" } } } } } 2.不要使用默认动态字符串映射 默认的动态字符串索引将字符串属性索引为文本和关键词,如果你只需要使用其中的一种这将会是很大的浪费,典型的id只需要被索引为关键字而body字段只需要被索引为文本属性。 可以通过在字符串上显式映射类型或者配置动态模板为文本或关键词来禁用上面的特性 PUT index { "mappings": { "_doc": { "dynamic_templates": [ { "strings": { "match_mapping_type": "string", "mapping": { "type": "keyword" } } } ] } } } 3.关注你的分片大小 分片越大在存储数据的时候越高效,通过使用更少的分片数量来创建索引从而减少一个索引中的主分片数量来增大分片大小或者通过使用Sharking API来修改目前已经存在的索引 注意:巨大的分片大小会带来一定的缺点,例如需要很久的恢复时间 4.禁用_all _all属性会索引一个文档中的所有字段值并且会使用巨大的空间。如果你不需要在同个时间索引所有字段,可以将_all属性禁用 5.禁用_source _source存储文档的原始json数据,如果你不需要这些可以直接禁用了。然而,像update和reindex这种需要访问_source的APIs将不起作用 6.使用best_compression _source和存储属性会很容易消耗掉不可忽视的磁盘空间。它们可以使用best_compression:codec 来进一步压缩空间 7.聚焦整合 es中的索引会被存储在一个或多个分片上。每一个分片就是一个Lucene索引并且有一个或多个片段组成,这些片段才是真正磁盘文件。越大的片段意味着越高效以及越能存储数据 _forcemerge API可以减少每个分片上的片段数量来增大每个片段的大小。在大多数情况下,每个分片的片段数量可以通过max_num_segments=1被设置为1 8.收缩索引 Shrink API帮助减少一个索引的分片数量。和上面的force_merge API一起使用可以显著地减少分片和片段的数量 9.在合适的情况下使用最小的数字类型 数值类型的类型选择将会在很大程度上影响磁盘使用率。具体地说,使用整值类型存储整数,在合适的情况下浮点数应该被存储在scaled_float中或更小的类型中。使用float而不是double,使用half_float而不是float将会帮助减少存储空间 10.使用索引排序来共置相同的文档 当es存储_source时,它会一次性压缩多个文档以提高整体压缩率。例如文档之间具有相同字段名称甚至字段值是很普遍的,特别是在基数较低或者遵循zipfian分布的情况下。 默认情况下,文档会被压缩在一起以便能够被添加到索引中,如果你提供索引排序那么它们会被有序压缩。有序并且结构,字段以及值都一样的文档会被压缩在一起以提高压缩率 11.文档字段保持相同的顺序 因为多个文档会被压缩到块中存储,如果字段遵循相同的顺序就更有可能在_source找到相同的长串。

优秀的个人博客,低调大师

ElasticSearch Reading and Writing documents Translation

开门见山,根据es官网的doc根据我自己的理解(先从网上学习了基本的es教程并在虚机上搭了一套es跑起来之后然后研究了es包中特别是conf文件夹中所有conf文件之后发现对于master节点和primaryreplication shard 还是有点confused,所以直接到官网学习这部分的doc),贴上该doc的翻译Translation: 1.介绍:es的每个索引都是被分配到分片上,每个分片都会有多个副本,这些副本组成了一个replication group,它们在文档被添加或移除时会强制保持同步。如果没有保持同步,从两个不同的副本上读取的数据可能不一样。保持分片副本同步并从中提取读取的过程就是我们所说的数据复制模型。es数据同步模型基于主备份模式并在微软研究院的PacificA这篇论文中有一个很好的描述。这个模型基于来自于replication group的单个副本,这个副本充当了主分片角色,而其他的副本就被成为副本分片。主分片作为所有索引操作的主要实体,它负责验证并确定这些索引操作是正确的。一旦某个索引操作被主分片接收,那么主分片也会负责复制这个操作到所有的副本分片。本节的目的是对es复制模型进行高级的概述,并讨论它对写入和读取操作各种交互的影响 基本的写入模型es中的所有索引操作首先都会通过路由被解析到replication group.这个机制一般是通过文档ID完成的。一旦replication group被确定了,操作将在内部转发到repicaltion group的主分片。主分片首先负责检查这个操作确定没有问题之后就会分发该操作到副本分片,由于副本分片可以拖机,所以主分片不需要分发到所有的副本分片。相反,es会保存一张含有那些应该接收到该操作的分片的列表。这个列表被称为in-sync列表,它由master节点保存。顾名思义,这个"好的"分片副本集合会保证处理那些需要向客户保证的索引和删除操作。主分片负责维持集群的不变性也因此不得不将所有的操作复制给到这个集合中的其他分片。主分片主要处理以下基本事项:1.检查进来的操作并在结构不符合预期的情况下拒绝2.本地执行操作,eg:创建或删除指定的文档,它会检查这个文本并在不符合规则的情况下拒绝该操作(索引中的关键字太长无法放入Lucene中)3.分发操作到其他处在in-sync集合中的其他副本分片,如何这个集合中的副本分片含有多个,就会异步执行4.一旦所有的in-sync集合中的副本分片执行完毕并且成功返回给了主分片,主分片就会将成功的结果反馈给客户端 故障处理在特殊情况下会导致错误发生,例如磁盘可能会损坏,节点可能会和其他节点失去练剑,或者有些错误配置导致副本分片上的操作失败尽管这些操作在主分片上是成功的。这些情况虽然是常见的,但是主分片不得不汇报这些情况。一旦主分片自己坏掉了,该分片所在的节点会向master节点汇报这件事,此时索引操作将会等待master从副本分片中选择一个分片作为新的主分片(默认等待1分钟),然后这个索引操作会被路由到这个新的主分片中。注意:master也会不断地监控节点的状态并可能决定主动降级主分片,这种情况一般发生在主分片所在的节点因为网络原因从集群中断开了。一旦主分片在本地成功执行了该索引操作,接下来主分片在副本分片上执行操作的时候可能会处理潜在的故障。这可能会因为在副本分片上发生了真实的故障或者由于网络问题阻止了请求从主分片到达副本分片(或者阻止了从副本分片到主分片的响应)。所有以上几种情况都会导致一个相同的结果:in-sync中的某个副本分片没有执行应该需要被执行的操作。为了保证稳定性,主分片会发送一个消息到master节点要求将有问题的分片及时从in-sync集合中移除。只有这个有问题的副本分片被master节点从in-sync中移除,主分片才会确认执行成功并返回到客户端。注意:master节点同时也会让另外一个节点生成一个新的副本分片从而保证存储系统处于一个健康的状态。主分片在分发操作给副本分片的时候也会通过副本分片来检测自己是否还是主分片,因为如果主分片由于网络原因失去了连接,在意识到它已经失去连接之前它还会继续向副本分片分发执行操作,但是副本分片会拒绝这些操作。当主分片接收到来自副本分片的拒绝反馈,它将会联系master节点并将接收到通知自己不再时主分片,然后它再将操作路由到新的主分片。 注意:如果没有副本分片怎么办? 这种情况在索引配置错误或者所有的副本分片都出现故障的时候是可能发生的,此时主分片在处理操作的时候没有任何其他分片的保证,这种情况看起来很糟糕。另一方面,主分片也不会让其他分片(没有)出现故障(也就是不能让自己出现故障,因为自己故障了整个单点集群就算挂了),但是会请求master节点检查自己,这样master节点就会知道只有一个好的主分片,从这个意义上我们可以说master不会让另外的节点成为新的主节点也因此所有的数据在主节点上都不会被丢失,当然因为只有一个主节点,物理机上存在的数据可能会丢失。 基础的读模式:es读取有两个方面,一个方面是通过ID进行轻量级的读取,另一方面可以在消费大量的CPU性能的情况下通过非常复杂的繁重的聚合查询。然而主备模式的美妙之处之一就是他会保持所有的副本分片都是平等的(除了飞行模式:目前不知道什么是飞行模式)。因此,in-sync中的一个节点就可以满足读操作当一个节点接收到读请求时,这个节点负责将该请求分发到与这个读请求相关的分片上去,收集rep并将结果反馈给客户端。我们称这个节点为这个请求的协同节点。基础的流程如下:1.将读请求分发给相关的分片。注意:由于大多数查找会发送一个或多个索引,它们一般需要从多个分片中读取,每一个代表整个数据的子集。2.从这个相关分片的replication group中选一个活跃分片,这个活跃分片有可能是主分片也有可能是副本分片,默认情况下,es会简单地在分片中进行循环。3.发送分片级别的读请求到被选中的分片中4.整合结果并返回,注意如果是通过ID查找,只有一个分片会是相关分片也就可以略过这步了故障处理:当一个分片因为故障不能返回结果,协同节点会从相同的replicaiton group中选取一个分片然后发送分片级别的请求给到这个分片。同样的错误也会发生在没有分片副本的情况下。在有些情况下,eg:"_search",es需要更快地返回结果时,它不会等待上面结果得到处理而是会直接返回部分结果(部分结果会被显示在返回体头部的_shards中)。 一些简单的含义:以下基本流程中的每一个都决定了es时如何作为一个读写系统的行为的。更重要的是,因为读写请求都可以同步执行,所以这两个流程可能会交互在一起。这里有一些固有的含义: 高效读取 正常情况下,对每一个相关replication group执行一次读取操作 只有在失败的情况下,相同的分片才会有多个副本进行相同的查询读取未被认证 由于主要的第一个索引在本地然后复制请求,因此并发读取可能在确 认之前已经看到了更改(关于这句话不明白什么意思)默认两个副本 此模型可以容错,同时只保留两个数据副本,这与基于法定数量的系统形成对比,其中容错的最小副本数为3 故障单个分片会拖慢整个索引速度 由于主分片在执行复制操作过程中会等待in-sync中所有副本的结果,如果一个分片速度很慢会导致整个索引速度下降,这是我们为上述阅读效率支付的代价。当然一个速度慢的分片也会拖累路由到它身上的搜索。 脏数据一个主分片在本地执行写操作之后,如果此时该分片坏了,那么就不能让其他分片进行复制操作,从而导致脏数据。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册