Elastic Search
- ELK基础
- 一、 什么是Elastic Search
- 1 相关概念
- 1.1 cluster
- 1.2 shards
- 1.3 replicas
- 1.4 recovery
- 1.5 river
- 1.6 gateway
- 1.7 discovery.zen
- 1.8 Transport
- 2 为什么不用数据库做搜索?
- 3 ES功能
- 3.1 分布式的搜索引擎和数据分析引擎
- 3.2 全文检索、结构化检索、数据分析
- 3.3 海量数据近实时处理
- 4 ES常见使用场景
- 5 ES的特点
- 1 相关概念
- 一、 什么是Elastic Search
- 二、 ES核心概念
- 1 lucene和ES的关系
- 1.1 lucene
- 1.2 ES:
- 1.3 lucene->ES的发展
- 2 ES的核心概念
- 2.1 倒排索引
- 2.2 Near Realtime (NRT)
- 2.3 Cluster&Node
- 2.4 Document
- 2.5 Index
- 2.6 Type
- 2.7 Shards
- 2.8 Replicas
- 2.9 总结
- 1 lucene和ES的关系
- 三、 Linux安装ES
- 1 升级Linux内核版本
- 2 设置启动内核版本
- 3 重启系统让内核生效
- 4 为ES提供完善的系统配置
- 4.1 修改限制信息
- 4.2 修改线程开启限制
- 4.3 修改系统控制权限
- 4.4 可选配置(建议增加)
- 5 安装ES(单机版)
- 5.1 修改ES应用的所有者
- 6 安装ES(集群版)
- 6.2 在集群中配置分词器
- 7 安装Kibana
- 8 简单Kibana命令
- 8.1 查看健康状态
- 8.2 检查分片信息
- 8.3 设置磁盘限制
- 8.4 查看索引信息
- 8.5 新增索引
- 8.5 新增索引
- 8.6 修改索引
- 8.7 删除索引
- 8.8 总结:索引不可变
- 8.8.1 倒排索引不可变的好处
- 8.8.2 倒排索引不可变的坏处
- 8.9 新增Document
- 8.10.2 GET _mget批量查询
ELK基础
一、 什么是Elastic Search
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到近实时搜索,稳定,可靠,快速,安装使用方便。官方网站
1 相关概念
1.1 cluster
代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
1.2 shards
代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改(primary shard)。 水平扩容时,需要重新设置分片数量,重新导入数据。
1.3 replicas
代表索引副本(replica shard),es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
1.4 recovery
代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
1.5 river
代表es的一个数据源,也是其它存储方式(如:数据库)同步数据到es的一个方法。它是以插件方式存在的一个es服务,通过读取river中的数据并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia的。
1.6 gateway
代表es索引快照的存储方式,es默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘。gateway对索引快照进行存储,当这个es集群关闭再重新启动时就会从gateway中读取索引备份数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和amazon的s3云存储服务。
1.7 discovery.zen
代表es的自动发现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。
1.8 Transport
代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)。
2 为什么不用数据库做搜索?
查询语法复杂度高。 如:电商系统中查询商品数据 - select * from products where name like ‘%关键字%’ and price bewteen xxx and yyy and …。不同的用户提供的查询条件不同,需要提供的动态SQL过于复杂。 关键字索引不全面,搜索结果不符合要求。 如:电商系统中查询商品数据,条件为商品名包含’笔记本电脑’。那么对此关键字的分析结果为-笔记本、电脑等。对应的查询语法应该为 - select * from products where name like ‘%笔记本%’ or name like ‘%电脑%’ … 效率问题。 数据量越大,查询反应效率越低。
3 ES功能
3.1 分布式的搜索引擎和数据分析引擎
分布式:使用多节点分部存储海量数据,多节点同时提供服务。 搜索:类似百度搜索引擎的功能。 数据分析:电商中的销量排行,新闻中的点击访问排行等。
3.2 全文检索、结构化检索、数据分析
- 全文检索 - 搜索商品名包含某关键字的信息。 select * from products where name like ‘%xxx%’
- 结构化检索 - 搜索某种类的商品信息。 select * from products where category=‘xxx’
- 数据分析 - 分析每个商品种类中有多少商品。 select category_name, count(*) from category group by category_name
3.3 海量数据近实时处理
通过分布式实现海量数据近实时处理。 近实时处理:在秒级别的时间内对数据进行处理和分析。(如果处理时长过长,如:1小时,则成为离线批处理【batch-processing,如:在电信营业厅登记查询最近3年的通话记录,需要3天后再取结果】)
4 ES常见使用场景
- 维基百科,全文检索,高亮显示,搜索推荐
- The Guardian(国外的一个新闻网站),此平台可以对用户的行为(点击、浏览、收藏、评论)、社区网络数据(对新闻的评论等)进行数据分析,为新闻的发布者提供相关的公众反馈。
- Stack Overflow(国外的程序异常讨论论坛)
- Github(开源代码管理),在千亿级别的代码行中搜索信息
- 电商网站
- 日志数据分析 - ELK技术
- 商品价格监控网站,在网站中设置商品价格监控,达到监控值的时候,会自动提示用户。
- BI系统,商业智能,Business Intelligence。如电信企业对不同地点的消费情况,进行分析,得到地方性套餐设定的建议。(ES实现数据的分析和挖掘、Kibana进行数据可视化)
- 站内搜索,如电商、招聘、门户、企业内部系统等。
- 数据分析
5 ES的特点
- 分部集群,单机处理。可大可小
- ES不是新技术,是将全文检索和数据分析、分布式整合到一起。
- 开箱即用。对中小型应用(数据量小,操作简单)来说,部署简单(默认部署),3分钟可部署使用。
- 补充数据库在现在互联网领域中的不足,如:全文检索、同义词处理、相关度排名、复杂数据分析、海量数据近实时处理等。
二、 ES核心概念
1 lucene和ES的关系
1.1 lucene
最先进、功能最强大的搜索库,基于lucene开发很复杂。(API复杂度高,需要深入理解内部原理【索引结构等】)
1.2 ES:
- 基于lucene开发,提供简单的restful api接口、java api接口、其他语言开发接口等。
- 实现了分布式的文档存储引擎,可支持PB级别的海量数据。
- 实现了分布式的搜索引擎和分析引擎。
- 开箱即用,优秀的默认参数,不需要任何额外设置,完全开源。
1.3 lucene->ES的发展
ES核心开发程序员,失业后,陪妻子在伦敦学习厨师课程。学习期间帮妻子写了一个菜谱搜索引擎,觉得lucene太复杂,就开发封装了一个lucene的开源应用-compass。后来重新工作后,做分布式高性能项目,觉得compass功能不足,开发了ES,实现了lucene的分布式系统。可见外国程序员和国内程序员的思维区别。
2 ES的核心概念
2.1 倒排索引
对数据进行分析,抽取出数据中的词条,以词条作为key,对应数据的存储位置作为value,实现索引的存储。这种索引称为倒排索引。
2.2 Near Realtime (NRT)
近实时。有两层概念, 从写入数据到可搜索数据有一个延迟(1秒左右,分析写入数据的过程); 基于ES执行搜索和分析可以达到秒级别的响应。
2.3 Cluster&Node
- Cluster-集群。包含多个节点,每个节点通过配置来决定属于哪一个集群(默认集群命名为“elasticsearch”)。对于中小型应用来说,最初只有一个节点也是很正常的。
- Node-节点。集群中的一个节点,节点的名字默认是随机分配的。节点名字在运维管理时很重要,节点默认会自动加入一个命名为“elasticsearch”的集群,如果直接启动多个节点,则自动组成一个命名为“elasticsearch”的集群。当然单节点启动也是一个集群。
2.4 Document
文档。ES中的最小数据单元。一个Document就是一条数据,一般使用JSON数据结构表示。每个Index下的Type中都可以存储多个Document。一个Document中有多个field,field就是数据字段。如:
代码语言:javascript复制product document
{
"product_id":1,
"product_name":"xxx",
.....
}
注意:不要在Document中描述java对象的双向关联关系。在转换为JSON字符串的时候会出现无限递归问题。
2.5 Index
索引。包含若干相似结构的Document数据。如:客户索引,订单索引,商品索引等。一个Index包含多个Document,也代表一类相似的或相同的Document。如:订单索引中存放了所有的订单数据(就是所有的订单Document)
2.6 Type
类型。每个索引中都可以有若干Type,Type是Index中的一个逻辑分类,同一个Type中的Document都有相同的field。 示例:订单索引,不同状态的订单包含不同的内容,如:未支付订单(自动取消时间)和已支付订单(支付时间)、已发货订单(发货时间、物流信息)等都有不同的内容。 ES6.x版本之后,type概念被弱化,一个index中只能有唯一的一个type。且在7.x版本之后,会删除type定义。
2.7 Shards
primary shard
2.8 Replicas
replica shard。 一个index默认10个shard,5个primary shard,5个replica shard。最小的高可用配置需要2台服务器。因为ES要求primary shard和replica shard不能处于同一个节点中。
2.9 总结
一个index分配到多个shard上,primary shard和他对应的replica shard不能在同一个节点中存储。
三、 Linux安装ES
使用的ES的版本是6.3.1。ES6.x要求Linux内核必须是3.5 版本以上。
在linux操作系统中,查看内核版本的命令是: uname -a
Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
使用的LInux是CentOS6.5。内核使用的是2.6。内核版本不满足要求。无法安装ES。必须升级内核。
1 升级Linux内核版本
系统内核的提升,对已部署的应用一般没有影响,但是新版本内核,对线程的资源给与了更多的空间。如:低版本内核每个线程分配128K内存,高版本内核可能分配256K内存。 注册内核
代码语言:javascript复制rpm –import http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7
下载内核安装包
代码语言:javascript复制rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
安装内核新版本
代码语言:javascript复制yum --enablerepo=elrepo-kernel install kernel-lt -y
2 设置启动内核版本
修改的是Linux系统的引导文件。
代码语言:javascript复制vim /etc/grub.conf
修改内容:
代码语言:javascript复制default=1 -> default=0
3 重启系统让内核生效
使用命令: reboot
4 为ES提供完善的系统配置
ES在Linux中安装部署的时候,需要系统为其提供若干系统配置。如:应用可启动的线程数、应用可以在系统中划分的虚拟内存、应用可以最多创建多少文件等。
4.1 修改限制信息
代码语言:javascript复制vi /etc/security/limits.conf
是修改系统中允许应用最多创建多少文件等的限制权限。Linux默认来说,一般限制应用最多创建的文件是65535个。但是ES至少需要65536的文件创建权限。修改后的内容为:
代码语言:javascript复制* soft nofile 65536
* hard nofile 65536
4.2 修改线程开启限制
代码语言:javascript复制vi /etc/security/limits.d/90-nproc.conf
是修改系统中允许用户启动的进程开启多少个线程。默认的Linux限制root用户开启的进程可以开启任意数量的线程,其他用户开启的进程可以开启1024个线程。必须修改限制数为4096 。因为ES至少需要4096的线程池预备。ES在5.x版本之后,强制要求在linux中不能使用root用户启动ES进程。所以必须使用其他用户启动ES进程才可以。
代码语言:javascript复制* soft nproc 4096
root soft nproc unlimited
注意:Linux低版本内核为线程分配的内存是128K。4.x版本的内核分配的内存更大。如果虚拟机的内存是1G,最多只能开启3000 个线程数。至少为虚拟机分配1.5G以上的内存。
4.3 修改系统控制权限
代码语言:javascript复制vi /etc/sysctl.conf
系统控制文件是管理系统中的各种资源控制的配置文件。ES需要开辟一个65536字节以上空间的虚拟内存。Linux默认不允许任何用户和应用直接开辟虚拟内存。 新增内容为:
代码语言:javascript复制vm.max_map_count=655360
使用命令: sysctl -p
。 让系统控制权限配置生效。
4.4 可选配置(建议增加)
修改elasticsearch的配置文件,设置可访问的客户端。0.0.0.0代表任意客户端访问。 vi config/elasticsearch.yml 修改下述内容
代码语言:javascript复制network.host: 0.0.0.0
5 安装ES(单机版)
ES是java开发的应用。在6.3.1版本中,要求JDK至少是1.8.0_131版本以上。 ES的安装过程非常简单。解压立刻可以使用。
代码语言:javascript复制tar -zxf elasticsearch-6.3.1.tar.gz
5.1 修改ES应用的所有者
因为ES不允许root用户启动,而案例中,ES是root用户解压缩的。所以解压后的ES应用属于root用户。所以我们需要将ES应用的所有者修改为其他用户。当前案例中虚拟机Linux内有bjsxt这个用户。
代码语言:javascript复制chown -R bjsxt.bjsxt elasticsearch
5.2 切换用户并启动
代码语言:javascript复制su bjsxt
$es_home/bin/elasticsearch
5.3 测试连接
代码语言:javascript复制curl http://192.168.2.119:9200
返回如下结果:
代码语言:javascript复制{
"name" : "L6WdN7y",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "s7_GSd9YQnaH10VQBKCQ5w",
"version" : {
"number" : "6.3.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "eb782d0",
"build_date" : "2018-06-29T21:59:26.107521Z",
"build_snapshot" : false,
"lucene_version" : "7.3.1",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
6 安装ES(集群版)
代码语言:javascript复制共享模式下:
useradd sxt
echo sxt | passwd --stdin sxt
su sxt
root 用户创建 /opt/sxt/es(普通用户无法创建)
mkdir -p /opt/sxt/es (注意:此时的目录权限属于root)
在附近目录尚学堂下执行: chown sxt:sxt es
单节点模式下root用户:
安装解压程序
ftp拷贝至根目录下,或者software目录下(备用,可选)
切换回sxt用户(共享模式,可以看到software内容)
单节点模式:
使用sxt用户解压es2.2.1zip包至es目录,保证es文件属于用户sxt:
unzip elasticsearch-2.2.1.zip -d /opt/sxt/es
进入es/conf, 修改elastic配置文件:
修改:
---------------cluster-------------------------
cluster.name: bjsxt-es
----------------node-------------------------------
node.name: node06 (分发后各节点修改)
----------------network--------------------------------
network.host: 192.168.133.6 (分发后修改)
http.port:9200 (放开)
末尾增加防脑裂:
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["192.168.133.6","192.168.133.7", "192.168.133.8"]
discovery.zen.ping_timeout: 120s
client.transport.ping_timeout: 60s
增加图形可视化插件:
[root@node06 software]# cp -abr plugins/ /opt/sxt/es/elasticsearch-2.2.1/
分发其他节点:
scp -r ./elasticsearch-2.2.1/ sxt@node07:`pwd`
scp -r ./elasticsearch-2.2.1/ sxt@node08:`pwd`
修改配置文件
进入bin目录,启动脚本:
[root@node06 bin]# ./elasticsearch
6.2 在集群中配置分词器
代码语言:javascript复制1.关闭es集群
2.共享模式sxt用户plugins下创建ik目录
3.ftp上传1个节点ik分词器到software目录下(便于拷贝)
4.plugins下sxt用户同步创建 ik目录
3.拷贝ik压缩包到software目录下,使用sxt用户解压 unzip -d (或者root用户拷贝压缩包到ik目录下,使用sxt解压)
4.修改ik的 vi plugin-descriptor.properties 配置文件,版本变为2.2.1 (/xxx 搜索)
# plugins with the incorrect elasticsearch.version.
elasticsearch.version=2.2.1
5.将 ik分发给别的节点:scp -r ik/ sxt@node07:`pwd`
6.重启动集群
7 安装Kibana
是ES提供的一个基于WEB的管理控制台。现阶段安装Kibana主要是为了方便学习。 在Linux中安装Kibana很方便。解压,启动即可。Kibana要求的环境配置是小于ES的要求的。
代码语言:javascript复制tar -zxf kibana-6.3.1-linux-x86_64.tar.gz
修改config/kibana.yml 新增内容:
代码语言:javascript复制server.host: "0.0.0.0"
$kibana_home/bin/kibana
访问时,使用浏览器访问http://ip:5601/
8 简单Kibana命令
8.1 查看健康状态
代码语言:javascript复制GET _cat/health?v
8.2 检查分片信息
查看索引的shard信息。
代码语言:javascript复制GET _cat/shards?v
代码语言:javascript复制PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.disk.watermark.low": "95%",
"cluster.routing.allocation.disk.watermark.high": "5gb"
}
}
注意: 配置磁盘空间限制的时候,要求low必须比high大。可以使用百分比或gb的方式设置。且ES要求low至少满足磁盘95%的容量。 此处配置的百分比都是磁盘的使用百分比,如85%,代表磁盘使用了85%后如何限制。配置的GB绝对值都是剩余空间多少。 low - 对磁盘空闲容量的最低限制。默认85%。 high - 对磁盘空闲容量的最高限制。默认90%。 如:low为50gb。high为10gb。则当磁盘空闲容量不足50gb时停止分配replica shard。 当磁盘空闲容量不足10gb时,停止分配shard,并将应该在当前结点中分配的shard分配到其他结点中。 强调:red问题。因为ES中primary shard是主分片,要求必须全部活动才能正常使用。
8.3 设置磁盘限制
ES默认当磁盘空间不足15%时,会禁止分配replica shard。可以动态调整ES对磁盘空间的要求限制,命令如下:
8.4 查看索引信息
代码语言:javascript复制GET _cat/indices?v
8.5 新增索引
代码语言:javascript复制PUT /test_index
8.5 新增索引
代码语言:javascript复制PUT /test_index
在ES中,默认的创建索引的时候,会分配5个primary shard,并为每个primary shard分配一个replica shard。在ES中,默认的限制是:如果磁盘空间不足15%的时候,不分配replica shard。如果磁盘空间不足5%的时候,不再分配任何的primary shard。 创建索引时指定分片。
代码语言:javascript复制PUT /test_index
{
"settings":{
"number_of_shards" : 2,
"number_of_replicas" : 1
}
}
8.6 修改索引
注意:索引一旦创建,primary shard数量不可变化,可以改变replica shard数量。
代码语言:javascript复制PUT /test_index/_settings
{
"number_of_replicas" : 2
}
ES中对shard的分布是有要求的。有其内置的特殊算法。ES尽可能保证primary shard平均分布在多个节点上。Replica shard会保证不和他备份的那个primary shard分配在同一个节点上。
8.7 删除索引
代码语言:javascript复制DELETE /test_index [, other_index]
8.8 总结:索引不可变
索引不可变的原因是倒排索引不可变。
8.8.1 倒排索引不可变的好处
不需要锁,提升并发能力,避免锁问题。数据不变,可以缓存在OS cache中(前提是cache足够大)。filter cache始终在内存中,因为数据是不可变的。可以通过压缩技术来节省CPU和IO的开销。
8.8.2 倒排索引不可变的坏处
倒排索引不可变,导致了ES中的index不可变。只要index的结构发生任何变化,都必须重建索引。重建索引的具体实现方式在后续课程中讲解。
8.9 新增Document
在索引中增加文档。在index中增加document。 ES有自动识别机制。如果增加的document对应的index不存在。自动创建,如果index存在,type不存在自动创建。如果index和type都存在,则使用现有的。
8.9.1 PUT语法 此操作为手工指定id的Document新增方式。
代码语言:javascript复制PUT /index_name/type_name/id{field_name:field_value}
如:
代码语言:javascript复制PUT /test_index/my_type/1
{
"name":"test_doc_01",
"remark":"first test elastic search",
"order_no":1
}
PUT /test_index/my_type/2
{
"name":"test_doc_02",
"remark":"second test elastic search",
"order_no":2
}
PUT /test_index/my_type/3
{
"name":"test_doc_03",
"remark":"third test elastic search",
"order_no":3
}
结果
代码语言:javascript复制{
"_index": "test_index", 新增的document在什么index中,
"_type": "my_type", 新增的document在index中的哪一个type中。
"_id": "1", 指定的id是多少
"_version": 1, document的版本是多少,版本从1开始递增,每次写操作都会 1
"result": "created", 本次操作的结果,created创建,updated修改,deleted删除
"_shards": { 分片信息
"total": 2, 分片数量只提示primary shard
"successful": 1, 数据document一定只存放在index中的某一个primary shard中
"failed": 0
},
"_seq_no": 0, 执行的序列号
"_primary_term": 1 词条比对。
}
8.9.2 POST语法 此操作为ES自动生成id的新增Document方式。 语法:POST /index_name/type_name{fieldname:fieldvalue} 如:
代码语言:javascript复制POST /test_index/my_type
{
"name":"test_doc_04",
"remark":"forth test elastic search",
"order_no":4
}
注意:在ES中,一个index中的所有type类型的Document是存储在一起的,如果index中的不同的type之间的field差别太大,也会影响到磁盘的存储结构和存储空间的占用。如:test_index中有test_type1和test_type2两个不同的类型,type1中的document结构为:{"_id":“1”,“f1”:“v1”,“f2”:“v2”},type2中的document结构为:{"_id":“2”,“f3”:“v3”,“f4”:“v4”},那么ES在存储的时候,统一的存储方式是{"_id":“1”,“f1”:“v1”,“f2”:“v2”,“f3”:"",“f4”:""}, {"_id":“2”,“f1”:"",“f2”:"",“f3”:“v3”,“f4”,“v4”}、建议,每个index中存储的document结构不要有太大的差别。尽量控制在总计字段数据的10%以内。
8.10 查询Document 8.10.1 GET查询
代码语言:javascript复制GET /index_name/type_name/id
如:
代码语言:javascript复制GET /test_index/my_type/1
结果
代码语言:javascript复制{
"_index": "test_index",
"_type": "my_type",
"_id": "1",
"_version": 1,
"found": true,
"_source": { 找到的document数据内容。
"name": "test_doc_01",
"remark": "first test elastic search",
"order_no":1
}
}
8.10.2 GET _mget批量查询
批量查询可以提高查询效率。推荐使用(相对于单数据查询来说)。 语法:
代码语言:javascript复制GET /_mget
{
"docs" : [
{
"_index" : "value",
"_type" : "value",
"_id" : "value"
}, {}, {}
]
}
GET /index_name/_mget
{
"docs" : [
{
"_type" : "value",
"_id" : "value"
}, {}, {}
]
}
GET /index_name/type_name/_mget
{
"docs" : [
{
"_id" : "value1"
},
{
"_id" : "value2"
}
]
}
…未完待续