大数据技术之_20_Elasticsearch学习_01
一 概述
1.1 什么是搜索?
百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜欢的电影,或者说找一本喜欢的书,或者找一条感兴趣的新闻(提到搜索的第一印象)。
百度 != 搜索
• 1)互联网的搜索:电商网站、招聘网站、新闻网站、各种 app。
• 2)IT 系统的搜索:OA 软件、办公自动化软件、会议管理、日程管理、项目管理。
搜索,就是在任何场景下,找寻你想要的信息,这个时候,会输入一段你要搜索的关键字,然后就期望找到这个关键字相关的有些信息
1.2 如果用数据库做搜索会怎么样?
用数据库来实现搜索,是不太靠谱的。通常来说,性能会很差的。
1.3 什么是全文检索和 Lucene?
1)全文检索,倒排索引
全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。全文搜索搜索引擎数据库中的数据。
2)lucene
就是一个 jar 包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。我们就用 java 开发的时候,引入 lucene jar,然后基于 lucene 的 api 进行去进行开发就可以了。
1.4 什么是 Elasticsearch?
Elasticsearch,基于 lucene,隐藏复杂性,提供简单易用的 restful api 接口、java api 接口(还有其他语言的 api 接口)。
关于 elasticsearch 的一个传说,有一个程序员失业了,陪着自己老婆去英国伦敦学习厨师课程。程序员在失业期间想给老婆写一个菜谱搜索引擎,觉得 lucene 实在太复杂了,就开发了一个封装了 lucene 的开源项目–Compass。后来程序员找到了工作,是做分布式的高性能项目的,觉得 Compass 不够,就写了 Elasticsearch,让 lucene 变成分布式的系统。
Elasticsearch 是一个实时分布式搜索和分析引擎。它用于全文搜索、结构化搜索、数据分析
。
全文检索:将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
结构化检索:我想搜索商品分类为日化用品的商品都有哪些,如:select * from products where category_id=‘日化用品’
数据分析:电商网站,最近7天牙膏这种商品销量排名前10的商家有哪些?新闻网站,最近1个月访问量排名前3的新闻版块是哪些?
1.5 Elasticsearch 的适用场景
• 1)维基百科,类似百度百科,比如:牙膏,牙膏的维基百科,全文检索、高亮、搜索推荐。
• 2)The Guardian(国外新闻网站),类似搜狐新闻,用户行为日志(点击、浏览、收藏、评论)+ 社交网络数据(对某某新闻的相关看法);数据分析,给到每篇新闻文章的作者,让他知道他的文章的公众反馈(好、坏、热门、垃圾、鄙视、崇拜等)。
• 3)Stack Overflow(国外的程序异常讨论论坛),IT 问题,程序的报错,提交上去,有人会跟你讨论和回答;全文检索,搜索相关问题和答案,程序报错了,就会将报错信息粘贴到里面去,搜索有没有对应的答案。
• 4)GitHub(开源代码管理),搜索上千亿行代码。
• 5)国内:站内搜索(电商、招聘、门户 等等);IT 系统搜索(OA、CRM、ERP 等等);数据分析(ES 热门的一个使用场景)。
1.6 Elasticsearch 的特点
• 1)可以作为一个大型分布式集群(数百台服务器)技术,处理 PB 级数据,服务大公司;也可以运行在单机上,服务小公司。
• 2)Elasticsearch 不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的 ES;比如:lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)。
• 3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接 3 分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂。
• 4)数据库的功能面对很多领域是不够用的(事务、还有各种联机事务型的操作);特殊的功能,比如全文检索、同义词处理、相关度排名、复杂数据分析、海量数据的近实时处理;Elasticsearch 作为传统数据库的一个补充,提供了数据库所不能提供的很多功能。
1.7 Elasticsearch 的核心概念
1.7.1 近实时
近实时,两个意思,从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于 es 执行搜索和分析可以达到秒级。
1.7.2 Cluster(集群)
集群包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是 elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常。
1.7.3 Node(节点)
集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为 “elasticsearch” 的集群,如果直接启动一堆节点,那么它们会自动组成一个 elasticsearch 集群,当然一个节点也可以组成一个 elasticsearch 集群。
1.7.4 Index(索引 --> 数据库)
索引包含一堆有相似结构的文档数据
,比如可以有一个客户索引、商品分类索引、订单索引,索引有一个名称。一个 index 包含很多 document,一个 index 就代表了一类类似的或者相同的 document。比如说建立一个 product index(商品索引),里面可能就存放了所有的商品数据,即所有的商品 document。
1.7.5 Type(类型 --> 表)
每个索引里都可以有一个或多个 type,type 是 index 中的一个逻辑数据分类,一个 type 下的 document 都有相同的 field
。比如博客系统,有一个索引,可以定义用户数据 type、博客数据 type、评论数据 type。
商品 index,里面存放了所有的商品数据,即商品 document。
但是商品分很多种类,每个种类的 document 的 field 可能不太一样,比如说电器商品,可能还包含一些诸如售后时间范围这样的特殊 field;生鲜商品,还包含一些诸如生鲜保质期之类的特殊 field。
例如:type:日化商品type、电器商品 type、生鲜商品 type
日化商品 type:product_id, product_name, product_desc, category_id, category_name
电器商品 type:product_id, product_name, product_desc, category_id, category_name, service_period
生鲜商品 type:product_id, product_name, product_desc, category_id, category_name, eat_period
每一个 type 里面,都会包含一堆 document。如下:
电器商品 type
{
"product_id": "1",
"product_name": "长虹电视机",
"product_desc": "4k高清",
"category_id": "3",
"category_name": "电器",
"service_period": "1年"
}
生鲜商品 type
{
"product_id": "2",
"product_name": "基围虾",
"product_desc": "纯天然,冰岛产",
"category_id": "4",
"category_name": "生鲜",
"eat_period": "7天"
}
1.7.6 Document(文档 --> 行)
文档是 es 中的最小数据单元
,一个 document 可以是一条客户数据、一条商品分类数据、一条订单数据,通常用 JSON 数据结构表示,每个 index 下的 type 中,都可以去存储多个 document。
1.7.7 Field(字段 --> 列)
Field 是 Elasticsearch 的最小单位
。一个 document 里面有多个 field,每个 field 就是一个数据字段。
1.7.8 Mapping(映射 --> 约束)
数据如何存放到索引对象上,需要有一个映射配置,包括:数据类型、是否存储、是否分词等。
这样就创建了一个名为 blog 的 Index。Type 不用单独创建,在创建 Mapping 时指定就可以。Mapping 用来定义 Document 中每个字段的类型,即所使用的 analyzer、是否索引等属性。创建 Mapping 的代码示例如下:
client.indices.putMapping({
index : 'blog',
type : 'article',
body : {
article: {
properties: {
id: {
type: 'string',
analyzer: 'ik',
store: 'yes',
},
title: {
type: 'string',
analyzer: 'ik',
store: 'no',
},
content: {
type: 'string',
analyzer: 'ik',
store: 'yes',
}
}
}
}
});
1.7.9 Elasticsearch 与数据库的类比
1.7.10 ES 存入数据和搜索数据机制
二 快速入门
2.1 安装包下载
1)Elasticsearch官网: https://www.elastic.co/products/elasticsearch
点击 Download
点击 past releases 我们选择 5.2.2 Linux 版本的。
补充:ELK简介以及新旧版架构介绍
2.2 安装 Elasticsearch(单节点 Linux 环境)
注意
:因为 Elasticsearch 是基于 java 写的,所以它的运行环境中需要 java 的支持,在 Linux 下执行命令:java -version,检查 Jar 包是否安装。安装 java 版本至少是 1.8 以上。
Step0:将 elasticsearch-5.2.2.tar.gz 上传至 Linux 的 /opt/software 目录下
Step1:解压 elasticsearch-5.2.2.tar.gz 到/opt/module 目录下
[atguigu@hadoop102 software]$ tar -zxf elasticsearch-5.2.2.tar.gz -C /opt/module/
Step2:在 /opt/module/elasticsearch-5.2.2 路径下创建 data 和 logs 文件夹
[atguigu@hadoop102 elasticsearch-5.2.2]$ mkdir data
[atguigu@hadoop102 elasticsearch-5.2.2]$ mkdir logs
Step3:修改配置文件 /opt/module/elasticsearch-5.2.2/config/elasticsearch.yml
[atguigu@hadoop102 config]$ pwd
/opt/module/elasticsearch-5.2.2/config
[atguigu@hadoop102 config]$ vim elasticsearch.yml
elasticsearch.yml
# ---------------------------------- Cluster -----------------------------------
cluster.name: my-application
# ------------------------------------ Node ------------------------------------
node.name: node-102
# ----------------------------------- Paths ------------------------------------
path.data: /opt/module/elasticsearch-5.2.2/data
path.logs: /opt/module/elasticsearch-5.2.2/logs
# ----------------------------------- Memory -----------------------------------
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
# ---------------------------------- Network -----------------------------------
network.host: 192.168.25.102
# --------------------------------- Discovery ----------------------------------
discovery.zen.ping.unicast.hosts: ["hadoop102"]
文件详解如下:
(1) cluster.name
如果要配置集群需要两个节点上的 elasticsearch 配置的 cluster.name 相同,都启动可以自动组成集群。
这里如果不改 cluster.name 则默认是 cluster.name=my-application。
(2) node.name
随意取但是集群内的各节点不能相同。
(3) 修改后的每行前面不能有空格,修改后的 “:” 后面必须有一个空格。
(4) bootstrap.memory_lock 和 bootstrap.system_call_filter 需要配置成 false,否则初始化会报错!
Step4:配置 linux 系统环境(参考:http://blog.csdn.net/satiling/article/details/59697916)
(1) 切换到 root 用户,编辑 limits.conf 添加类似如下内容
[root@hadoop102 elasticsearch-5.2.2]# vim /etc/security/limits.conf
添加如下内容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
(2) 切换到 root 用户,进入 limits.d 目录下修改配置文件。
[root@hadoop102 elasticsearch-5.2.2]# vim /etc/security/limits.d/90-nproc.conf
修改如下内容:
* soft nproc 1024
#修改为
* soft nproc 2048
(3) 切换到 root 用户,修改配置 sysctl.conf
[root@hadoop102 elasticsearch-5.2.2]# vim /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
并执行命令:
[root@hadoop102 elasticsearch-5.2.2]# sysctl -p
然后,重新启动 elasticsearch,即可启动成功。
Step5:启动集群,注意
:要切回 atguigu 用户启动集群,否则会报错!
[atguigu@hadoop102 elasticsearch-5.2.2]$ bin/elasticsearch
Step6:两种方式测试集群
方式一:重新开启一个会话窗口,输入命令:curl http://hadoop102:9200
[atguigu@hadoop102 elasticsearch-5.2.2]$ curl http://hadoop102:9200
{
"name" : "node-102",
"cluster_name" : "my-application",
"cluster_uuid" : "yb29ijbJQ2mBzCHTOjyUGw",
"version" : {
"number" : "5.2.2",
"build_hash" : "f9d9b74",
"build_date" : "2017-02-24T17:26:45.835Z",
"build_snapshot" : false,
"lucene_version" : "6.4.1"
},
"tagline" : "You Know, for Search"
}
方式二:通过浏览器查看:http://hadoop102:9200/
Step7:停止集群
kill -9 进程号
2.3 安装 Elasticsearch(多节点集群 Linux 环境)
略
2.4 Elasticsearch head 插件安装
Step1:下载 elasticsearch-head 插件
https://github.com/mobz/elasticsearch-head
elasticsearch-head-master.zip
Step2:nodejs 官网下载安装包
https://nodejs.org/dist/
node-v6.9.2-linux-x64.tar.xz
Step3:将 elasticsearch-head-master.zip 和 node-v6.9.2-linux-x64.tar.xz 都上传到 Linux 的 /opt/software 目录下
Step4:安装nodejs
[atguigu@hadoop102 software]$ tar -zxf node-v6.9.2-linux-x64.tar.gz -C /opt/module/
Step5:切换到 root 用户,配置 nodejs 环境变量
[root@hadoop102 software]# vim /etc/profile
#NODE_HOME
export NODE_HOME=/opt/module/node-v6.9.2-linux-x64
export PATH=$PATH:$NODE_HOME/bin
[root@hadoop102 software]# source /etc/profile
Step6:查看 node 和 npm 版本
[root@hadoop102 software]# node -v
v6.9.2
[root@hadoop102 software]# npm -v
3.10.9
Step7:切换到 atguigu 用户,解压 head 插件到 /opt/module 目录下
[atguigu@hadoop102 software]$ unzip elasticsearch-head-master.zip -d /opt/module/
Step8:查看当前 head 插件目录下有无 node_modules/grunt 目录,没有的话,执行命令创建:
[atguigu@hadoop102 elasticsearch-head-master]$ npm install grunt --save
Step9:安装 head 插件:
[atguigu@hadoop102 elasticsearch-head-master]$ npm install -g cnpm --registry=https://registry.npm.taobao.org
Step10:安装 grunt:
[atguigu@hadoop102 elasticsearch-head-master]$ npm install -g grunt-cli
Step11:编辑 Gruntfile.js
[atguigu@hadoop102 elasticsearch-head-master]$ vim Gruntfile.js
在文件93行添加 hostname: '0.0.0.0',
options: {
hostname: '0.0.0.0',
port: 9100,
base: '.',
keepalive: true
}
Step12:检查 head 根目录下是否存在 base 文件夹,如果没有,就创建 base 文件夹,然后将 _site 目录下的 base 文件夹及其内容复制到 head 根目录下
[atguigu@hadoop102 elasticsearch-head-master]$ mkdir base
[atguigu@hadoop102 _site]$ cp base/* ../base/
Step13:启动 grunt server:
[atguigu@hadoop102 elasticsearch-head-master]$ grunt server -d
Running "connect:server" (connect) task
[D] Task source: /opt/module/elasticsearch-head-master/node_modules/grunt-contrib-connect/tasks/connect.js
Waiting forever...
Started connect web server on http://localhost:9100
如果提示 grunt 的模块没有安装:
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?
Warning: Task “connect:server” not found. Use –force to continue.
执行以下命令:
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
最后一个模块可能安装不成功,但是不影响使用。
再次重新启动 grunt server,启动成功
Step14:浏览器访问 head 插件:http://hadoop102:9100
Step15:启动集群插件后发现【集群健康值:未连接】
在 /opt/module/elasticsearch-5.2.2/config 路径下修改配置文件 elasticsearch.yml,在文件末尾增加:
[atguigu@hadoop102 config]$ pwd
/opt/module/elasticsearch-5.2.2/config
[atguigu@hadoop102 config]$ vim elasticsearch.yml
http.cors.enabled: true
http.cors.allow-origin: "*"
再次重新启动 elasticsearch,然后再次重新启动 grunt server。
浏览器再次访问 head 插件:http://hadoop102:9100,成功截图如下:
Step16:关闭插件服务
ctrl+c
[atguigu@hadoop102 elasticsearch-head-master]$ netstat -lntp | grep 9100
tcp 0 0 192.168.25.102:9100 0.0.0.0:* LISTEN 6070/grunt
三 Java API 操作
Elasticsearch 的 Java 客户端非常强大;它可以建立一个嵌入式实例并在必要时运行管理任务。
运行一个 Java 应用程序和 Elasticsearch 时,有两种操作模式可供使用。该应用程序可在 Elasticsearch 集群中扮演更加主动或更加被动的角色。在更加主动的情况下(称为 Node Client),应用程序实例将从集群接收请求,确定哪个节点应处理该请求,就像正常节点所做的一样。(应用程序甚至可以托管索引和处理请求。)另一种模式称为 Transport Client,它将所有请求都转发到另一个 Elasticsearch 节点,由后者来确定最终目标。
3.1 API 基本操作
3.1.1 操作环境准备
1)创建 maven 工程(不使用骨架的方式)
2)添加 pom.xml 文件
<dependencies>
<dependency>