1 关于机器 配置。
内存:上亿的数据一般需要64G内存的服务器。劲量不要使用小于32G 内存的服务器。
cpu:es 对cpu 要求依赖不如内存。一般要求2-8 核就可以了。
磁盘:es 对磁盘依赖严重。Lucene 底层 是基于磁盘存储。所以 劲量使用ssd。并且 io 模式 不要设置为 cfq(适用于机械硬盘)。劲量使用deadline/noop scheduler 这两种模式。可以使用 raid 0.但是别的 格式的磁盘阵列对es 没有明显作用。es 分副本机制 本来就 有备份。避免 nas ( netword-attache-storge)等基于网络的存储。
网咯:使用内网,同机房部署 ,劲量不要跨机房部署同一个集群。 es 是 p to p 的 ,而不是 主从的 关系,节点之间通讯非常频繁。
2 es 的 集群发现机制。默认的 es 会在本机扫面 9200 到 9300 的所有端口,看是否有 es 的节点,如果找到了就组成es 集群。 一般都是 不同节点在不同主机上 可以通过 unicast host 配置指定需要扫描的主机。
discovery.zen.ping.unicast.hosts:["host1","host2","host3"]
3 es 默认的集群名字是elasticsearch 。一般建议修改这个名字。避免 奇怪的节点默认加入这个集群。
cluster.name: my-application
4 建议修改 节点名字
node.name: node-1
5 diccovery.zen.master_election.ignore_non_master_pings:true
如果设置成true 那么只有 node.master=true的 节点才可以参加选举。
6 discovery.zen.minimum_master_nodes: 2
需要多少个阶段才能组成 只是要有多少个 master 候选节点才可以选举。
7 在 安装es 的 的时候需要 ,如果 起不起来 可能是三个配置的问题。
1 jvm 内存不够。 修改 jvm 的 内存 为 180m
2 max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]、 异常
vi /etc/security/limits.conf zyk hard nofile 65536 zyk soft nofile 65536
3 max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 异常
vi /etc/sysctl.conf vm.max_map_count=655360
然后 :sysctl -p
es 的启动需要非 root 用户.
8 es 的 脑裂问题。英文名字 partition,又叫 网络分区。
配置参数 discovery.zen.minimun_master_nodes:这个的 配置应该 master候选节点/2 +1 ,描述的 是 至少有多少个 master候选节点才可以选举出 master节点。 这个参数 很重要生产中一定要设置。避免脑裂问题。
9 在集群重启的时候,部分先启动的节点组成集群的时候。这时候可能出现 检查到 primary shard 不够,然后把 replica shard 设置成 primary shard 。然后 检查到 replica 不够。有构建大量 replica shard 。等 所有节点启动以后 又 因为节点多余。而删除新的节点数据。有触发 rebalance 节点移动。的耗费资源的 问题。
我们需要设置,让大部分节点都启动以后。才检测节点的分布。
gateway.recover_after_nodes:8 这只参数至少有多少个节点上线以后,才启动恢复功能。
gateway.expected_nodes:10 设置期望节点数是多少。
gateway.recover_after_time:5m 在节点 超过 gateway.recover_after_nodes 后。但是没有达到 gateway.expected_nodes的时候。最多等待多少分钟 就开始恢复工作。如果5分钟内 10 个节点都在线了,那么立即recovery ,如果 一直不满足8 个 ,那么一直等待,满足 8 个 到时不满足10 个。等待5 分钟,然后开始恢复。
10 绝对不能随意调节 jvm gc和 thread pool 的 原因。 因为他们已经设置的 相当合理。 es 的 默认 gc 是 cms 。默认的 es 的运行线程池设置的数量是 和cpu core 一样多。es 默认的搜索线程数是 core*3/2+1.
而是的写操作一般是交个地城的Lucene 的。所以写操作不需要 es 来处理,es 线程只是把任务传递给Lucene 的线程。然后 在没有 超线程的cpu 中。一个core 在一个时间点只能运行 一个线程,如果线程太多。会导致 cpu 强制切换 线程。这需要保存线程状态。并且如果是跨cpu的线程切换还需要走cpu core 的内部通道。目前的cpu这个操作大概每次需要30微秒。所有 适量的 线程池有利于提高效率。
11 设置 es jvm heap 的大小。 es 的 jvm 默认大小是2G ,生产一般大于这个。 可以通过环境变量指定 ES_HEAP_SIZE.,es 启动的时候回去读这个变量的值。还可以通过启动 es 的时候传递一个 参数 指定 xms 和xmx 的大小 ,es 建议设置 最小堆内存和最大堆内存一样。es JAVA_OPTS="-Xms10g -Xmx10g" 。目前版本推荐 在jvm.options 里面设置。
es 的性能严重依赖 Lucene 里面的 osche 如果没有 fielddata( 这个是存在 jvm 的 对内存里面的),我们可以分1/3 内存给jvm 。剩下的都留给oscache 使用。但是新版本默认使用 fielddata 。所以 估计给jvm 一般内存比较好。不要给给jvm 分配超过32g 的内存(超过32 g java就无法使用内存指针压缩算法)。 32 位 的 系统只能 有4G 内存,2^32 = 4G 。传统指针表示的 一个2进制位。64 位系统中 。使用32 位的指针 代替 64 位置指针。来减少 cpu 和内存之间的带宽,提升效率。这里的一个指针不是代表一个 2进制位,而是一个字节。就是 8倍。所以这种算法只能有4*8 = 32 G内存。超过以后就无法使用这种指针压缩算法。64 位的指针,会大概多消耗 1/2 的内存。使用使用 jvm 内存小于 64G 以前 最好只是用32 g 。java使用 compressed oops 算法。
一般 1亿到10亿的 数据。 使用 5 台 64 个内存的机子。分配 32g 内存给jvm 32 g 给 oscache。( 如果不明白 compressed oops 不同版本系统的开启 条件 ,建议是指31 g,避免 没有开启 compressed oops )
12 如果 机子大于 64 g 建议在一台机子上运行 多个 es 节点。如果在一个 机子运行了多个es 节点需要避免 primar shard 和replic shard 在同一台机子上。
可以设置 cluster.routing.allocation.same_shard.host:true 告诉es避免在同一个物理机上设置同 主副节点。
13 关闭 虚拟内存,避免 内存 swape 到 硬盘。这会 非常影响效率。
零时关闭:swapoff -a
永久关闭 可以在 /etc/fstab 配置 配置。
如果不能关闭,那么尽量降低 swap 的 频率。
14 启动es 并且指定 配置文件位置( 一般 建议 es 的 配置文件。数据文件,日志文件 插件 都不要放在 es 的 目录下,如果es 会升级的话,到时我觉得 没有必要 es还是不要升级的好。)
./elasticsearch -d -Epath.conf=/etc/elasticsearch。
备注: /etc/elasticsearch 下面应该有 es config 目录下面的那些配置文件。
15 es 可以通过配置 ,然后 用root 用户启动 ,按时一般不 建议这样做。
es 怎么 root启动 ?
1 启动的 时候指定参数:-Des.insecure.allow.root=true
2在启动文件里面 写入: ES_JAVA_OPTS="-Des.insecure.allow.root=true" 这个好像不生效了
16 可以吧es 的 bin 加入 path。 这样可以直接运行。
17 不要使用 kill -9 ,尽量 使用 kill -sigterm 关闭。
18 基于 es hdfs 的 快照备份。 未 实验,因为不会 hadoop
待补充.................
19 es 的升级
1 查看文档,各个版本的变化
2 使用 elasticsearch migration plugin 工具在升级前检测潜在的问题( 老版本使用 ,现在不怎么用了 ?)
3 做一次全量备份
4 在测试环境 升级一次试试
5 可能需要升级插件
1 rolling upgrade 节点滚动升级升级(适合es小版本之间的升级)
1 设置 节 shard 配为禁用
设置allocation.enable:none
2 停止数据写入,并且 flush 一次
3 备份插件和jvm 配置文件
4 停掉 就版本的 es ,换旧的版本
5 升级插件
6 启动新的 es 版本
7 启动 shard 分配
设置allocation.enable:all
8 等待 shard recover 过程
新的节点不会吧副本复制给旧的版本的。因此如果只有少量 新节点这个状态不会变成 green ,这时候可以直接升级下一个节点、
9 重复下一个节点,直到所有节点完成
2 full cluster restart 全集群重启升级( 对打大版本的升级 )
几乎 和 rolling upgrade 一样。唯一的区别在于全部节点停止以后再做版本的升级,和插件的替换,所有节点 升级完成以后再逐步启动。
3 reindex ( 对跨大版本的升级)
查询旧几点的数据插入到新的节点。( 需要在 新节点吧旧节点设置成白名单 )
20 索引可以关闭。 关闭的索引不在占用内存资源,不能读写,可以重新开启。
PUT /index1/_close
PUT /index1/_open
21 索引压缩 shrink 压缩只能压缩可以减少 primary shard 的数量,但是只能整数倍的减少。比如 8 个 变成 4,或者 2 或者1
shrink 前需要 阻塞 索引的写操作,并且把 所有 完整的 这个shard 组 都复制到同一个 节点上。
22 rollover index
在使用别名队一个有别名的索引 rollover 的时候,如果满足某些条件中的一个,那么久产生一个新的索引,并且这个 别名指向新的索引。(多用于翻滚日志)
如果用-数字结尾每次就会递增,还可以支持日期的递增。
23 template 可以让 索引创建的时候,给符合名字规则的所以,使用 指定的setting 和 mapping ,别名等.....
24 indeName/_stats 索引的一些统计。
25 indeName/_segment 可以查看到 Lucene 的 segment 信息
25 indeName/_shard 可以查看到 Lucene 的 segment 信息
26 indeName/_cache/clear 清空 某个所用的 缓存。
27 indeName/_flush 吧索引的信息刷到硬盘。会清空tranlog 日志。
28 indeName/_refresh 刷新一个 索引,是这个索引之前的操作都处于课件状态
29 indeName/_forcemerge 强制合并多个索引文件,会让多个 segment 合并起来。会减少 segment 的数量。
30 总的短路器 (如果内存使用超过一定量就不执行)
indices.breaker.total.limit 配置父短路器的最大内存限制,默认是 jvm heap 内存的 70%
31 fielddata 短路器
indices.breaker.fielddata.limit 默认是 jvm heap 的 60%
32 估算因数 估算的内存 * 估算因数 如果 大于 断路器界限 那么久会被短路。
indices.breaker.fielddata.overhead 默认 1.03
33 请求断路器 如果一个请求估算的内存达到这个值就不会执行。
indices.breaker.request.limit 默认是 jvm heap 的 60%
34 请求估算因数
indices.breaker.request.overhead 默认是1
35 flight request circuit 限制 突然port或者 http 层请求的大小
network.breaker.inflight_request.limit 默认是jvm 100%
network.breaker.inflight_request.overhead 因数默认是1
36 一分钟默认 编译 的脚本数
script.max_compilations_per_minute 默认是1 分钟15 个。
37 这些断路器做的事情是 尽量保证 jvm heap 不溢出。不出现oom 异常。
38 fielddata 在jvm heap 中。排序聚合的时候 会把 fielddata 都加载到 fielddata cache 中。
indices.fielddata.cache.size 可以控制这的大小 。默认没有限制。可以指定30% 或者4G 两种格式。
39 查询缓存
indices.queries.cache.size 控制 filter 查询缓存的大小。
40 index buffer 存储最新的 docment 。但满足一定条件会flush 到oscache 和 tranlog
indices.memory.index_buffer_size 控制 index buffer 的大小 默认是 jvm 的 10%
indices.memory.min_index_buffer_size 最小的 buffer 大小 ,默认 48mb
41 shard request cache
indices.request.cache.size 默认 1% 这个是针对 查询和聚合的( 上面的 是fiter),
默认聚合的结果会缓存,search 的 结果只有 在请求的时候指定 request-cache=true才会开启。
indices.request.cache 可以对指定index 禁用,开启了了只是对默认对聚合缓存,search 缓存需要每条请求 指定。
42 indices.recovery.max_bytes_per_sec 限制没面可以恢复多少数据 默认 40mb
43 index.merge.scheduler.max_thread_count 限制 merge 操作最大使用的线程数量。 默认 是 Math.max(1,Math.min(4,Runtime.getRuntime().avalilableProcessors()/2))这个 默认值得 ssd 比较实用,如果是 机械硬盘 应该降低为1.
44 index.translog.flush_threshold_size 指定 os cache 中数据 达到多大会执行flush 。默认是512mb.
45 inde.translog.durability 设置 事务日志是不是每次都要 fsync 。默认是request ,每次写入(只要返回成功数据就不会丢)。如果是设置成 async,那么就 默认5 秒 fsync 一次。最多会丢失5 秒的数据。
46 inde.translog.sync_interval 事务日志 fsync 的 频率是多少。默认是5 秒。
47 translog 如果破损 了,可以通过 elasticsearch-translog 工具来恢复部分数据。但是这个不能在 elasticsearch 运行的时候使用,否则可能丢失数据。
elasticsearch-translog truncate -d translog文件
48 es 安装离线插件的三种方式
elasticsearch-plugin install file:///path/aaaa.plugin
elasticsearch-plugin install 在线地址
elasticsearch-plugin install 插件名
49 查看插件:elasticsearch-plugin list
删除插件: elasticsearch-plugin remove 插件名 (删除后需要重启节点)
50 es 的常见插件都有哪些?
51 node的 类型
mater eligible node mater 候选节点
data node 数据节点
ingest node 接纳节点 可以预处理
coordinate node 坐标节点 分配查询和结果统计
tribe node 部落节点 可以跨集群
52 es 的 慢查询日志.可以记录 查询时间 达到某些阈值的 查询。
53 es 的 docment 结构要尽量紧凑,要避免大量稀疏数据。要避免 不同type 存入不同的 document。如果必须存入的时候 应该 进行数据的规整化,并且 应该禁用 nroms 和 doc values。
54. 写入数据的时候尽量使用 bulk api。并且找打 合适的 bulk 条数。
55. 使用多线程 写入数据,要比单线程高。我们应该 找到合适的写入线程数。
56 如果增加 index.refresh_interval . 可以提高写入 写入性能。默认是1秒。如果我们可以接受 写入以后能以查询到的时间。那么我们可以增加这个时间来提高性能。
这个参数的意思的 多少时间 写入一次数据到磁盘( 是写到 oscache 和 taranslog 里面 )
57. 如果一次写入大量数据 可以考虑 关闭 reflush 和replica 机制.这时候不需要副本。也不需要每次 不断的刷入 磁盘。
58. 禁用 swapping 的使用。避免使用虚拟内存。
59 尽量给 es 更多的 filesystem cache ,如果内存足够,那么es 都是在内存里面 查找数据。数据 极快。
60 尽量使用 自动生成id。
手动id es 回去检查这个 id 是否存在。 自动的话,生成的时候就已经保证唯一了。不会用检查是否存在。我们业务Id 可以作为es 的一个field。
61 .给es 跟多好的硬件。 跟大内存。ssd。避免使用nas,nfs 网络存储。可以考录raio0 来 提高磁盘读写。
62 。 如果我们非常重视 写入性能,那么调高 index buffer 可以提高写入。但是这个对于每个shaed 来说,最多 512MB。多了太多作用。默认是10% 的 jvm。如果有2 个shard 在同一个机子上应为 index buffer 是2 个shard 共享的。那么设置为不超过1G
63 es 的 oscache 的内存总和 尽量要 有数据量的 一半。最好是 数据量 小于 欧式cache 可用内存数。
64 es 里面 尽量不要放一些不用于搜索的数据。最好的是 es 里面只放需要搜索的东西,然后查询出一个id ,在去别的数据库冲查询这个id。比如 放在mysql redis 。hbase 之类的。
65 不要在es 里面做一些特别复杂的操作。es 提供的是全文检索。核心不是聚合统计。如果一定要做。
建议在1.在做数据存的的前做好数据模型结构。后面 直接查询
2.查询出结果,然后在java程序里面去分析。
66 预热es。 es 重启的时候 cache 是空壳。这时候最好查询一下常用查询数据,然后这些数据就到内存中了。 后面用户查询旧很快了。
67 尽量避免适应 脚本。,因为效率低。
68 查询的 日期的时候尽量使用指定日期范围,而不要 使用now 。因为每次now 都不一样。查询缓存不生效。
69 now/m 是当前时间精确到分。
70 如果想节省磁盘空间,那么你可以根据下面你的 情况设置。银盘我们不在乎,硬盘减少了。内存也会减少一部分。 因为这些很多就是缓存在 内存里面的。
如果我们这个字段只是用于聚合统计,而不是搜索。那么我们可以禁用 倒排缩影。
如果 不关系 聚合,只关心查询。那么就可以禁用掉 doc value。
如果 这个字段只是用于搜索,不是 聚合,可以警用掉doc values。 在 mapping 里面吧index 设置成false
如果 我们不关心一个字段的 分数,那么我们可以吧这个norm是分数禁用掉。 在mapping 里面吧 norms 设置成 false。
如果 我们不需要 phrase 这种位置近似匹配, 和出现评率的 的相关数分数。那么可以吧 index_options 禁用掉。
如果需要频率,那么就 吧这个字段设置成 index_options:“freqs”
不要使用 string类型的默认映射。应为会默认建立 正排索引。
如果不需要对所有filed 搜索,那么禁用 _all