Elasticesearch内存详解——1.基础

社区Elasticsearch
1. cluster 集群

多个节点组合在一起就形成了一个集群,在每个ES节点中,我们可以通过配置集群的名称来使各个节点组合在一起,成为一个集群。当某些节点的集群名称一样,ES会自动根据配置文件中的地址找到这些节点,然后就自动组成一个集群了,这一切都是ES自动来完成的,所以说ES的分布式扩展性很强,在这些节点中可以随时增加和删除节点不用费一点精力。    

picture.image

2.node  节点

ES的时候是在一台服务器上安装ES,其实这就是一个节点(Node),由ES是分布式的,所以我们可以在多台服务器上安装ES,这样我们就有了多个节点。

picture.image

3.index 索引、type类型、Document文档

(逻辑命名空间,它映射到一个或多个主分片,并且可以具有零个或多个副本分片)类似mysql中的数据库

type 文档的逻辑容器,类似表,在 Elasticsearch 6.0 以后,一个 Index 只能含有一个 type。在默认的情况下是 _doc。在 8.0 的版本中,type 将被彻底删除

Document 文档  就是 mysql里的一条记录,ES的最小单元。

查看索引信息:

curl -XGET http://localhost:9200/twitter/_settings?pretty

4 share 分片

share,Elasticsearch 提供了将索引划分成多份的能力,这些份就叫做分片(shard)。

每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。

有两种类型的分片:Primary shard 和 Replica shard

Primary shard: 每个文档都存储在一个 Primary shard。 索引文档时,它首先在Primary shard 上编制索引,然后在此分片的所有副本上(replica)编制索引。索引可以包含一个或多个主分片。

Replica shard: 每个主分片可以具有零个或多个副本。 副本是主分片的副本,有两个目的:

增加故障转移:如果主要故障,可以将副本分片提升为主分片。

提高性能:get 和 search 请求可以由主 shard

永远不会在与其主分片相同的节点上启动副本分片

默认情况下,Elasticsearch 为每个索引创建一个主分片和一个副本。

picture.image

下面的图表示的是一个 index 有 5 个 shard 及 1 个 replica

分配多个分片和副本是分布式搜索功能设计的本质,提供高可用性和快速访问索引中的文档。

主副本和副本分片之间的主要区别在于,只有主分片可以接受索引请求。副本和主分片都可以提供查询请求

picture.image

如果一个 index 显示的是红色,表面这个 index 至少有一个 primary shard 没有被正确分配,并且有的 shard 及其相应的 replica 已经不能正常访问。

如果是绿色,表明 index 的每一个 shard 都有备份 (replica),并且其备份也成功复制在相应的replica shard 之中。

如果其中的一个 node 坏了,相应的另外一个 node 的 replica将起作用,从而不会造成数据的丢失。

获得index健康情况

http://localhost:9200/_cat/indices/twitter

yellow 标识RS PS在同一个node中,无法高可用

http://localhost:9200/_cat/shards

picture.image

5.内存架构

Elasticsearch能控制的是On Heap内存部分,这部分由JVM管理;Off Heap由Lucene管理,负责缓存倒排索引数据空间(Segment Memory)。

同时堆内内存又分为可以 GC 和不可以 GC,不可 GC 的部分采用 LRU 方式进行缓存更新。

picture.image

picture.image

设置Elasticsearch内存的方式:

       1、设置变量的方式: export ES_HEAP_SIZE=32G   该方式比较好

       2、启动es时添加启动差数: -Xmx 32G -Xms 32G  ,Xmx和Xms的大小最好一样,防止程序在运行时改变大小。

将最小堆大小(Xms)和最大堆大小(Xmx)设置为彼此相等

防止内存抖动

 

给多大的堆内存?

给ES的内存配置不是越大越好,建议不能超过32GB,不同jdk版本最大边界值是不同的,对于32位小于32G JVM才采用内存对象指针压缩技术,不然对象指针需要占用很大的内存; 一旦你越过那个神奇的30-32G的边界,指针就会切回普通对象的指针,意味着就算给ES100G的内存,ES仍然最多使用30-32G的内存;

 

预留一半的内存给lucene

 

假如设备的内存是64G , 那就要预留出32G的内存给Lucene,Lucene的设计目的是把底层OS里的数据缓存到内存中。Lucene的段是分别存储到单个文件中的,这些文件都是不会变化的,所以很利于缓存,同时操作系统也会把这些段文件缓存起来,以便更快的访问。

建议是把50%的内存给elasticsearch,剩下的50%也不会没有用处的,Lucene会很快吞噬剩下的这部分内存

Elasticsearch最大分配32G内存的原因:

   1、内存对于Elasticsearch来说绝对是重要的,用于更多的内存数据提供更快的操作。而且还有一个内存消耗大户-Lucene

Lucene的设计目的是把底层OS里的数据缓存到内存中。Lucene的段是分别存储到单个文件中的,这些文件都是不会变化的,所以很利于缓存,同时操作系统也会把这些段文件缓存起来,以便更快的访问。

Lucene的性能取决于和OS的交互,如果你把所有的内存都分配给Elasticsearch,不留一点给Lucene,那你的全文检索性能会很差的。

最后标准的建议是把50%的内存给elasticsearch,剩下的50%也不会没有用处的,Lucene会很快吞噬剩下的这部分内存。不要超过32G

   2、不分配大内存给Elasticsearch,事实上jvm在内存小于32G的时候会采用一个内存对象指针压缩技术。

在java中,所有的对象都分配在堆上,然后有一个指针引用它。指向这些对象的指针大小通常是CPU的字长的大小,不是32bit就是64bit,这取决于你的处理器,指针指向了你的值的精确位置。

对于32位系统,内存最大可使用4G。64系统可以使用更大的内存。但是64位的指针意味着更大的浪费,因为你的指针本身大了。浪费内存不算,更糟糕的是,更大的指针在主内存和缓存器之间移动数据的时候,会占用更多的带宽。

java 使用一个叫内存指针压缩的技术来解决这个问题。它的指针不再表示对象在内存中的精确位置,而是表示偏移量。这意味着32位的指针可以引用40亿个对象,而不是40亿个字节。最终,也就是说堆内存长到32G的物理内存,也可以用32bit的指针表示。

一旦你越过那个神奇的30-32G的边界,指针就会切回普通对象的指针,每个对象的指针都变长了,就会使用更多的CPU内存带宽,也就是说你实际上失去了更多的内存。事实上当内存到达40-50GB的时候,有效内存才相当于使用内存对象指针压缩技术时候的32G内存。

这段描述的意思就是说:即便你有足够的内存,也尽量不要超过32G,因为它浪费了内存,降低了CPU的性能,还要让GC应对大内存。

 

swapping 是性能的坟墓

内存交换到磁盘对服务器性能来说是致命的。想想看一个内存的操作必须是快速的。 如果内存交换到磁盘上,一个100微秒的操作可能变成10毫秒,再想想那么多10微秒的操作时延累加起来。不难看出swapping对于性能是多么可怕。 最好的办法就是在你的操作系统中完全禁用swapping

暂时禁用:sudo swapoff -a

永久禁用:

修改参数的方法是修改/etc/sysctl.conf文件,加入vm.swappiness=xxx,并重起系统。这个操作相当于是修改虚拟系统中的/proc/sys/vm/swappiness文件,将值改为XXX数值。

如果不想重起,可以通过sysctl -p动态加载/etc/sysctl.conf文件,但建议这样做之前先清空swap。

 

以上系统参数配置完成,还要修改elasticsearch.yml配置:

bootstrap.memory_lock : true 锁定内存,防止进行内存的交换使用swapping

0
0
0
0
关于作者
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论