tigercn 2019-12-30
Elasticsearch是一个基于Lucene的实时的分布式搜索和分析 引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠, 快速,安装使用方便。基于RESTful接口。
1)Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
2)Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
1.一个ES集群可以包含多个索引(数据库),每个索引又包含了很多类型(表),类型中包含了很多文档(行),每个文档又包含了很多字段(列)。
2.传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。
3.倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。
(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
倒排索引有两种不同的反向索引形式:
一条记录的水平反向索引(或者反向档案索引)包含每个引用单词的文档的列表。
一个单词的水平反向索引(或者完全反向索引)又包含每个单词在一个文档中的位置。
后者的形式提供了更多的兼容性(比如短语搜索),但是需要更多的时间和空间来创建。
现代搜索引擎的索引都是基于倒排索引。相比“签名文件”、“后缀树”等索引结构,
“倒排索引”是实现单词到文档映射关系的最佳实现方式和最有效的索引结构
更新策略有四种:完全重建、再合并策略、原地更新策略以及混合策略。
完全重建策略:当新增文档到达一定数量,将新增文档和原先的老文档整合,然后利用静态索引创建方法对所有文档重建索引,新索引建立完成后老索引会被遗弃。此法代价高,但是主流商业搜索引擎一般是采用此方式来维护索引的更新(这句话是书中原话)
再合并策略:当新增文档进入系统,解析文档,之后更新内存中维护的临时索引,文档中出现的每个单词,在其倒排表列表末尾追加倒排表列表项;一旦临时索引将指定内存消耗光,即进行一次索引合并,这里需要倒排文件里的倒排列表存放顺序已经按照索引单词字典顺序由低到高排序,这样直接顺序扫描合并即可。其缺点是:因为要生成新的倒排索引文件,所以对老索引中的很多单词,尽管其在倒排列表并未发生任何变化,也需要将其从老索引中取出来并写入新索引中,这样对磁盘消耗是没必要的。
原地更新策略:试图改进再合并策略,在原地合并倒排表,这需要提前分配一定的空间给未来插入,如果提前分配的空间不够了需要迁移。实际显示,其索引更新的效率比再合并策略要低。
混合策略:出发点是能够结合不同索引更新策略的长处,将不同索引更新策略混合,以形成更高效的方法。
简单法
索引的构建相当于从正排表到倒排表的建立过程。当我们分析完网页时 ,得到的是以网页为主码的索引表。当索引建立完成后 ,应得到倒排表 ,具体流程如图所示:
流程描述如下:
1)将文档分析成单词term标记,
2)使用hash去重单词term 3)对单词生成倒排列表 倒排列表就是文档编号DocID,没有包含其他的信息(如词频,单词位置等),这就是简单的索引。 这个简单索引功能可以用于小数据,例如索引几千个文档。然而它有两点限制: 1)需要有足够的内存来存储倒排表,对于搜索引擎来说, 都是G级别数据,特别是当规模不断扩大时 ,我们根本不可能提供这么多的内存。 2)算法是顺序执行,不便于并行处理。
合并法
归并法,即每次将内存中数据写入磁盘时,包括词典在内的所有中间结果信息都被写入磁盘,这样内存所有内容都可以被清空,后续建立索引可以使用全部的定额内存。
如图 归并示意图:
合并流程:
1)页面分析,生成临时倒排数据索引A,B,当临时倒排数据索引A,B占满内存后,将内存索引A,B写入临时文件生成临时倒排文件, 2) 对生成的多个临时倒排文件 ,执行多路归并 ,输出得到最终的倒排文件 ( inverted file)。
合并流程
索引创建过程中的页面分析 ,特别是中文分词为主要时间开销。算法的第二步相对很快。这样创建算法的优化集中在中文分词效率上。
elasticsearch只兼容jdk1.8 以上版本
上传jdk-->解压jdk(tar -zxvf jdk-1.8.0)-->移动jdk(mv jdk-1.8.0 /opt/sxt)-->更换配置文件(vim /etc/porfile)-->更改hadoop中的相关配置文件的jdk路径-->更改hbase中相关配置文件的jdk路径-->启用jdk
启动jdk时,只能断开连接,在重新连接,不能用source,因为环境上还有jdk-1.7.0版本
上传压缩包
解压压缩包(tar -zxvf elasticsearch.tar)
移动压缩包(mv elasticsearch-2.4.5 /opt/sxt)
修改配置文件
vim /opt/sxt/elasticsearch/config
修改集群名字为"shsxt-es" 同一集群名字必须相同
修改node.name 同一集群节点名称不同
修改Network.Host 地址为该节点的地址
配置防止脑裂
discovery.zen.ping.multicast.enabled: falsediscovery.zen.ping_timeout: 120sclient.transport.ping_timeout: 60sdiscovery.zen.ping.unicast.hosts: ["192.168.61.220","192.168.61.221", "192.168.61.222"]
拷贝到其他节点上
scp elasticsearch-2.4.5 :/opt/sxt
scp elasticsearch-2.4.5 :/opt/sxt
修改配置文件
启动ES
进入bin目录下
./elasticsearch
后台运行./elasticsearch -d
测试
REST 全称是 Resource Representational State Transfer,通俗来讲就是:资源在网络中以某种表现形式进行状态转移。分解开来:Resource:资源,即数据。比如 news,friends等;Representational:某种表现形式,比如用JSON,XML,JPEG等;State Transfer:状态变化。通过HTTP动词实现。
它一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
GET :获取对象的当前状态
PUT :改变对象的状态
POST :创建对象
DELETE : 删除对象
HEAD : 获取头信息
-X 指定http请求的方法
-HEAD GET POST PUT DELETE
-d 指定要传输的数据
curl -XPUT http://192.168.61.220:9200/shsxt/
PUT/POST都可以
curl -XDELETE http://192.168.61.220:9200/shsxt/
curl -XPUT http://192.168.61.220:9200/shsxt/employee/1 -d ‘{
"first_name" : "john",
"last_name" : "smith",
"age" : 25,
"about" : "I love to go rock climbing",
"address": "shanghai"
}‘
curl -XPOST http://192.168.61.220:9200/shsxt/employee -d ‘{
"first_name" : "john",
"last_name" : "smith",
"age" : 25,
"about" : "I love to go rock climbing"
}‘
注意事项:
索引库名称必须要全部小写,不能以下划线开头,也不能包含逗号;如果没有明确指定索引数据的ID,那么es会自动生成一个随机的ID,这时需要使用POST方式,PUT方式会出错。
命令:curl -XPOST http://localhost:9200/shsxt/employee -d ‘{"first_name" : "John"}‘
命令:curl -XPUT http://localhost:9200/shsxt/employee -d ‘{"first_name" : "John"}‘ 会报错
curl -XPUT http://192.168.61.220:9200/shsxt/employee/1 -d ‘
{
"first_name" : "god bin",
"last_name" : "pang",
"age" : 38,
"about" : "I love to go rock climbing",
"address": "shanghai"
}‘
curl -XPUT http://192.168.61.220:9200/shsxt/employee/1 -d ‘{
"first_name" : "god bin",
"last_name" : "pang",
"age" : 36,
"about" : "I love to go rock climbing",
"address": "shanghai"
}‘
PUT 和 POST 都是新增,修改。PUT必须指定ID,所以PUT一般数据更新 。POST 可以指定ID,也可以不指定 做新增比较好。
注意:执行更新操作的时候
– ES首先将旧的文档标记为删除状态
– 然后添加新的文档
– 旧的文档不会立即消失,但是你也无法访问
– ES会在你继续添加更多数据的时候在后台清理已经标记为删除状态的文档
局部更新:可以添加新字段或者更新已有字段(必须使用 POST)
curl -XPOST http://localhost:9200/shsxt/employee/1/_update -d ‘{
"doc":{
"city":"beijing",
“sex”:”male”
}
}‘
全局更新:curl -XPUT http://localhost:9200/shsxt/employee/1 -d ‘{"city":"beijing","car":"BMW"}‘
根据员工id查询
在任意的查询字符串中添加pretty参数,es可以得到易于识别的json结果。
curl后添加-i 参数,这样你就能得到反馈头文件
curl -i XGET http://localhost:9200/shsxt/employee/1?pretty
检索文档中的一部分,如果只需要显示指定字段
curl -XGET http://localhost:9200/shsxt/employee/1?_source=name,age
如果只需要source的数据
curl -XGET http://localhost:9200/shsxt/employee/1/_source?pretty
查询所有
curl -XGET http://localhost:9200/shsxt/employee/_search?pretty
根据条件进行查询
curl -XGET http://localhost:9200/shsxt/employee/_search?q=last_name:smith
领域特定语言
curl -XGET http://localhost:9200/shsxt/employee/_search?pretty -d ‘{
"query":
{"match":
{"last_name":"smith"}
}
}‘
对多个field发起查询:multi_match
curl -XGET http://localhost:9200/shsxt/employee/_search?pretty -d ‘
{
"query":
{"multi_match":
{
"query":"bin",
"fields":["last_name","first_name"]
}
}
}‘
复合查询,must,must_not, should
must: AND
must_not:NOT
should:OR
curl -XGET http://192.168.78.101:9200/shsxt/employee/_search?pretty -d ‘{
"query":
{"bool" :
{
"must" :
{"match":
{"first_name":"bin"}
},
"must" :
{"match":
{"age":37}
}
}
}
}‘
查询first_name=bin的,并且年龄不在20岁到30岁之间的
curl -XGET http://192.168.61.220:9200/shsxt/employee/_search -d ‘{
"query":
{"bool" :
{
"must" :
{"term" :
{ "first_name" : "bin" }
}
,
"must" :
{"range":
{"age" : { "from" : 30, "to" : 40 }
}
}
}
}
}‘
curl -XDELETE http://localhost:9200/shsxt/employee/1?pretty
如果文档存在,es会返回200 ok的状态码,found属性值为 true,_version属性的值+1
found属性值为false,但是_version属性的值依然会+1,这个就是内部管理的一部分,它保证了我们在多个节点间的不同操作的顺序都被正确标记了
注意:删除一个文档也不会立即生效,它只是被标记成已删除。 Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理
上传压缩包
解压压缩包
进入bin目录下
cd /opt/sxt/elasticsearch/bin
./plugin install /opt/sxt/ES-head
重新启动ES
测试
三个节点上只需要在其中一个节点上安装head即可
上传压缩包
解压
修改配置文件
vim /opt/sxt/kibana/config/kibana.yml
elasticsaerch.url:"http://192.168.61.221:9200"
进入bin目录下
cd /opt/sxt/elasticsearch/bin
plugin install license
进入bin目录下
cd /opt/sxt/elasticsearch/bin
plugin install marvel-agent
进入bin目录下
cd /opt/sxt/kibana/bin
plugin --install elasticsearch/marvel/latest
拷贝到其他节点上
scp marvel-agent license : pwd
scp marvel-agent license : pwd
启动
ES启动
进入bin目录下执行./elasticsearch三台同时启动
kibana启动
进入kibana的bin目录下执行kibana在装有kibana的虚拟机上启动
测试
访问kibana所在的的虚拟机 192.168.62.221:5601/app/mavel
Kibana的marvel插件把elasticsearch信息展示出来,点击es集群(途中箭头所指),可查看具体的信息。
箭头所指的地方分别代表了这个集群一共有多少个节点,有多少个索引库,内存使用量,分片数量,文档数量
点击indices可查看集群里一共有多少个索引库,其中 箭头2和箭头3所指向的两个索引库,是marvel插件在elasticsearch里注册的,myindex是我自己创建的一个索引库。
点击myindex索引库可查看此索引库的信息,上图中的箭头1和2所指的地方可以查看myindex索引库里一共存了多少个文档,数据大小。
创建新目录
mkdir ik /opt/sxt/elasticsearch-2.4.5/plugin/
上传压缩包到创建的目录中并解压
unzip elasticsearch-analysis-ik-1.8.0.zip
重新启动ES集群
测试
创建索引库
curl -XPUT http://localhost:9200/ik
设置mapping
curl -XPOST http://localhost:9200/ik/ikType/_mapping -d‘{
"properties": {
"content": {
"type": "string",
"index":"analyzed",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}‘
插入数据
curl -XPOST http://localhost:9200/ik/ikType/1 -d‘
{"content":"美国留给伊拉克的是个烂摊子吗"}‘
curl -XPOST http://localhost:9200/ik/ikType/2 -d‘
{"content":"公安部:各地校车将享最高路权"}‘
curl -XPOST http://localhost:9200/ik/ikType/3 -d‘
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}‘
curl -XPOST http://localhost:9200/ik/ikType/4 -d‘
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}‘
查询
curl -XGET http://localhost:9200/ik/ikType/_search?pretty -d‘{
"query" : { "term" : { "content" : "中国" }}
}‘