Elasticsearch7从入门到精通(简介部署原理开发ELK)
Posted 王亭_666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch7从入门到精通(简介部署原理开发ELK)相关的知识,希望对你有一定的参考价值。
Elasticsearch7从入门到精通(简介、部署、原理、开发、ELK)第1章.Elasticsearch简介
1-1.Elasticsearch介绍
-
Elasticsearch官方网站:https://www.elastic.co/cn/elasticsearch/
-
Elasticsearch是一个基于Lucene的搜索服务器
Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。
-
提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口
-
Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎
-
Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、php、Python、Apache Groovy、Ruby和许多其他语言都可以使用
-
根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎
搜索引擎分类,Elasticsearch已经遥遥领先,其次是Apache Solr也较为出名,两者都是基于Lucene
DB-Engines官网:https://db-engines.com/en/ranking
- Elasticsearch的创始人是:Shay Banon (谢巴农)
1-2.Elasticsearch使用场景
-
信息检索
- 百度搜索
- 淘宝京东主页商品搜索
- CSDN主页关键词搜索
- …
-
企业内部系统搜索
-
公司内网系统的OA、CRM、ERP搜索
- 关系型数据库使用like进行模糊检索,会导致索引失效,效率低下
- 可以基于Elasticsearch来进行高效检索
-
-
数据分析引擎
- Elasticsearch 聚合可以对数十亿行日志数据进行聚合分析,探索数据的趋势和规律
1-3.Elasticsearch知名企业使用场景
- 2013年初,GitHub抛弃了Solr,采取ElasticSearch 来做PB级的搜索。“GitHub使用ElasticSearch搜索20TB的数据,包括13亿文件和1300亿行代码”
- 维基百科:启动以elasticsearch为基础的核心搜索架构
- SoundCloud:“SoundCloud使用ElasticSearch为1.8亿用户提供即时而精准的音乐搜索服务”
- 百度:百度目前广泛使用ElasticSearch作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部20多个业务线(包括casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,每天导入30TB+数据
- 新浪使用ES分析处理32亿条实时日志
- 阿里使用ES构建挖财自己的日志采集和分析体系
1-4.Elasticsearch特点
-
海量数据处理
- 大型分布式集群(数百台规模服务器)
- 处理PB级数据
- 也支持单机运作
-
开箱即用
- 简单易用,操作相对便捷
- 可快速部署生产环境
-
可作为传统数据库的功能补充
-
传统关系型数据库不擅长全文检索
mysql自带的全文索引,与ES性能差距非常大
-
传统关系型数据库无法支持搜索排名、海量数据存储、分析等功能
-
Elasticsearch可以作为传统关系数据库的补充,提供RDBM无法提供的功能
-
1-5.Elasticsearch对比Solr
Solr 和 Elasticsearch 都在快速发展,但从近几年的流行趋势来看,与 Solr 相比,Elasticsearch 具有很大的吸引力;其次,与 Solr 相比,Elasticsearch 易于安装且非常轻巧;ES 增长非常的迅速。
1-6.Elasticsearch发展历史
- 2004年,发布第一个版本名为Compass的搜索引擎,创建搜索引擎的目的主要是为了搜索食谱
- 2010年,发布第二个版本更名为Elasticsearch,基于Apache Lucene开发并开源
- 2012年,创办Elasticsearch公司
- 2015年,Elasticsearch公司更名为Elastic,是专门从事与Elasticsearch相关的商业服务,并衍生了Logstash和Kibana两个项目,填补了在数据采集、数据可视化的空白。于是,ELK就诞生了
- 2015年,Elastic公司将开源项目Packetbeat整合到Elasticsearch技术栈中,并更名为Beats,它专门用于数据采集的轻量级组件,可以将网络日志、度量、审计等各种数据作为不同的源头发送到Logstash或者Elasticsearch
- 此后ELK不再包括Elastic公司所有的开源项目,ELK开始更名为Elastic Stack,将来还有更多的软件加入其中,包括数据采集、清洗、传输、存储、检索、分析、可视化等
- 2018年,Elastic公司在纽交所挂牌上市Elastic NV
第2章.Lucene全文检索库(铺垫加深es的检索逻辑)
2-1.全文检索介绍
- 结构化数据与非结构化数据、
- 结构化数据
- 指具有固定格式或有限长度的数据
- 如数据库,元数据等
- 非结构化数据
- 指不定长或无固定格式的数据
- 如邮件,word文档等磁盘上的文件
- 结构化数据
- 搜索结构化数据和搜索非结构化数据
- 使用SQL语言专门搜索结构化的数据
- 使用ES/Lucene/Solor建立倒排索引,根据关键字就可以搜索一些非结构化的数据
- 全文检索
- 通过一个程序扫描文本中的每一个单词,针对单词建立索引,并保存该单词在文本中的位置、以及出现的次数
- 用户查询时,通过之前建立好的索引来查询,将索引中单词对应的文本位置、出现的次数返回给用户,因为有了具体文本的位置,所以就可以将具体内容读读取出来
- 类似于通过字典中的检索字表查字的过程
2-2.Lucene简介
-
Lucene是一种高性能的全文检索库,在2000年开源,最初由Doug Cutting(道格·卡丁)开发
除了Lucene,还开发了著名的网络爬虫工具Nutch,分布式系统基础架构Hadoop
-
Lucene是Apache的一个顶级开源项目,是一个全文检索引擎工具包。但Lucene不是一个完整的全文检索引擎,它只是提供一个基本的全文检索的架构,还提供了一些基本的文本分词库
-
Lucene是一个简单易用的工具包,可以方便的实现全文检索的功能
2-3.通过Lucene实现美文搜索案例
2-3-1.需求背景
在资料中的文章文件夹中,有很多的文本文件。这里面包含了几篇文章,通过搜索一个关键字就能够找到哪些文章包含了这些关键字。例如:搜索「hadoop」,就能找到hadoop相关的文章
需求分析:
方案1:
用户输入搜索关键字,遍历读取文件,并查找每个文件中是否包含关键字
方案2:
预先遍历读取文件,对每个文件的文本内容进行分词(例如:按标点符号),然后建立索引,用户输入关键字,根据之前建立的全部索引,逐个匹配搜索的关键字。
对比两种方案,方案2要比第1种效果好得多,性能也好得多。下面就使用Lucene来建立索引,然后根据索引来进行检索。
2-3-2.开发环境准备
- 创建一个Maven项目
GroupId: cn.wangting
ArtifactId: es_2022
- 创建module模块
创建完毕后,右键项目名称: es_2022 - > New -> Module 创建一个新maven模块
GroupId:cn.wangting
ArtifactId:lucene_test
- 导入模块的pom文件
注意是es_2022项目下,lucene_test模块下的pom.xml文件,不是父项目的总pom文件
E:\\20221101\\es_2022\\lucene_test\\pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>es_2022</artifactId>
<groupId>cn.wangting</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lucene_test</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>8.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>8.4.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.jianggujin</groupId>
<artifactId>IKAnalyzer-lucene</artifactId>
<version>8.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
- java下创建包和类
- 在java目录创建 cn.wangting.lucene 包结构
- 创建BuildArticleIndex类
- 导入测试文章数据
模块下创建data目录用来存放文章文件( 被处理的数据文件 )
模块下创建index目录用于存放最后生成的索引文件( 处理完毕后的输出结果文件 )
测试样例文章素材:
https://osswangting.oss-cn-shanghai.aliyuncs.com/elasticsearch/data_for_lucene_test.zip
2-3-3.建立索引库代码实现
实现步骤:
1.构建分词器(StandardAnalyzer)
2.构建文档写入器配置(IndexWriterConfig)
3.构建文档写入器(IndexWriter)
4.读取所有文件构建文档
5.文档中添加字段
字段名 | 类型 | 说明 |
---|---|---|
file_name | TextFiled | 文件名字段,需要在索引文档中保存文件名内容 |
content | TextFiled | 内容字段,只需要能被检索,但无需在文档中保存 |
path | StoredFiled | 路径字段,无需被检索,只需要在文档中保存即可 |
6.写入文档
7.关闭写入器
BuildArticleIndex类代码:
package cn.wangting.lucene;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.FSDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
public class BuildArticleIndex
public static void main(String[] args) throws IOException
// 1.构建分词器(StandardAnalyzer)
IKAnalyzer standardAnalyzer = new IKAnalyzer();
// 2.构建文档写入器配置(IndexWriterConfig)
IndexWriterConfig writerConfig = new IndexWriterConfig(standardAnalyzer);
// 3.构建文档写入器(IndexWriter,注意:需要使用Paths来)
IndexWriter indexWriter = new IndexWriter(FSDirectory.open(Paths.get("E:\\\\20221101\\\\es_2022\\\\lucene_test\\\\index")), writerConfig);
// 4.读取所有文件构建文档
File dataDir = new File("E:\\\\20221101\\\\es_2022\\\\lucene_test\\\\data");
File[] fileArray = dataDir.listFiles();
// 迭代data目录中所有的文本文件,读取文件并建立索引
for (File file:fileArray)
// 5.文档中添加字段
Document doc = new Document();
doc.add(new TextField("file_name",file.getName(), Field.Store.YES));
doc.add(new TextField("content", FileUtils.readFileToString(file),Field.Store.NO));
doc.add(new StoredField("path",file.getAbsolutePath()));
// 6.写入文档
indexWriter.addDocument(doc);
// 7.关闭写入器
indexWriter.close();
将代码执行后,在index目录会生成索引文件
有了索引库,接下来需要有一个查询类,来测试索引查询
2-3-4.关键字查询代码实现
需求:输入一个关键字,根据关键字查询索引库中是否有匹配的文档
1.前提:基于文章文本文件,已经生成好了索引
2.在cn.wangting.lucene包下创建一个类KeywordSearch
实现步骤:
1.使用DirectoryReader.open构建索引读取器
2.构建索引查询器(IndexSearcher)
3.构建词条(Term)和词条查询(TermQuery)
4.执行查询,获取文档
5.遍历打印文档(可以使用IndexSearch.doc根据文档ID获取到文档)
6.关键索引读取器
KeywordSearch
package cn.wangting.lucene;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import java.io.IOException;
import java.nio.file.Paths;
public class KeywordSearch
public static void main(String[] args) throws IOException
// 1. 使用DirectoryReader.open构建索引读取器
DirectoryReader reader = DirectoryReader.open(FSDirectory.open(Paths.get("E:\\\\20221101\\\\es_2022\\\\lucene_test\\\\index")));
// 2. 构建索引查询器(IndexSearcher)
IndexSearcher indexSearcher = new IndexSearcher(reader);
// 3. 构建词条(Term)和词条查询(TermQuery)
TermQuery termQuery = new TermQuery(new Term("content", "座位"));
// 4. 执行查询,获取文档
TopDocs topDocs = indexSearcher.search(termQuery, 50);
// 5. 遍历打印文档(使用IndexSearch.doc根据文档ID获取到文档)
ScoreDoc[] scoreDocArray = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocArray)
// 在Lucene中,每一个文档都有一个唯一ID
// 根据唯一ID就可以获取到文档
Document document = indexSearcher.doc(scoreDoc.doc);
// 获取文档中的字段
System.out.println("-------------");
System.out.println("文件名:" + document.get("file_name"));
System.out.println("文件路径:" + document.get("path"));
System.out.println("文件内容:" + document.get("content"));
// 6. 关闭索引读取器
reader.close();
输入一个关键词:”座位“,执行结果筛选出在《永远的坐票》文章中出现了关键词:座位
原文章路径均在索引定义的对应关系中:
字段名 | 类型 |
---|---|
file_name | TextFiled |
content | TextFiled |
path | StoredFiled |
2-4.倒排索引结构
倒排索引是一种建立索引的方法。是全文检索系统中常用的数据结构。通过倒排索引,就是根据单词快速获取包含这个单词的文档列表。倒排索引通常由两个部分组成:单词词典、文档
2-5.企业不直接使用Lucene原因分析
- Lucene的内建不支持分布式
- Lucene是作为嵌入的类库形式使用的,本身是没有对分布式支持
- 区间范围搜索速度非常缓慢
- Lucene的区间范围搜索API是扩展补充的,对于在单个文档中term出现比较多的情况,搜索速度会变得很慢
- Lucene只有在数据生成索引文件之后(Segment),才能被查询到,做不到实时
- 可靠性无法保障
- 无法保障Segment索引段的可靠性
第3章.Elasticsearch中的核心概念
3-1.索引-index
- 一个索引就是一个拥有几分相似特征的文档的集合。比如说,可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引
- 一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字
- 在一个集群中,可以定义任意多的索引
3-2.映射-mapping
- ElasticSearch中的映射(Mapping)用来定义一个文档
- mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置
3-3.字段-Field
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识
3-4.类型-Type
针对每一个字段都应该有一个对应的类型,例如:Text、Keyword、Byte等
3-5.文档-document
- 一个文档是一个可被索引的基础信息单元
- 某一个客户的文档
- 某一个产品的一个文档
- 某个订单的一个文档
- 文档以JSON(javascript Object Notation)格式来表示
3-6.集群-cluster
- 一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能
- 一个集群由一个唯一的名字标识在定义,这个名字默认就是“elasticsearch”
- 定义的这个名字非常重要,因为一个节点只能通过指定某个集群的名字,来加入这个集群,来发现探寻
3-7.节点-node
- 一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能
- 一个节点可以通过配置集群名称的方式来加入一个指定的集群。每个节点都会被安排加入到配置文件中定义的集群名中,例如默认的“elasticsearch”
- 如果在网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中
- 在一个集群里,可以拥有任意多个节点。而且,如果当前网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群
3-8.分片-shards
- 一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢
- Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片
- 当创建一个索引的时候,可以指定分片数量
- 每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上
- 分片允许水平分割/扩展你的内容容量
- 分片允许在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量
- 至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户来说,这些都是透明的
3-9.副本-replicas
- 在一个网络/云的环境里,任务失败或者故障随时都可能发生,在某个分片/节点出现问题导致离线状态,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许创建的分片有一份或多份拷贝,这些拷贝叫做副本分片,或者直接叫副本
- 副本在分片/节点失败的情况下,提供了高可用性。注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的
- 扩展搜索量/吞吐量,因为搜索可以在所有的副本上并行运行
- 每个索引可以被分成多个分片。一个索引有0个或者多个副本
- 一旦设置了副本,每个索引就有了主分片和副本分片,分片和副本的数量可以在索引创建的时候指定
- 在索引创建之后,可以在任何时候动态地改变副本的数量,但是不能改变分片的数量
第4章.Elasticsearch安装部署
4-1.环境准备
4-1-1.机器规划
IP地址 | 操作系统 | 主机名 |
---|---|---|
172.28.54.207 | CentOS7.8 | es01 |
172.28.54.208 | CentOS7.8 | es02 |
172.28.54.209 | CentOS7.8 | es03 |
各节点设置主机名:
# 172.28.54.207
hostnamectl set-hostname es01
# 172.28.54.208
hostnamectl set-hostname es01
# 172.28.54.209
hostnamectl set-hostname es01
4-1-2.各节点创建普通用户
ES不能使用root用户来启动,否则会报错,使用普通用户来安装启动。创建一个普通用户以及定义一些常规目录用于存放我们的数据文件以及安装包等
# 3台机器都需要执行
[root@es01 ~]# useradd wangting
[root@es01 ~]# echo wangting|passwd --stdin wangting
4-1-3.各节点将普通用户权限提高
[root@es01 ~]# visudo
# 增加一行普通用户权限内容
wangting ALL=(ALL) NOPASSWD:ALL
让普通用户有更大的操作权限,一般都会给普通用户设置sudo权限,方便普通用户的操作,避免操作时频繁输入密码
4-1-4.各节点添加hosts主机名解析
[root@es01 ~]# vim /etc/hosts
# es
172.28.54.207 es01
172.28.54.208 es02
172.28.54.209 es03
如果在各节点的/etc/hosts中都配置了节点的ip解析,那后续在配置文件中,相关的ip配置都可以用解析名代替;
例如:network.host: 172.28.54.207 等同于 network.host: es01
4-1-5.安装包准备
各组件均可以在官方找到对应版本下载:
elasticsearch:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
kibana:https://www.elastic.co/cn/downloads/past-releases#kibana
本文章所有相关组件安装包以及素材均分享在云盘:
链接:https://pan.baidu.com/s/1NI9vDPNZHJkqzNevwZFOmw?pwd=54lg
提取码:54lg可以根据需要自行获取
注意:ES相关的各组件工具,版本需要对齐一致
[root@es01 ~]# su - wangting
Last login: Wed Nov 2 15:50:21 CST 2022 on pts/0
[wangting@es01 ~]$ ll
total 533168
-rw-r--r-- 1 wangting wangting 296454172 Nov 2 15:37 elasticsearch-7.6.1-linux-x86_64.tar.gz
-rw-r--r-- 1 wangting wangting 249498863 Nov 2 15:49 kibana-7.6.1-linux-x86_64.tar.gz
4-1-6.各节点环境优化
注意各节点执行的命令,需要自行在其它每个节点去执行
优化1:
系统允许 Elasticsearch 打开的最大文件数需要修改成65536
[root@es01 ~]# vim /etc/security/limits.conf
# End of file
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 65536
# 断开重连会话
[root@es01 ~]# ulimit -n
65535
这个配置不优化启动服务会出现:
[error] max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536] elasticsearch
优化2:
允许最大进程数配置修该成4096;不是4096则需要修改优化
[root@es01 ~]# vim /etc/security/limits.d/20-nproc.conf
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.
* soft nproc 4096
root soft nproc unlimited
这个配置不优化启动服务会出现:
[error]max number of threads [1024] for user [judy2] likely too low, increase to at least [4096]
优化3:
设置一个进程可以拥有的虚拟内存区域的数量
# 增加配置项vm.max_map_count
[root@es01 ~]# vim /etc/sysctl.conf
vm.max_map_count=262144
# 重载配置
[root@es01 ~]# sysctl -p
这个配置不优化启动服务会出现:
[error]max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
4-2.安装es
4-2-1.解压安装
[wangting@es01 ~]$ sudo mkdir -p /opt/module/
[wangting@es01 ~]$ sudo chown -R wangting.wangting /opt/module/
[wangting@es01 ~]$ tar -xf elasticsearch-7.6.1-linux-x86_64.tar.gz -C /opt/module/
[wangting@es01 ~]$ cd /opt/module/elasticsearch-7.6.1/
4-2-2.修改配置文件
elasticsearch.yml
[wangting@es01 elasticsearch-7.6.1]$ cd config/
[wangting@es01 config]$ mv elasticsearch.yml elasticsearch.yml_bak
[wangting@es01 config]$ vim elasticsearch.yml
cluster.name: wangting-es
node.name: es01
path.data: /data
bootstrap.memory_lock: false
network.host: es01
http.port: 9200
bootstrap.system_call_filter: false
http.cors.enabled: true
http.cors.allow-origin: "*"
discovery.seed_hosts: ["es01", "es02", "es03"]
cluster.initial_master_nodes: ["es01", "es02"]
配置项说明:
cluster.name: wangting-es # 集群名称;同一集群各节点名称必须相同
node.name: es01 # 当前节点名称;可理解成在集群中各自用这个名称区别
path.data # 数据存储路径
path.logs # 服务日志路径
bootstrap.memory_lock: false # bootstrap自检程序
network.host: es01 # 当前节点host主机
http.port: 9200 # es启动端口
bootstrap.system_call_filter: false # 禁用系统调用过滤器
http.cors.enabled: true # 是否支持跨域
http.cors.allow-origin # 跨域范围
discovery.seed_hosts # 所有可以被检索的节点列表清单
cluster.initial_master_nodes # 用于在es集群初始化时选举主节点master
jvm.options
# 修改-Xms和-Xmx参数为2g
[wangting@es01 config]$ vim jvm.options
-Xms2g
-Xmx2g
调整jvm堆内存大小
创建data目录和log目录
[wangting@es01 ~]$ http://mageedu.blog.51cto.com/4265610/1714522?utm_source=tuicool&utm_medium=referral
各位运维同行朋友们,大家好,非常高兴能有这么个机会与大家一起交流一些技术问题。此前的各位分享达人们在技术领域或管理领域均有十分精彩的分享,他们带给我们的是多个领域中研究或实践的最前沿知识。这使我本人获益良多,首先要郑重感谢他们。
开始之前,本人首先做一下自我介绍。
马永亮,马哥Linux运维培训创始人,已直接培养Linux运维工程师一千多人,他们绝大多数从事Linux运维和相关管理岗位,就业公司包括但不限于阿里、腾讯、百度、京东、网易、新浪、搜狐、大众点评、饿了么等。课程的间接受益者数万人。
这些一线的运维或运维开发工程师不断地将知识、经验或应用趋势等反馈给我们,也因此,我们的课程体系也发展为了快速迭代和演进的模式。另外,不断地通过各种渠道指导他们解决实践中的问题的经验也成为课堂中案例的组成部分。
比如今天的分享,沿用我们的一贯方式,初衷是为那些不甚了解、即将或刚用到ELK stack的朋友们提供一个可落地的思路和实践方法。而ELK达人们还请多批评指正。
下面进入正题。今天的分享共分为如下几个组成部分。不过,如果时间上来不及,可能只会聊前两个而不及其余。
1、搜索引擎组件介绍;
2、ElasticSearch工作原理、查询及常用插件;
3、日志收集器Logstash及常见的同类工具;
4、可视化工具Kibina;
5、使用案例及优化思路;
一、关于搜索引擎
各位知道,搜索程序一般由索引链及搜索组件组成。
索引链功能的实现需要按照几个独立的步骤依次完成:检索原始内容、根据原始内容来创建对应的文档、对创建的文档进行索引。
搜索组件用于接收用户的查询请求并返回相应结果,一般由用户接口、构建可编程查询语句的方法、查询语句执行引擎及结果展示组件组成。
如图所示。
著名的开源程序Lucene是为索引组件,它提供了搜索程序的核心索引和搜索模块,例如图中的“Index”及下面的部分;而ElasticSearch则更像一款搜索组件,它利用Lucene进行文档索引,并向用户提供搜索组件,例如“Index”上面的部分。二者结合起来组成了一个完整的搜索引擎。
二、索引组件
索引是一种数据结构,它允许对存储在其中的单词进行快速随机访问。当需要从大量文本中快速检索文本目标时,必须首先将文本内容转换成能够进行快速搜索的格式,以建立针对文本的索引数据结构,此即为索引过程。
它通常由逻辑上互不相关的几个步骤组成。
第一步:获取内容。
过网络爬虫或蜘蛛程序等来搜集及界定需要索引的内容。Lucene并不提供任何获取内容的组件,因此,需要由其它应用程序负责完成这一功能,例如著名的开源爬虫程序Solr、Nutch、Grub及Aperture等。必要时,还可以自行开发相关程序以高效获取自有的特定环境中的数据。获取到的内容需要建立为小数据块,即文档(Document)。
第二步:建立文档。
获取的原始内容需要转换成专用部件(文档)才能供搜索引擎使用。
一般来说,一个网页、一个PDF文档、一封邮件或一条日志信息可以作为一个文档。文档由带“值(Value)”的“域(Field)”组成,例如标题(Title)、正文(body)、摘要(abstract)、作者(Author)和链接(url)等。不过,二进制格式的文档处理起来要麻烦一些,例如PDF文件。
对于建立文档的过程来说有一个常见操作:向单个的文档和域中插入加权值,以便在搜索结果中对其进行排序。权值可在索引操作前静态生成,也可在搜索期间才动态生成。权值决定了其搜索相关度。
第三步:文档分析。
搜索引擎不能直接对文本进行索引,确切地说,必须首先将文本分割成一系列被称为语汇单元(token)的独立原子元素,此过程即为文档分析。每个token大致能与自然语言中的“单词”对应起来,文档分析就是用于确定文档中的文本域如何分割成token序列。
此即为切词,或分词。
文档分析中要解决的问题包括如何处理连接一体的各个单词、是否需要语法修正(例如原始内容存在错别字)、是否需要向原始token中插入同义词(例如laptop和notebook)、是否需要将大写字符统一转换为小写字符,以及是否将单数和复数格式的单词合并成同一个token等。这通常需要词干分析器等来完成此类工作,Lucene提供了大量内嵌的分析器,也支持用户自定义分析器,甚至联合Lucene的token工具和过滤器创建自定义的分析链。
第四步:文档索引
在索引步骤中,文档将被加入到索引列表。事实上,Lucene为此仅提供了一个非常简单的API,而后自行内生地完成了此步骤的所有功能。
接下来,我们说搜索组件。
索引处理就是从索引中查找单词,从而找到包含该单词的文档的过程。搜索质量主要由查准率(Precision)和查全率(Recall)两个指标进行衡量。查准率用来衡量搜索系列过滤非相关文档的能力,而查全率用来衡量搜索系统查找相关文档的能力。
另外,除了快速搜索大量文本和搜索速度之后,搜索过程还涉及到了许多其它问题,例如单项查询、多项查询、短语查询、通配符查询、结果ranking和排序,以及友好的查询输入方式等。这些问题的解决,通常需要多个组件协作完成。
1、用户搜索界面
UI(User Interface)是搜索引擎的重要组成部分,用户通过搜索引擎界面进行搜索交互时,他们会提交一个搜索请求,该请求需要先转换成合适的查询对象格式,以便搜索引擎能执行查询。
2、建立查询
户提交的搜索请求通常以HTML表单或Ajax请求的形式由浏览器提交到搜索引擎服务器,因此,需要事先由查询解析器一类的组件将这个请求转换成搜索引擎使用的查询对象格式。
3、搜索查询
当查询请求建立完成后,就需要查询检索索引并返回与查询语句匹配的并根据请求排好序的文档。搜索查询组件有着复杂的工作机制,它们通常根据搜索理论模型执行查询操作。常见的搜索理论模型有纯布尔模型、向量空间模型及概率模型三种。Lucene采用了向量空间模型和纯布尔模型。
4、展现结果
查询获得匹配查询语句并排好序的文档结果集后,需要用直观、经济的方式为用户展现结果。UI也需要为后续的搜索或操作提供清晰的向导,如完善搜索结果、寻找与匹配结果相似的文档、进入下一页面等。
三、Lucene
Lucene是一款高性能的、可扩展的信息检索(IR)工具库,是由Java语言开发的成熟、自由开源的搜索类库,基于Apache协议授权。Lucene只是一个软件类库,如果要发挥Lucene的功能,还需要开发一个调用Lucene类库的应用程序。
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,而域的值则是真正被搜索的内容。每个域都有其标识名称,通常为一个文本值或二进制值。将文档加入索引中时,需要首先将数据转换成Lucene能识别的文档和域,域值是被搜索的对象。例如,用户输入搜索内容“title:elasticsearch”时,则表示搜索“标题”域值中包含单词“elasticsearch”的所有文档。
都是文字,大家可能看的眼花。参考一幅从互联网上获取的图片吧。
如前所述,ElasticSearch在底层利用Lucene完成其索引功能,因此其许多基本概念源于Lucene。
四、ES的基本概念
索引(Index)
ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。
类型(Type)
类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。
文档(Document)
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。
三者关系,如图中所示。
映射(Mapping)
ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。
节点(Node)
运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。节点通过为其配置的ES集群名称确定其所要加入的集群。
分片(Shard)和副本(Replica)
ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。
Shard有两种类型:primary和replica,即主shard及副本shard。Primary shard用于文档存储,每个新的索引会自动创建5个Primary shard,当然此数量可在索引创建之前通过配置自行定义,不过,一旦创建完成,其Primary shard的数量将不可更改。Replica shard是Primary Shard的副本,用于冗余数据及提高搜索性能。每个Primary shard默认配置了一个Replica shard,但也可以配置多个,且其数量可动态更改。ES会根据需要自动增加或减少这些Replica shard的数量。
ES集群可由多个节点组成,各Shard分布式地存储于这些节点上。
ES可自动在节点间按需要移动shard,例如增加节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。
如图所示。
ElasticSearch的RESTful API通过tcp协议的9200端口提供,可通过任何趁手的客户端工具与此接口进行交互,这其中包括最为流行的curl。curl与ElasticSearch交互的通用请求格式如下面所示。
1
2
3
4
5
6
7
curl -X<VERB>
\'<PROTOCOL>://<HOST>/<PATH>?<QUERY_STRING>\'
-d
\'<BODY>\'
VERB:HTTP协议的请求方法,常用的有GET、POST、PUT、HEAD以及DELETE;
PROTOCOL:协议类型,http或https;
HOST:ES集群中的任一主机的主机名;
PORT:ES服务监听的端口,默认为9200;
QUERY_STRING:查询参数,例如?pretty表示使用易读的JSON格式输出;
BODY:JSON格式的请求主体;
例如,查看ElasticSearch工作正常与否的信息。
1
~]$ curl
\'http://localhost:9200/?pretty\'
与ElasticSearch集群交互时,其输出数据均为JSON格式,多数情况下,此格式的易读性较差。cat API会在交互时以类似于Linux上cat命令的格式对结果进行逐行输出,因此有着较JSON好些的可读性。调用cat API仅需要向“_cat”资源发起GET请求即可。具体使用方法请查阅官方文档。
另外,ES集群的CRUD操作也非常容易进行,朋友们参考官方文档即可。
五、ES中的数据查询简介
需要注意的是,文档中每个域的值可能会存储为特定类型,而非字符串类型,因此,_all域的索引方式与特域的索引方式未必完全相同。
文档中,域的数据存储时支持“string”、“numbers”、“Booleans”和“dates”几种类型,不同类型的数据在索引时是略有区别的。在创建文档时,Elasticsearch会通过检查域的值来动态为其创建mapping,可通过Mapping API来查看type的mapping,其访问端点是_mapping。
下面,我们聊一个麻烦一点的问题,ES的精确值、full-text及倒排索引。
精确值(Exact values)就是指数据未曾加工过的原始值,而Full-text则用于引用文本中的数据。在查询中,精确值是很容易进行搜索的,但full-text则需要判断文档在“多大程度上”匹配查询请求,换句话讲,即需要评估文档与给定查询的相关度(relevant)。因此,所谓的full-text查询通常是指在给定的文本域内部搜索指定的关键字,但搜索操作该需要真正理解查询者的目的。
例如:
(1) 搜索“UK”应该返回包含“United Kingdom”的相关文档;
(2) 搜索“jump”应该返回包含“JUMP”、“jumped”、“jumps”、“jumping”甚至是“leap”的文档;
(3) 搜索“johnny walker”应该匹配包含“Johnnie Walker”的文档;
为了完成此类full-text域的搜索,ES必须首先分析文本并将其构建成为倒排索引(inverted index),倒排索引由各文档中出现的单词列表组成,列表中的各单词不能重复且需要指向其所在的各文档。因此,为了创建倒排索引,需要先将各文档中域的值切分为独立的单词(也称为term或token),而后将之创建为一个无重复的有序单词列表。这个过程称之为“分词(tokenization)”。
六、Queries and Filters
尽管统一称之为query DSL,事实上Elasticsearch中存在两种DSL:查询DSL(query DSL)和过滤DSL(filter DSL)。查询子句和过滤子句的自然属性非常相近,但在使用目的上略有区别。简单来讲,当执行full-text查询或查询结果依赖于相关度分值时应该使用查询DSL,当执行精确值(extac-value)查询或查询结果仅有“yes”或“no”两种结果时应该使用过滤DSL。
Filter DSL计算及过滤速度较快,且适于缓存,因此可有效提升后续查询请求的执行速度。而query DSL不仅要查找匹配的文档,还需要计算每个文件的相关度分值,因此为更重量级的查询,其查询结果不会被缓存。不过,得益于倒排索引,一个仅返回少量文档的简单query或许比一个跨数百万文档的filter执行起来并得显得更慢。
Filter DSL中常见的有term Filter、terms Filter、range Filter、exists and missing Filters和bool Filter。而Query DSL中常见的有match_all、match 、multi_match及bool Query。鉴于时间关系,这里不再细述,朋友们可参考官方文档学习。
Queries用于查询上下文,而filters用于过滤上下文,不过,Elasticsearch的API也支持此二者合并运行。组合查询可用于合并查询子句,组合过滤用于合并过滤子句,然而,Elasticsearch的使用习惯中,也常会把filter用于query上进行过滤。不过,很少有机会需要把query用于filter上的。
好了,朋友们,今天的分享就先到这里吧。感谢大家的时间。这些内容是我用来讲课的讲义精练出的内容,用于微信的方式分享可能显得过于啰嗦,请大家将就着看啦。