【1】Elasticsearch概述
① 什么是全文检索
全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置。当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。全文搜索搜索引擎数据库中的数据。
② lucene
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
对于我们目前来说,lucene,就是一个jar包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。我们就用java开发的时候,引入lucene jar,然后基于lucene的api进行去进行开发就可以了。
lucene官网地址:http://lucene.apache.org/core/
在线文档地址:http://lucene.apache.org/core/8_2_0/index.html
③ 什么是Elasticsearch
Elasticsearch是一个实时分布式搜索和分析引擎。它用于全文搜索、结构化搜索、分析。Elasticsearch基于lucene并隐藏复杂性,提供简单易用的restful api接口、java api接口(还有其他语言的api接口)。
全文检索: 将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
结构化检索: 我想搜索商品分类为日化用品的商品都有哪些,select * from products where category_id='日化用品'
。
数据分析: 电商网站,最近7天牙膏这种商品销量排名前10的商家有哪些;新闻网站,最近1个月访问量排名前3的新闻版块是哪些。
④ Elasticsearch的适用场景
- 维基百科,类似百度百科,牙膏,牙膏的维基百科,全文检索,高亮,搜索推荐。
- The Guardian(国外新闻网站),类似搜狐新闻,用户行为日志(点击,浏览,收藏,评论)+ 社交网络数据(对某某新闻的相关看法),数据分析,给到每篇新闻文章的作者,让他知道他的文章的公众反馈(好,坏,热门,垃圾,鄙视,崇拜)。
- Stack Overflow(国外的程序异常讨论论坛),IT问题,程序的报错,提交上去,有人会跟你讨论和回答,全文检索,搜索相关问题和答案,程序报错了,就会将报错信息粘贴到里面去,搜索有没有对应的答案
- GitHub(开源代码管理),搜索上千亿行代码。
- 国内:站内搜索(电商,招聘,门户,等等),IT系统搜索(OA,CRM,ERP,等等),数据分析(ES热门的一个使用场景)。
⑤ Elasticsearch的特点
- 可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
- Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
- 对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
- 数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;Elasticsearch作为传统数据库的一个补充,提供了数据库所不能提供的很多功能
【2】Elasticsearch中数据结构
① 索引(index)
索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。然而,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。如果你知道MongoDB,可以把Elasticsearch的索引看成MongoDB里的一个集合。如果你熟悉CouchDB,可以把索引看成CouchDB数据库索引。
Elasticsearch可以把索引存放在一台机器或者分散在多台服务器上,每个索引有一或多个分片(shard)每个分片包含了文档集的一部分,每个分片可以有多个副本(replica)。Elasticsearch的默认值,索引结束时将得到5个分片及其各自1个副本。简单来说,操作结束时,将有10个Lucene索引分布在集群中。
索引包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。一个index包含很多document,一个index就代表了一类类似的或者相同的document。比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。
② 文档类型(type)
在Elasticsearch中,一个索引对象可以存储很多不同用途的对象,也就是不同类型。
例如,一个博客应用程序可以保存文章和评论。文档类型让我们轻易地区分单个索引中的不同对象。每个文档可以有不同的结构,但在实际部署中,将文件按类型区分对数据操作有很大帮助。当然,需要记住一个限制,不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title的字段必须具有相同的类型。
③ 文档(document)
存储在Elasticsearch中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库表中的一行记录。当比较Elasticsearch中的文档和MongoDB中的文档,你会发现两者都可以有不同的结构,但ES的文档中,相同字段必须有相同类型。这意味着,所有包含title字段的文档,title字段类型都必须一样,比如string。
文档是es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。
文档由多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫多值字段(multivalued)。
每个字段有类型,如文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数组。字段类型在ES中很重要,因为它给出了各种操作(如分析或排序)如何被执行的信息。虽然可以自动确定,然而,仍然建议使用映射。
与关系型数据库不同,文档不需要有固定的结构,每个文档可以有不同的字段,此外,在程序开发期间,不必确定有哪些字段。当然,可以用模式强行规定文档结构。每个文档存储在一个索引中并有一个Elasticsearch自动生成的唯一标识符和文档类型。文档需要有对应文档类型的唯一标识符
,这意味着在一个索引中,两个不同类型的文档可以有相同的唯一标识符。
④ 映射(mappings)
数据如何存放到索引对象上,需要有一个映射配置,包括:数据类型、是否存储、是否分词等。这样就创建了一个名为blog的Index。Type不用单独创建,在创建Mapping 时指定就可以。Mapping用来定义Document中每个字段的类型,即所使用的 analyzer、是否索引等属性,非常关键等。
⑤ 字段(Field)
Field是Elasticsearch的最小单位。一个document里面有多个field,每个field就是一个数据字段。
【3】Elasticsearch主要概念
① 节点和集群
Elasticsearch可以作为一个独立的单个搜索服务器。不过,为了能够处理大型数据集,实现容错和高可用性,Elasticsearch可以运行在许多互相合作的服务器上。这些服务器称为集群(cluster),形成集群的每个服务器称为节点(node)。
cluster代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
② 分片
当有大量的文档时,由于内存的限制、硬盘能力、处理能力不足、无法足够快地响应客户端请求等,一个节点可能不够。在这种情况下,数据可以分为较小的部分称为分片(shard)(其中每个分片都是一个独立的Apache Lucene索引实例,它只是保存了索引数据的一部分)。
每个分片可以放在不同的服务器上,因此,数据可以在集群的节点中传播。当你查询的索引分布在多个分片上时,Elasticsearch会把查询发送给每个相关的分片,并将结果合并在一起,而应用程序并不知道分片的存在。此外,多个分片可以加快索引。
③ 副本
为了提高查询吞吐量或实现高可用性,可以使用分片副本。副本(replica)只是一个分片的精确复制,每个分片可以有零个或多个副本。换句话说,Elasticsearch可以有许多相同的分片,其中之一被自动选择去更改索引操作。这种特殊的分片称为主分片(primary shard),其余称为副本分片(replica shard)。在主分片丢失时,例如该分片数据所在服务器不可用,集群将副本提升为新的主分片。
④ 时光之门
Elasticsearch处理许多节点。集群的状态由时光之门控制。默认情况下,每个节点都在本地存储这些信息,并且在节点中同步。
【4】Elasticsearch单节点安装
安装ES之前先安装好jdk,可以简单实用如下命令:
yum install -y java-1.8.0-openjdk.x86_64
ES官网下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
这里用的版本是5.2.2,linux是Centos 6。
① 解压到指定目录
tar -zxvf elasticsearch-5.2.2.tar.gz -C /home/softinstall/
② 在目标目录下创建data和logs文件夹
cd /home/softinstall/elasticsearch-5.2.2
mkdir data logs
③ 修改config下的配置文件config/elasticsearch.yml
进入config文件夹,可以发现有三个配置文件,分别是elasticsearch的配置、jvm的配置以及日志配置。
[root@localhost elasticsearch-5.2.2]# cd config/
[root@localhost config]# ll
total 12
-rw-rw----. 1 root root 2854 Feb 24 2017 elasticsearch.yml
-rw-rw----. 1 root root 2892 Feb 24 2017 jvm.options
-rw-rw----. 1 root root 3992 Feb 24 2017 log4j2.properties
vim elasticsearch.yml
主要进行如下配置(切记是yml语法冒号后面有空格):
cluster.name: my-application
node.name: node-1
path.data: /home/softinstall/elasticsearch-5.2.2/data
path.logs: /home/softinstall/elasticsearch-5.2.2/logs
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
network.host: 192.168.18.128
http.port: 9200
discovery.zen.ping.unicast.hosts: ["localhost"]
如果要配置集群需要两个节点上的elasticsearch配置的cluster.name相同,都启动可以自动组成集群,这里如果不改cluster.name则默认是cluster.name=my-application
。nodename随意取但是集群内的各节点不能相同。
还需要一些文件描述符数量限制的配置,如下:
vi /etc/security/limits.conf
添加如下内容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
vi /etc/security/limits.d/90-nproc.conf
* soft nproc 1024
#修改为
* soft nproc 2048
vi /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
并执行命令:sysctl -p
关于文件描述符可以参考博文:Linux下修改文件描述符数量限制
④ 启动
直接以root身份运行是会报错的,es不允许用root用户运行:
Linux或OS X:bin/elasticsearch
Windows:bin/elasticsearch.bat
这时就需要将es切换用户了:
chown -R jane:jane /home/softinstall/elasticsearch-5.2.2
⑤ 正常启动与测试
启动命令:
//bin目录下以后台服务方式启动
./elasticsearch -d
ES正常启动如下:
在浏览器上测试访问:
可以查询es的相关信息:
http://192.168.18.128:9200/_cat?pretty
默认HTTP API端口为9200,内部广播端口为9300,如果用了header插件则会使用9100端口。
⑥ 关闭es
下面是三种可以关闭Elasticsearch的方法:
- 如果节点是连接到控制台,按下Ctrl+C。
- 第二种选择是通过发送TERM信号杀掉服务器进程(参考Linux上的kill命令和Windows
上的任务管理器)。 - 第三种方法是使用REST API。
第三种方法可以执行以下命令来关掉整个集群:
curl -XPOST http://localhost:9200/_cluster/nodes/_shutdown
【5】ES集群搭建
这里使用了三台虚拟机搭建ES集群:192.168.18.128,192.168.18.129,192.168.18.130。
具体搭建参考单节点搭建但是集群中配置文件修改如下:
cluster.name: my-application
node.name: node-1 #这里分别是1 2 3
path.data: /home/softinstall/elasticsearch-5.2.2/data
path.logs: /home/softinstall/elasticsearch-5.2.2/logs
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
network.host: 192.168.18.128 #这里填写对应主机IP
http.port: 9200
discovery.zen.ping.unicast.hosts: ["192.168.18.128","192.168.18.129","192.168.18.130"]
discovery.zen.minimum_master_nodes: 2
分别启动三台虚拟机上的ES,集群之间会进行选举出一个master。
192.168.18.128图示如下:
192.168.18.129图示如下:
192.168.18.130图示如下:
【6】启动报错总结
① java.lang.UnsupportedOperationException: seccomp unavailable: CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed
因为Centos6不支持SecComp,而ES默认bootstrap.system_call_filter为true
进行检测,所以导致检测失败,失败后直接导致ES不能启动解决。
修改elasticsearch.yml 添加一下内容 :
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
② 修改文件描述符数量限制
异常日志如下:
ERROR: bootstrap checks failed
max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
max number of threads [1024] for user [jane] is too low, increase to at least [2048]
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
解决方案:
vi /etc/security/limits.conf
添加如下内容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
vi /etc/security/limits.d/90-nproc.conf
* soft nproc 1024
#修改为
* soft nproc 2048
vi /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
并执行命令:sysctl -p
关于文件描述符可以参考博文:Linux下修改文件描述符数量限制
【7】Elasticsearch head插件安装
下载elasticsearch-head-master.zip插件,官网地址:https://github.com/mobz/elasticsearch-head
nodejs官网下载安装包:https://nodejs.org/dist/ ,这里使用node-v6.9.2-linux-x64.tar.xz
① 安装nodejs
解压包到指定目录:
tar -zxvf node-v6.9.2-linux-x64.tar.gz
配置环境变量:
export NODE_HOME=/home/softinstall/node-v6.9.2-linux-x64
export PATH=$PATH:$NODE_HOME/bin
检测环境:
[root@localhost Desktop]# node -v
v6.10.0
[root@localhost Desktop]# npm -v
3.10.10
② 解压并安装header
unzip elasticsearch-head-master.zip
查看当前head插件目录下有无node_modules/grunt
目录,如果没有就执行命令创建:
mkdir -p node_modules/grunt
执行命令安装grunt:
npm install grunt --save
安装header插件:
npm install -g cnpm --registry=https://registry.npm.taobao.org
这一步可能很慢,耐心等待。
安装grunt-cli:
npm install -g grunt-cli
编辑Gruntfile.js:
第93行添加hostname:'0.0.0.0'
options: {
hostname:'0.0.0.0',
port: 9100,
base: '.',
keepalive: true
}
检查head根目录下是否存在base文件夹。如果没有将 _site下的base文件夹及其内容复制到head根目录下:
mkdir base
cp _site/base/* ./base/
③ 启动grunt server
grunt server -d
可能会遇到以下错误提示:
> Local Npm module "grunt-contrib-clean" not found. Is it installed?
>> Local Npm module "grunt-contrib-concat" not found. Is it installed?
>> Local Npm module "grunt-contrib-watch" not found. Is it installed?
>> Local Npm module "grunt-contrib-connect" not found. Is it installed?
>> Local Npm module "grunt-contrib-copy" not found. Is it installed?
>> Local Npm module "grunt-contrib-jasmine" not found. Is it installed?
那么就需要一个个安装需要的模块:
npm install grunt-contrib-clean -registry=https://registry.npm.taobao.org
npm install grunt-contrib-concat -registry=https://registry.npm.taobao.org
npm install grunt-contrib-watch -registry=https://registry.npm.taobao.org
npm install grunt-contrib-connect -registry=https://registry.npm.taobao.org
npm install grunt-contrib-copy -registry=https://registry.npm.taobao.org
npm install grunt-contrib-jasmine -registry=https://registry.npm.taobao.org
修改配置文件elasticsearch.yml,在文件末尾增加如下配置(其实就是跨域):
http.cors.enabled: true
http.cors.allow-origin: "*"
重启ES,再次启动grunt server grunt server -d
,浏览器访问:http://192.168.18.128:9100/
这个界面可以进行索引的增删改查: