优化经验
elasticsearch优秀实践
Elasticsearch • jingpeiyang 发表了文章 • 0 个评论 • 9958 次浏览 • 2018-11-09 11:34
Elasticsearch在数据湖中的地位
- 解读Elasticsearch:
- 定位: ElasticSearch作为高扩展分布式搜索引擎,主要满足于海量数据实时存储与检索、全文检索与复查查询、统计分析。在如今大数据时代已经成为较popular的存储选择。
- 特点: 由于Elasticsearch使用java作为开发语言、使用lucene作为核心处理索引与检索,尤其是使用简单的RestApi隐藏lucene的复杂,使得上手非常容易、海量数据索引与检索极快。es集群由于分片和副本的机制实现了自动容错、高可用、易扩展。
- 开源且流行: Elasticsearch支持插件机制,社区活跃度高、官网更新频繁:提供了分析插件、同步插件、hadoop插件、es-sql插件、可视化插件、性能监控插件等,可以让我们站在巨人的肩膀上专心研究搜索需求
- 不支持: 不支持频繁更新、关联查询、事务
最优部署架构
角色划分
-
es分为三种角色: master、client、data,三种角色根据elasticsearch.yml配置中node.master、node.data区分,分别为true false、false false、true true
-
master: 该节点不和应用创建连接,主要用于元数据(metadata)的处理,比如索引的新增、删除、分片分配等,master节点不占用io和cpu,内存使用量一般
-
client: 该节点和检索应用创建连接、接受检索请求,但其本身不负责存储数据,可当成负载均衡节点,client节点不占用io、cpu、内存
-
data: 该节点和索引应用创建连接、接受索引请求,该节点真正存储数据,es集群的性能取决于该节点个数(每个节点最优配置情况下),data节点会占用大量的cpu、io、内存
- 各节点间关系: master节点具备主节点的选举权,主节点控制整个集群元数据。client节点接受检索请求后将请求转发到与查询条件相关的的data节点的分片上,data节点的分片执行查询语句获得查询结果后将结果反馈至client,在client对数据进行聚合、排序等操作将最终结果返回给上层请求
资源规划
- master节点: 只需部署三个节点,每个节点jvm分配2-10G,根据集群大小决定
- client节点: 增加client节点可增加检索并发,但检索的速度还是取决于查询所命中的分片个数以及分片中的数据量。如果不清楚检索并发,初始节点数可设置和data节点数一致,每个节点jvm分配2-10
- data节点: ①单个索引在一个data节点上分片数保持在3个以内;②每1GB堆内存对应集群的分片保持在20个以内;③每个分片不要超过30G。
- data节点经验:
- 如果单索引每个节点可支撑90G数据,依此可计算出所需data节点数 。
- 如果是多索引按照单个data节点jvm内存最大30G来计算,一个节点的分片保持在600个以内,存储保持在18T以内。
- 主机的cpu、io固定,建议一台主机只部署一个data节点,不同角色节点独立部署,方便扩容
- 每条数据保持在2k以下索引性能大约3000-5000条/s/data节点,增加data节点数可大幅度增加索引速率,节点数与索引效率的增长关系呈抛物线形状
优秀的插件与工具
-
ik分词器: es默认分词器只支持英文分词,ik分词器支持中文分词
-
head数据查询工具: 类似于mysql的Navicat
-
logstash: 数据处理管。采样各种样式、大小的数据来源,实时解析和转换数据,选择众多输出目标导出数据
-
x-pack性能监控: 获取进程运行时资源与状态信息并存储至es中。可通过kibana查看es、logstash性能指标,试用版包括集群状态、延迟、索引速率、检索速率、内存、cpu、io、磁盘、文件量等还可以看到集群数据负载均衡时的情况。商用版还支持安全、告警等功能
-
kibana可视化工具: es的可视化工具可制作各种图表,可在该工具上执行dsl语句灵活操作es
-
es-sql: 用sql查询elasticsearch的工具,将封装复杂的dsl语句封装成sql
-
beats: 轻量级的数据采集工具,可监控网络流量、日志数据、进程信息(负载、内存、磁盘等),支持docker镜像的file采集
-
repository-hdfs: 该插件支持将es中离线数据转存至hdfs中长期存储
Elasticsearch优化经验
-
参数调优
-
开启内存锁,禁止swapping
执行linux命令(临时生效)
ulimit -l unlimited
修改主机配置:/etc/security/limits.conf
* soft memlock unlimited * hard memlock unlimited
修改es配置:config/elasticsearch.yml
bootstrap.memory_lock : true
-
调大文件描述符数量
执行linux命令(临时生效)
ulimit -n 65535
修改linux配置文件:/etc/security/limits.conf
* soft nofile 65536 * hard nofile 65536
-
调大最大映射数
执行linux命令(临时生效)
sysctl -w vm.max_map_count=262144
修改linux配置文件:/etc/sysctl.conf
vm.max_map_count=262144
-
-
索引配置
-
settings:{efresh_interval}:数据写入刷新间隔,默认1s,调整增加该值可以减少写入压力、增加写入速度,如设为60
{ "settings": { "refresh_interval": "60s" } }
-
mappings:{dynamic}: 禁止es自动创建字段,仅允许预先设定好的字段存入es,防止索引结构混乱
{ "mappings": { "mytype": { "dynamic": false } } }
-
_all:建议禁用
{ "_all": { "enable": false } }
-
keyword字段属性: ingore_above超过多少字符不写入,keyword一般用于精确查询,不能写入太长。
{ "name": { "type": "keyword", "ingore_above": 1000 } }
-
index属性:将 不作为查询字段的index值设为false
{ { "content": { "type": "text", "index": "false" } } }
-
-
JVM内存溢出处理
防止es节点内存溢出后处于僵死状态且无法恢复,影响整个集群,在进程出现OOM时让进程宕掉,退出ES集群并引发告警,然后重启。 在config/jvm.options中增加JVM启动参数:
-XX:+ExitOnOutOfMemoryError
该参数在jdk 1.8.0_92版本上线
-
数据生命周期
es中的开启状态的索引都会占用堆内存来存储倒排索引,过多的索引会导致集群整体内存使用率多大,甚至引起内存溢出。所以需要根据自身业务管理历史数据的生命周期,如近3个月的数据开启用于快速查询;过去3-6月的数据索引关闭以释放内存,需要时再开启;超过6个月的可以生成快照保存至hdfs并删除索引,需要的时候从hdfs选择需要的索引恢复至集群中进行查询
生产上常常使用logstash+索引模板的方式按照一定时间创建新的索引,例如按天创建索引,索引的命名可能是index-yyyy-mm-dd,每天生产不同的索引,清除历史数据时可直接关闭或删除
需要注意的是:如何按照logstash默认的时间分割索引会有8个小时的误差,所以需要在logstash中将真实数据中的时间字段作为分割条件,保障按照业务时间分割索引
-
路由查询
在将数据写入es时,指定一个字段作为路由字段,es会将该字段进行hash计算写入到对应的分片上;查询时根据查询条件中的路由值,直接查找所在的分片,大幅度提高查询速度。
需要注意的是:路由字段必须是随机分布,否则会导致分片数据不平均引发的主机存储使用不平均,可以作为路由字段的:如业务流水、省份、系统编码等。
-
过滤器
ES中的查询操作分为2种:查询(query)和过滤(filter),查询默认会计算每个返回文档的得分,然后根据得分排序;而过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档。单从性能考虑,过滤比查询更快而且更节省io资源。过滤适合在大范围筛选数据,而查询则适合精确匹配数据。开发时应先使用过滤操作过滤数据,然后使用查询匹配数据
-
查询限制
限制是为了保证es集群的稳定性。限制的内容包括:查询范围、单次查询数量等,过大的查询范围不仅会导致查询效率低,而且会是es集群资源耗费急剧增加,甚至引起es集群崩溃;单次查询数量限制是为了保证内存不会被查询内存大量占用,就是分页原理,es默认可以查询10000条数据
-
批量导入
如果你在做大批量导入,考虑通过设置
index.number_of_replicas: 0
关闭副本。把每个索引的index.refresh_interval
改到 -1关闭刷新。导入完毕后再开启副本和刷新
elasticsearch优秀实践
Elasticsearch • jingpeiyang 发表了文章 • 0 个评论 • 9958 次浏览 • 2018-11-09 11:34
Elasticsearch在数据湖中的地位
- 解读Elasticsearch:
- 定位: ElasticSearch作为高扩展分布式搜索引擎,主要满足于海量数据实时存储与检索、全文检索与复查查询、统计分析。在如今大数据时代已经成为较popular的存储选择。
- 特点: 由于Elasticsearch使用java作为开发语言、使用lucene作为核心处理索引与检索,尤其是使用简单的RestApi隐藏lucene的复杂,使得上手非常容易、海量数据索引与检索极快。es集群由于分片和副本的机制实现了自动容错、高可用、易扩展。
- 开源且流行: Elasticsearch支持插件机制,社区活跃度高、官网更新频繁:提供了分析插件、同步插件、hadoop插件、es-sql插件、可视化插件、性能监控插件等,可以让我们站在巨人的肩膀上专心研究搜索需求
- 不支持: 不支持频繁更新、关联查询、事务
最优部署架构
角色划分
-
es分为三种角色: master、client、data,三种角色根据elasticsearch.yml配置中node.master、node.data区分,分别为true false、false false、true true
-
master: 该节点不和应用创建连接,主要用于元数据(metadata)的处理,比如索引的新增、删除、分片分配等,master节点不占用io和cpu,内存使用量一般
-
client: 该节点和检索应用创建连接、接受检索请求,但其本身不负责存储数据,可当成负载均衡节点,client节点不占用io、cpu、内存
-
data: 该节点和索引应用创建连接、接受索引请求,该节点真正存储数据,es集群的性能取决于该节点个数(每个节点最优配置情况下),data节点会占用大量的cpu、io、内存
- 各节点间关系: master节点具备主节点的选举权,主节点控制整个集群元数据。client节点接受检索请求后将请求转发到与查询条件相关的的data节点的分片上,data节点的分片执行查询语句获得查询结果后将结果反馈至client,在client对数据进行聚合、排序等操作将最终结果返回给上层请求
资源规划
- master节点: 只需部署三个节点,每个节点jvm分配2-10G,根据集群大小决定
- client节点: 增加client节点可增加检索并发,但检索的速度还是取决于查询所命中的分片个数以及分片中的数据量。如果不清楚检索并发,初始节点数可设置和data节点数一致,每个节点jvm分配2-10
- data节点: ①单个索引在一个data节点上分片数保持在3个以内;②每1GB堆内存对应集群的分片保持在20个以内;③每个分片不要超过30G。
- data节点经验:
- 如果单索引每个节点可支撑90G数据,依此可计算出所需data节点数 。
- 如果是多索引按照单个data节点jvm内存最大30G来计算,一个节点的分片保持在600个以内,存储保持在18T以内。
- 主机的cpu、io固定,建议一台主机只部署一个data节点,不同角色节点独立部署,方便扩容
- 每条数据保持在2k以下索引性能大约3000-5000条/s/data节点,增加data节点数可大幅度增加索引速率,节点数与索引效率的增长关系呈抛物线形状
优秀的插件与工具
-
ik分词器: es默认分词器只支持英文分词,ik分词器支持中文分词
-
head数据查询工具: 类似于mysql的Navicat
-
logstash: 数据处理管。采样各种样式、大小的数据来源,实时解析和转换数据,选择众多输出目标导出数据
-
x-pack性能监控: 获取进程运行时资源与状态信息并存储至es中。可通过kibana查看es、logstash性能指标,试用版包括集群状态、延迟、索引速率、检索速率、内存、cpu、io、磁盘、文件量等还可以看到集群数据负载均衡时的情况。商用版还支持安全、告警等功能
-
kibana可视化工具: es的可视化工具可制作各种图表,可在该工具上执行dsl语句灵活操作es
-
es-sql: 用sql查询elasticsearch的工具,将封装复杂的dsl语句封装成sql
-
beats: 轻量级的数据采集工具,可监控网络流量、日志数据、进程信息(负载、内存、磁盘等),支持docker镜像的file采集
-
repository-hdfs: 该插件支持将es中离线数据转存至hdfs中长期存储
Elasticsearch优化经验
-
参数调优
-
开启内存锁,禁止swapping
执行linux命令(临时生效)
ulimit -l unlimited
修改主机配置:/etc/security/limits.conf
* soft memlock unlimited * hard memlock unlimited
修改es配置:config/elasticsearch.yml
bootstrap.memory_lock : true
-
调大文件描述符数量
执行linux命令(临时生效)
ulimit -n 65535
修改linux配置文件:/etc/security/limits.conf
* soft nofile 65536 * hard nofile 65536
-
调大最大映射数
执行linux命令(临时生效)
sysctl -w vm.max_map_count=262144
修改linux配置文件:/etc/sysctl.conf
vm.max_map_count=262144
-
-
索引配置
-
settings:{efresh_interval}:数据写入刷新间隔,默认1s,调整增加该值可以减少写入压力、增加写入速度,如设为60
{ "settings": { "refresh_interval": "60s" } }
-
mappings:{dynamic}: 禁止es自动创建字段,仅允许预先设定好的字段存入es,防止索引结构混乱
{ "mappings": { "mytype": { "dynamic": false } } }
-
_all:建议禁用
{ "_all": { "enable": false } }
-
keyword字段属性: ingore_above超过多少字符不写入,keyword一般用于精确查询,不能写入太长。
{ "name": { "type": "keyword", "ingore_above": 1000 } }
-
index属性:将 不作为查询字段的index值设为false
{ { "content": { "type": "text", "index": "false" } } }
-
-
JVM内存溢出处理
防止es节点内存溢出后处于僵死状态且无法恢复,影响整个集群,在进程出现OOM时让进程宕掉,退出ES集群并引发告警,然后重启。 在config/jvm.options中增加JVM启动参数:
-XX:+ExitOnOutOfMemoryError
该参数在jdk 1.8.0_92版本上线
-
数据生命周期
es中的开启状态的索引都会占用堆内存来存储倒排索引,过多的索引会导致集群整体内存使用率多大,甚至引起内存溢出。所以需要根据自身业务管理历史数据的生命周期,如近3个月的数据开启用于快速查询;过去3-6月的数据索引关闭以释放内存,需要时再开启;超过6个月的可以生成快照保存至hdfs并删除索引,需要的时候从hdfs选择需要的索引恢复至集群中进行查询
生产上常常使用logstash+索引模板的方式按照一定时间创建新的索引,例如按天创建索引,索引的命名可能是index-yyyy-mm-dd,每天生产不同的索引,清除历史数据时可直接关闭或删除
需要注意的是:如何按照logstash默认的时间分割索引会有8个小时的误差,所以需要在logstash中将真实数据中的时间字段作为分割条件,保障按照业务时间分割索引
-
路由查询
在将数据写入es时,指定一个字段作为路由字段,es会将该字段进行hash计算写入到对应的分片上;查询时根据查询条件中的路由值,直接查找所在的分片,大幅度提高查询速度。
需要注意的是:路由字段必须是随机分布,否则会导致分片数据不平均引发的主机存储使用不平均,可以作为路由字段的:如业务流水、省份、系统编码等。
-
过滤器
ES中的查询操作分为2种:查询(query)和过滤(filter),查询默认会计算每个返回文档的得分,然后根据得分排序;而过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档。单从性能考虑,过滤比查询更快而且更节省io资源。过滤适合在大范围筛选数据,而查询则适合精确匹配数据。开发时应先使用过滤操作过滤数据,然后使用查询匹配数据
-
查询限制
限制是为了保证es集群的稳定性。限制的内容包括:查询范围、单次查询数量等,过大的查询范围不仅会导致查询效率低,而且会是es集群资源耗费急剧增加,甚至引起es集群崩溃;单次查询数量限制是为了保证内存不会被查询内存大量占用,就是分页原理,es默认可以查询10000条数据
-
批量导入
如果你在做大批量导入,考虑通过设置
index.number_of_replicas: 0
关闭副本。把每个索引的index.refresh_interval
改到 -1关闭刷新。导入完毕后再开启副本和刷新