搜索引擎是对数据进行检索,数据总体分为两种:结构化数据和非结构化数据。
- 结构化数据:也称行数据,是由二维表来逻辑 表达和实现的数据,严格遵循数据格式和长度规范,主要通过关系型数据库进行存储和管理。只具有固定格式或有限长度的数据。
- 非结构化数据:也称全文数据,不定长和无固定的格式,不适于数据库和二维表来表现。
二维表:excel就是一个二维表,行记录一个信息叫做元组,列记录一个信息叫做字段
根据两种数据分类,搜索也相应分为两种:结构化数据搜索和非结构化数据搜索。 - 结构化数据,因为他们具有特定的结构,所以我们一般都是可以通过关系型数据库的二维表的方式存储和搜索,也可以建立索引
- 非结构化数据,对全文数据的搜索主要有两种方法:顺序扫描法,全文检索
- 顺序扫描法:通过文字名称也可了解到它的大概搜索方式,即按照顺序扫描的方式查询特定的关键字
- 全文搜索:将非结构化数据一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
Elasticearch:ES是使用Java编写的一种开源搜索引擎,它在内部使用lucene做索引与搜索,通过lucene的封装,隐藏了lucene的复杂性,取而代之的提供一套简单一致的RESTful API。 Elasticsearch是一个分布式、可扩展、实时的搜索引擎与数据分析引擎
ES核心概念:
- 集群:Elasticsearch本身实现了集群的管理功能。ES集群由一个或多个Elasticsearch节点组成,每个节点配置相同的cluster.name即可加入集群。确保不同环境中使用不同集群名称,否则最终会导致节点加入错误的集群。
-
1.发现机制:
一个Elasticsearch服务启动实列就是一个节点(Node)。节点通过node.name来设置节点名称,如果不设置则在启动时给节点分配一个随机通用唯一标识符作为名称
ES内部是ZenDiscovery通过一个相同的设置cluster.name就能将不同的节点连接到同一个集群 -
2.节点的角色:每个节点既可以是候选主节点也可以是数据节点。
-
数据节点负责数据的存储和相关的操作。数据的增、删、改、查、聚合等操作
-
候选主节点可以被选举为主节点,集群中只有候选主节点才有选举权和被选举权;其他节点不参与选举的工作。主节点负责创建索引、删除索引、跟踪那些节点是集群的一部分,并决定那些分片分配给相关的节点、追踪集群中节点的状态等,稳定的主节点对集群的健康是非常重要的。
主节点和其他节点之间通过ping方式互相检查,主节点负责ping所有其他节点,判断是否有节点已经挂掉。其他节点也通过ping的方式判断主节点是否处于可用状态 -
3.脑裂现象:由于网络或其他原因导致集群同时选举出多个Master节点,使得数据更新时出现不一致,这种现象称之为脑裂,即集群中不同的节点对于master的选择出现了分歧,出现了多个master竞争。
"脑裂"能由以下几个原因造成:
-
节点负载:主节点的角色即为master又为data,访问量较大时可能会导致ES停止响应
-
网络问题:集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片
-
内存回收:主节点的角色即为master又为data,当data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应
-
- 分片:ES支持PB级全文搜索,当索引上的数据量太大的时候,ES通过水平拆分的方式将一个索引上的数据拆分出来分配到不同的数据块上,拆分出来的数据库块称之为一个分片。类似于分库分表,ES内部自身实现了此功能。在一个多分片的索引写入数据时,通过路由来确定具体写入那一个分片中,所以创建的时候需要指定分片的数量,并且分片的数量一旦确定就不能修改。
- 副本:就是对分片的Copy,每个分片都有一个或多个副本分片,当主分片异常时,副本可以提供数据的查询等操作。副本越多,集群的可用性就越改。
- 映射:是用于定义ES对索引中的字段的存储类型、分词方式和是否存储等信息,对字段类型根据格式自动识别的映射称之为动态映射,我们创建索引时具体定义字段类型的映射称之为静态映射
ES的基本使用
- 使用时要考虑版本问题
- 检查集群的运行状况:集群的状态通过绿、黄、红来标识
- 绿色:集群健康完好,一切功能齐全正常,所有分片和副本都可以正常工作
- 黄色:预警状态,所有主分片功能正常,但至少有一个副本是不能正常工作。此时集群是可以正常工作,但高可用是在某种程度上会受影响
- 红色:集群不可正常使用。某个或某些分片及其副本异常不可用,这是集群的查询操作还能执行,但是返回的结果会不准确。对于分配到这个分片的写入请求将会报错,最终会导致数据的丢失。
ES的机制原理
- 写索引原理:写索引是只能写在主分片上,然后同步到副本分片上。这个流程是在ES的内存中执行的,数据被分配到特定的分片和副本上之后,最终是存储到磁盘上的,这样在断电的时候就不会丢失数据。
- 存储原理:
- 分段存储:索引文件被拆分为多个子文件,则每个子文件叫做段,每一个段本身都是一个倒排索引,并且段具有不变性,一旦索引的数据被写入硬盘,就不可再更改。
- 延迟写策略:每当有新增的数据时,就将其写入到内存中,在内存和磁盘之间是文件系统缓存,当达到默认的时间或者内存的数据达到一定量时,会触发一次刷新,将内存中的数据生成到一个新的段上并缓存到文件缓存系统上,稍后再被刷新到磁盘中并生成提交点
- 段合并:由于自动刷新流程每秒会创建一个新的段,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段然后合并查询结果,所以段越多,搜索也就越慢。 Elasticsearch通过后台定期进行段合并来解决这个问题。小的段被合并到大的段,然后大的段被合并为更大的段。段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档不会被拷贝到新的大段中。合并的过程不会中断索引和搜索。
ES调优:
- 存储设备:Elasticsearch重度使用磁盘,你的磁盘能处理的吞吐量越大,你的节点就越稳定。优化磁盘I/O的技巧:
- 使用SSD
- 使用RAID
- 使用多块硬盘
- 不要使用远程挂载的存储
- 内部索引优化:为了能快速找到某个term,先将所有的term排个序,根据二分法查找
- JVM调优:
- 确保堆内存最小值与最大值的大小是相同的,防止程序在运行时改变堆内存大小。
- GC默认采用CMS的方式,并发但是有STW的问题,可以考虑使用G1收集器。
- ES非常依赖文件系统缓存,快速搜索。一般来说,应该至少确保物理上有一半的可用内存分配到文件系统缓存。