ElasticSearch入门学习
文章目录
一、elasticsearch简介
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。
1、elasticSearch的使用场景
1、 为用户提供按关键字查询的全文搜索功能。
2、 实现企业海量数据的处理分析的解决方案。大数据领域的重要一份子,如著名的ELK框架(ElasticSearch,Logstash,Kibana)。
2、与其他数据存储进行比较
redis | mysql | elasticsearch | hbase | hadoop/hive | |
---|---|---|---|---|---|
容量/容量扩展 | 低 | 中 | 较大 | 海量 | 海量 |
查询时效性 | 极高 | 中等 | 较高 | 中等 | 低 |
查询灵活性 | 较差 k-v模式 | 非常好,支持sql | 较好,关联查询较弱,但是可以全文检索,DSL语言可以处理过滤、匹配、排序、聚合等各种操作 | 较差,主要靠rowkey, scan的话性能不行,或者建立二级索引 | 非常好,支持sql |
写入速度 | 极快 | 中等 | 较快 | 较快 | 慢 |
一致性、事务 | 弱 | 强 | 弱 | 弱 | 弱 |
3、elasticsearch的特点
3.1天然分片,天然集群
es 把数据分成多个shard,多个shard可以组成一份完整的数据,这些shard可以分布在集群中的各个机器节点中。随着数据的不断增加,集群可以增加多个分片,把多个分片放到多个机子上,已达到负载均衡,横向扩展。
在实际运算过程中,每个查询任务提交到某一个节点,该节点必须负责将数据进行整理汇聚,再返回给客户端,也就是一个简单的节点上进行Map计算,在一个固定的节点上进行Reduces得到最终结果向客户端返回。
这种集群分片的机制造就了elasticsearch强大的数据容量及运算扩展性。
3.2天然索引
ES 所有数据都是默认进行索引的,这点和mysql正好相反,mysql是默认不加索引,要加索引必须特别说明,ES只有不加索引才需要说明。
而ES使用的是倒排索引和Mysql的B+Tree索引不同。
全文搜索引擎目前主流的索引技术就是倒排索引的方式。
传统的保存数据的方式都是
记录→单词
而倒排索引的保存数据的方式是
单词→记录
基于分词技术构建倒排索引:
首先每个记录保存数据时,都不会直接存入数据库。系统先会对数据进行分词,然后以倒排索引结构保存。
lucene 倒排索引结构
可以看到 lucene 为倒排索引(Term Dictionary)部分又增加一层Term Index结构,用于快速定位,而这Term Index是缓存在内存中的,但mysql的B+tree不在内存中,所以整体来看ES速度更快,但同时也更消耗资源(内存、磁盘)。
二、elasticsearch的基本概念
1、对象名词解释
cluster | 整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。 |
---|---|
node | 集群中的一个节点,一般只一个进程就是一个node |
shard | 分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。(7.0默认改为1片) |
index | index相当于table |
type | 对表的数据再进行划分,比如“区”的概念。但是实际上对数据查询优化的作用有限,比较鸡肋的设计。(6.x只允许建一个,7.0之后被废弃) |
document | 类似于rdbms的 row、面向对象里的object |
field | 相当于字段、属性 |
2、服务状态查询
- GET /_cat/indices?v 查询各个索引状态
表头的含义
※ health 索引的健康状态
※ index 索引名
※ pri 索引主分片数量
※ rep 索引复制分片 数
※ store.size 索引主分片 复制分片 总占用存储空间
※ pri.store.size 索引总占用空间, 不计算复制分片 占用空间
- GET /_cat/health?v 服务整体状态查询
※ cluster 集群名称
※ status 集群状态 green代表健康(所有主分片都正常而且每个主分片都至少有一个副本,集群状态);yellow代表分配了所有主分片,但至少缺少一个副本,此时集群数据仍旧完整,主片副本都在单点;red代表部分主分片不可用,可能已经丢失数据。
※ node.total 代表在线的节点总数量
※ node.data 代表在线的数据节点的数量
※ shards active_shards 存活的分片数量
※ pri active_primary_shards 存活的主分片数量 正常情况下 shards的数量是pri的两倍。
※ relo relocating_shards 迁移中的分片数量,正常情况为 0
※ init initializing_shards 初始化中的分片数量 正常情况为 0
※ unassign unassigned_shards 未分配的分片 正常情况为 0
※ pending_tasks 准备中的任务,任务指迁移分片等 正常情况为 0
※ max_task_wait_time 任务最长等待时间
※ active_shards_percent 正常分片百分比 正常情况为 100%
- GET /_cat/nodes?v 查询各个节点状态
※ heap.percent 堆内存占用百分比
※ ram.percent 内存占用百分比
※ cpu CPU占用百分比
※ master *表示节点是集群中的主节点
※ name 节点名
- GET /_cat/shards/xxxx 查询某个索引的分片情况
※ index 索引名称
※ shard 分片序号
※ pri rep p表示该分片是主分片, r 表示该分片是复制分片
※ store 该分片占用存储空间
※ node 所属节点节点名
※ docs 分片存放的文档数
三、DSL语法
https://blog.****.net/qq_43297252/article/details/106884010
四、关于shard的划分注意点
由于索引是以天为单位进行建立,如果业务线很多,每个索引又不注意控制分片,日积月累下来一个集群几万到几十万个分片也是不难见到的。
1 shard太多带来的危害
每个分片都有Lucene索引,这些索引都会消耗cpu和内存。
shard的目的是为了负载均衡让每个节点的硬件充分发挥,但是如果分片多,在单个节点上的多个shard同时接受请求,并对本节点的资源形成了竞争,实际上反而造成了内耗。
2 如何规划shard数量
1) 根据每日数据量规划shard数量
以按天划分索引情况为例,单日数据评估低于10G的情况可以只使用一个分片,高于10G的情况, 单一分片也不能太大不能超过30G。所以一个200G的单日索引大致划分7-10个分片。
2) 根据堆内存规划shard数量
另外从堆内存角度,一个Elasticsearch服务官方推荐的最大堆内存是32G。一个10G分片,大致会占用30-80M堆内存,那么对于这个32G堆内存的节点,最好不要超过1000个分片。
3) 及时归档冷数据。
4) 降低单个分片占用的资源消耗,具体方法就是:合并分片中多个segment。
3 对Segment(段)的优化
由于es的异步写入机制,后台每一次把写入到内存的数据refresh(默认每秒)到磁盘,都会在对应的shard上产生一个segment。
segment太多的危害:
这个segment上的数据有着独立的Lucene索引。日积月累,如果一个shard是由成千上万的segment组成,那么性能一定非常不好,而且消耗内存也大。
官方优化:
如果尽可能的把小的segment合并成为大segment,这样既节省内存又提高查询性能。于是Es 后台实际上会周期性的执行合并segment的任务。
问题:
但是由于ES担心这种合并操作会占用资源,影响搜索性能(事实上也确实很有影响尤其是在有写操作的时候)。所以有很多内置的限制和门槛设置的非常保守,导致很久不会触发合并,或者合并效果不理想。
手动优化:
可如果是以天为单位切割索引的话,我们其实是可以明确的知道只要某个索引只要过了当天,就几乎不会再有什么写操作了,这个时候其实是一个主动进行合并的好时机。
可以利用如下语句主动触发合并操作:
POST movie_index0213/_forcemerge?max_num_segments=1
验证查询语句:
GET _cat/indices/?s=segmentsCount:desc&v&h=index,segmentsCount,segmentsMemory,memoryTotal,storeSize,p,r
操作:
POST movie_index0213/_forcemerge?max_num_segments=1
验证查询语句:
GET _cat/indices/?s=segmentsCount:desc&v&h=index,segmentsCount,segmentsMemory,memoryTotal,storeSize,p,r