Elasticsearch介绍
Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene。
Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库——无论是开源还是私有,但它也仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理,因为Lucene 非常复杂。
为了解决Lucene使用时的繁复性,于是Elasticsearch便应运而生。它使用 Java 编写,内部采用 Lucene 做索引与搜索,但是它的目标是使全文检索变得更简单,简单来说,就是对Lucene 做了一层封装,它提供了一套简单一致的 RESTful API 来帮助我们实现存储和检索。
当然,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确地形容:
- 一个分布式的实时文档存储,每个字段可以被索引与搜索;
- 一个分布式实时分析搜索引擎;
- 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
什么是全⽂检索和倒排索引
什么是索引
索引就好⽐书的⽬录,如果我们想快速查看某个章节,只需要找到⽬录⾥相应章节对应的⻚数即可。
通过⽬录找到章节,通过章节找到⻚码这个过程就是索引的过程。
索引的⽬的就是加快数据搜索的效率。
什么是全⽂检索
先建⽴索引,再对索引进⾏搜索的过程就叫全⽂检索(Full-text Search)。
什么是倒排索引
索引是根据章节找到⻚数,但是如果我并不知道我要找的内容属于哪个章节,⽐如我只知道⼀个关键词,但是不知道这个关键词属于哪个章节。⼤家可以想⼀下,我们平时利⽤搜索引擎搜索的时候是不是也是这种场景呢?
⽐如我们想知道⼀个电影的名字,但是记不起来具体的名字,只知道部分关键词或者剧情的内容,那这种情景背后如何⽤技术解决呢?这时候就不得不提到倒排索引了。
举例
正常索引:
第1章 Elasticsearch介绍 第10⻚
第2章 Elasticsearch安装配置 第15⻚
第3章 Elasticsearch⾃定义配置 第20⻚
倒排索引:
关键词 章节
Elasticsearch 第1章 第2章 第3章
安装 第2章
配置 第2章 第3章
⾃定义 第3章
节点 & 集群(Node & Cluster)
Elasticsearch 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个Elasticsearch实例。单个Elasticsearch实例称为一个节点(Node),一组节点构成一个集群(Cluster)。
文档(Document)
Index里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。Document 使用 JSON 格式表示。同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。
类型(Type)
Document 可以分组,比如employee这个 Index 里面,可以按部门分组,也可以按职级分组。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document,类似关系型数据库中的数据表。
不同的 Type 应该有相似的结构(Schema),性质完全不同的数据(比如 products 和 logs)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然可以做到)。
文档元数据(Document metadata)
文档元数据为_index, _type, _id, 这三者可以唯一表示一个文档,_index表示文档在哪存放,_type表示文档的对象类别,_id为文档的唯一标识。
字段(Fields)
每个Document都类似一个JSON结构,它包含了许多字段,每个字段都有其对应的值,多个字段组成了一个 Document,可以类比关系型数据库数据表中的字段。
在 Elasticsearch 中,文档(Document)归属于一种类型(Type),而这些类型存在于索引(Index)中,下图展示了Elasticsearch与传统关系型数据库的类比:
Elasticsearch工作原理图
检索原理
Elasticsearch应⽤场景
1.搜索: 电商,百科,app搜索,搜索结果⾼亮显示
2.⽇志分析和数据挖掘,数据展示
Elasticsearch特点
1.⾼性能,天然分布式集群
2.对运维友好,不需要会java语⾔,开箱即⽤,配置⽂件精简
Elasticsearch在电商搜索的实现
cat
skuid name
1 狗粮100kg
2 猫粮50kg
3 猫罐头200g
select * from cat where name like ‘%’
Elasticsearch:
聚合运算之后得到SKUID:
1
2
拿到ID之后,mysql就只需要简单地where查询即可
mysql:
select xx from xxx where skuid 1
Elasticsearch安装
1.关闭防⽕墙和Selinux
关闭swap分区
内存 2G
iptables -nL
iptables -F
iptables -X
iptables -Z
iptables -nL
#关闭selinux
临时⽣效:
setenforce 0
getenforce
永久⽣效:
setenforce 0
vim /etc/selinux/config
SELINUX=disabled
2.下载软件
mkdir /data/soft -p
cd /data/soft/
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch7.9.1-x86_64.rpm
3.安装jdk
对于Elasticsearch7.0之后的版本不需要再独⽴的安装JDK了,软件包⾥已经⾃带了最新的JDK,所以直接启动即可。
4.安装ES
rpm -ivh elasticsearch-7.9.1-x86_64.rpm
5.启动并检查
systemctl daemon-reload
systemctl enable elasticsearch.service
systemctl start elasticsearch.service
netstat -lntup|grep 9200
curl 127.0.0.1:9200
Elasticsearch⾃定义配置
查看ES有哪些配置
[root@node-51 ~]# rpm -qc elasticsearch
/etc/elasticsearch/elasticsearch.yml #主配置⽂件
/etc/elasticsearch/jvm.options #JVM配置⽂件
/etc/init.d/elasticsearch #init启动脚本
/etc/sysconfig/elasticsearch #环境变量⽂件
/usr/lib/sysctl.d/elasticsearch.conf #内核参数⽂件
/usr/lib/systemd/system/elasticsearch.service #systemd启动⽂件
⾃定义配置⽂件
cp /etc/elasticsearch/elasticsearch.yml /opt/
cat > /etc/elasticsearch/elasticsearch.yml << 'EOF'
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 127.0.0.1,10.0.0.51
http.port: 9200
discovery.seed_hosts: ["10.0.0.51"]
cluster.initial_master_nodes: ["10.0.0.51"]
EOF
重启服务
systemctl restart elasticsearch.service
解决内存锁定失败
重启后查看⽇志发现提示内存锁定失败
[root@node-51 ~]# tail -f /var/log/elasticsearch/elasticsearch.log
[2020-12-17T19:34:38,132][ERROR][o.e.b.Bootstrap ] [node-1]
node validation exception
[1] bootstrap checks failed
[1]: memory locking requested for elasticsearch process but memory is
not locked
官⽹解决⽅案:[https://www.elastic.co/guide/en/elasticsearch/reference/current/settingsystem-settings.html#systemd](https://www.elastic.co/guide/en/elasticsearch/reference/current/settingsystem-settings.html#systemd)
解决命令:
systemctl edit elasticsearch
[Service]
LimitMEMLOCK=infinity
systemctl daemon-reload
systemctl restart elasticsearch.service
Elasticsearch插件安装
elasticsearch-head 介绍
elasticsearch-head是⼀款⽤来管理Elasticsearch集群的第三⽅插件⼯具。
elasticsearch-Head插件在5.0版本之前可以直接以插件的形式直接安装,但是5.0以后安装⽅式发⽣了改变,需要nodejs环境⽀持,或者直接使⽤别⼈封装好的docker镜像,更推荐的是⾕歌浏览器的插件。
elasticsearch-head的三种安装⽅式
1.npm安装⽅式
2.docker安装
3.google浏览器插件(推荐)
elasticsearch-head编译安装命令
插件官⽅地址:https://github.com/mobz/elasticsearch-head
使⽤docker部署elasticsearch-head
docker pull alivv/elasticsearch-head
docker run --name es-head -p 9100:9100 -dit elivv/elasticsearch-head
使⽤nodejs编译安装elasticsearch-head
cd /opt/
wget https://nodejs.org/dist/v12.13.0/node-v12.13.0-linux-x64.tar.xz
tar xf node-v12.13.0-linux-x64.tar.xz
mv node-v12.13.0-linux-x64 node
echo 'export PATH=$PATH:/opt/node/bin' >> /etc/profile
source /etc/profile
npm -v
node -v
git clone git://github.com/mobz/elasticsearch-head.git
unzip elasticsearch-head-master.zip
cd elasticsearch-head-master
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install
cnpm run start &
es-head⾕歌浏览器插件安装
更多⼯具–>拓展程序–>开发者模式–>选择解压缩后的插件⽬录
Elasticsearch使用
Elasticsearch提供了多种交互使用方式,包括Java API和RESTful API ,本文主要介绍RESTful API 。所有其他语言可以使用RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。甚至,你还可以使用 curl 命令来和 Elasticsearch 交互。
一个Elasticsearch请求和任何 HTTP 请求一样,都由若干相同的部件组成:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
返回的数据格式为JSON,因为Elasticsearch中的文档以JSON格式储存。其中,被 < > 标记的部件:
对于HTTP方法,它们的具体作用为:
我们以下面的数据为例,来展示Elasticsearch的用法。
Elasticsearch插⼊命令
参考官⽹地址: https://www.elastic.co/guide/en/elasticsearch/reference/current/gettingstarted-index.html
使⽤⾃定义的ID
PUT linux/_doc/1
{
"name": "zhang",
"age": "29"
}
使⽤随机ID
POST linux/_doc/
{
"name": "zhang",
"age": "29",
"address": "BJ"
}
和mysql数据对比
mysql
id name age address job
1 lang 27 BJ it
2 ya 22 SZ it
POST linux/_doc/
{
"id": "1",
"name": "zhang",
"age": "29",
"address": "BJ",
"job": "it"
}
POST linux/_doc/
{
"id": "2",
"name": "yy",
"age": "22",
"address": "SZ",
"job": "it"
}
Elasticsearch查询命令
1.创建测试语句
POST linux/_doc/
{
"name": "zhang3",
"age": "22",
"address": "SZ",
"job": "ops"
}
POST linux/_doc/
{
"name": "li4",
"age": "30",
"address": "BJ",
"job": "dev"
}
POST linux/_doc/
{
"name": "wang5",
"age": "24",
"address": "BJ",
"job": "dev"
}
POST linux/_doc/
{
"name": "zhao6",
"age": "35",
"address": "SZ",
"job": "devops"
}
POST linux/_doc/
{
"name": "sun7",
"age": "21",
"address": "BJ",
"job": "ops"
}
POST linux/_doc/
{
"name": "jack",
"age": "27",
"address": "BJ",
"job": "devops"
}
POST linux/_doc/
{
"name": "scott",
"age": "25",
"address": "SZ",
"job": "dev"
}
2.简单查询
GET linux/_search/
3.条件查询
GET linux/_search
{
"query": {
"term": {
"name": {
"value": "zhang3"
}
}
}
}
GET linux/_search
{
"query": {
"term": {
"job": {
"value": "ops"
}
}
}
}
4.多条件查询
GET /linux/_search
{
"query" : {
"bool": {
"must": [
{"match": {"address": "BJ"}},
{"match": {"job": "dev"}}
],
"filter": {
"range": {
"age": {
"gte": 27,
"lte": 30
}
}
}
}
}
}
}
Elasticsearch更新命令
1.⾃定义的ID更新
PUT linux/info/1
{
"name": "zhang",
"age": 30,
"job": "it",
"id": 1
}
2.随机ID更新
创建测试数据
PUT linux/_doc/1
{
"name": "zhang",
"age": "30",
"job": "it",
"id": 2
}
先根据⾃定义的Id字段查出数据的随机ID
GET linux/_search/
{
"query": {
"term": {
"id": {
"value": "2"
}
}
}
}
取到随机ID后更改数据
PUT linux/_doc/CVDdknIBq3aq7mPQaoWw
{
"name": "tony",
"age": 30,
"job": "it",
"id": 2
}