ElasticSearch
全文搜索引擎
全 ⽂搜索引擎是 ⽬前 ⼴泛应 ⽤的主流搜索引擎。它的 ⼯作原理是计算机索引程序通过扫描 ⽂章中的每 ⼀个词,对每 ⼀个词建 ⽴ ⼀个索引,指明该词在 ⽂章中出现的次数和位
置,当 ⽤户查询时,检索程序就根据事先建 ⽴的索引进 ⾏查找,并将查找的结果反馈给 ⽤户的。
数据分类
- 结构化数据:通常可以通过 TRDB 以表的方式存储和搜索、也可以建立索引,通过 b-tree 等数据结构快速搜索数据。
- 非结构化数据:全文数据,不定长或无固定格式的数据。例如:邮件、word 文档等。对非结构化数据的搜索方法有两种:顺序扫描法、全文搜索法。
顺序扫描法
按字 ⾯意思,我们可以了解它的 ⼤概搜索 ⽅式,就是按照顺序扫描的 ⽅式查找特定的关键字。⽐如让你在 ⼀篇篮球新闻中,找出"科 ⽐"这个名字在哪些段落出现过。那你肯定需要从头到尾把 ⽂章阅读 ⼀遍,然后标记出关键字在哪些地 ⽅出现过。这种 ⽅法毋庸置疑是最低效的,如果 ⽂章很 ⻓,有 ⼏万字,等你阅读完这篇新闻找到"科 ⽐"这个关键字,那得花多少时间。
全文搜索法
对 ⾮结构化数据进 ⾏顺序扫描很慢,可以将 ⾮结构化数据中的 ⼀部分信息提取出来,重新组织,使其变得有 ⼀定结构,然后对这些有 ⼀定结构的数据进 ⾏搜索,从 ⽽达到搜索相对较快的 ⽬的。这种 ⽅式就构成了全 ⽂搜索的基本思路。这部分从 ⾮结构化数据中提取出的然后重新组织的信息,我们称之索引。
为什么不用 MySQL 做全文搜索?
- 数据类型:全 ⽂索引搜索很好的 ⽀持 ⾮结构化数据的搜索,可以更好地快速搜索 ⼤量存在的任何单词 ⾮结构化 ⽂本。
1例如 Google,百度类的⽹站搜索,它们都是根据⽹⻚中的关键字⽣成索引,我们在搜索的时候输⼊关键字,它们会将该关键字即索引匹配到的所有⽹⻚返回;还有常⻅的项⽬中应⽤⽇志的搜索等等。对于这些⾮结构化的数据⽂本,关系型数据库搜索不是能很好的⽀持。
- 搜索性能:如果使 ⽤ MySQL 做搜索,⽐如有个 player 表,这个表有 user_name 这个字段,我们要查找出 user_name 以 james 开头的球员,和含有 James 的球员。我们 ⼀般怎么做?数据量达到千万级别的时候怎么办?like 的性能很慢(不会使用索引)。
- 灵活的搜索:如果我们想查出名字叫 james 的球员,但是 ⽤户输 ⼊了 jame,我们想提示他 ⼀些关键字。如果我们想查出带有"冠军"关键字的 ⽂章,但是 ⽤户输 ⼊了"总冠军",我们也希望能查出来。
- 索引的维护:⼀般传统数据库,全 ⽂搜索都实现的很鸡肋,因为 ⼀般也没 ⼈ ⽤数据库存 ⻓ ⽂本字段,因为进 ⾏全 ⽂搜索的时候需要扫描整个表,如果数据量 ⼤的话即使对 SQL 的语法进 ⾏优化,也是效果甚微。即使建 ⽴了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。
适合全 ⽂索引引擎的场景
- 搜索的数据对象是 ⼤量的 ⾮结构化的 ⽂本数据。
- ⽂本数据量达到数 ⼗万或数百万级别,甚 ⾄更多。
- ⽀持 ⼤量基于交互式 ⽂本的查询。
- 需求 ⾮常灵活的全 ⽂搜索查询。
- 对安全事务,⾮ ⽂本数据操作的需求相对较少的情况。
常见搜索引擎
Lucene
Lucene 是 ⼀个 Java 全 ⽂搜索引擎,完全 ⽤ Java 编写。Lucene 不是 ⼀个完整的应 ⽤程序,⽽是 ⼀个代码库和 API,可以很容易地 ⽤于向应 ⽤程序添加搜索功能。通过简单的 API 提供强 ⼤的功能:
- 可扩展的 ⾼性能索引
- 强 ⼤,准确,⾼效的搜索算法
- 跨平台解决 ⽅案
在 Apache 软件基 ⾦会提供的开源软件项 ⽬的 Apache 社区的 ⽀持。
但是 Lucene 只是 ⼀个框架,要充分利 ⽤它的功能,需要使 ⽤ Java,并且在程序中集成 Lucene。需要很多的学习了解,才能明 ⽩它是如何运 ⾏的,熟练运 ⽤ Lucene 确实 ⾮常复杂。
Solr
Solr 是 ⼀个基于 Lucene 的 Java 库构建的开源搜索平台。它以 ⽤户友好的 ⽅式提供 ApacheLucene 的搜索功能。它是 ⼀个成熟的产品,拥有强 ⼤ ⽽ ⼴泛的 ⽤户社区。它能提供分布式索引,复制,负载均衡查询以及 ⾃动故障转移和恢复。如果它被正确部署然后管理得好,它就能够成为 ⼀个 ⾼度可靠,可扩展且容错的搜索引擎。很多互联 ⽹巨头,如 Netflflix,eBay,Instagram 和亚 ⻢逊都使 ⽤ Solr,因为它能够索引和搜索多个站点。强 ⼤的功能:
- 全 ⽂搜索
- 突出功能
- 分 ⾯搜索
- 实时索引
- 动态群集
- 数据库集成
- NoSQL 功能和丰富的 ⽂档处理
Elastic search
Elasticsearch 是 ⼀个开源,是 ⼀个基于 Apache Lucene 库构建的 RESTFul 搜索引擎。
Elasticsearch 是在 Solr 之后 ⼏年推出的。它提供了 ⼀个分布式,多租户能 ⼒的全 ⽂搜索引擎,具有 HTTP Web 界 ⾯(REST)和 ⽆架构 JSON ⽂档。Elasticsearch 的官 ⽅客户端库提供 Java,Groovy,PHP,Ruby,Perl,Python,.NET 和 JavaScript。
主要功能:
- 分布式搜索
- 数据分析
- 分组和聚合
应 ⽤场景:
- 维基百科
- Stack Overflflow
- GitHub 电商 ⽹站
- ⽇志数据分析
- 商品价格监控 ⽹站
- BI 系统
- 站内搜索
- 篮球论坛
安装
- Elasticsearch 是强依赖于我们的 JDK 环境,所以 ⼀定要安装对应的 JDK,并且配置好相 关的
- 创建用户与组
1[root@localhost bin]# groupadd elsearch
2[root@localhost bin]# useradd elsearch -g elsearch
3[root@localhost bin]# passwd elsearch
4[root@localhost software]# chown -R elsearch:elsearch elasticsearch-7.2.1
- 环境变量 mac/linux,打开软件的安装路径,进 ⼊到 bin ⽬录,
1启动方式
2 sh elasticsearch.sh
3守护进程的⽅ 式可以使⽤
4 sh elasticsearch.sh -d -p pid
5 sh elasticsearch -d -p 9999
6验证
7[elsearch@localhost bin]$ curl http://localhost:9200
8{
9 "name" : "localhost.localdomain",
10 "cluster_name" : "elasticsearch",
11 "cluster_uuid" : "qu8IpbtWTQes05d5dnVUvQ",
12 "version" : {
13 "number" : "7.2.1",
14 "build_flavor" : "oss",
15 "build_type" : "tar",
16 "build_hash" : "fe6cb20",
17 "build_date" : "2019-07-24T17:58:29.979462Z",
18 "build_snapshot" : false,
19 "lucene_version" : "8.0.0",
20 "minimum_wire_compatibility_version" : "6.8.0",
21 "minimum_index_compatibility_version" : "6.0.0-beta1"
22 },
23 "tagline" : "You Know, for Search"
24}
目录结构
类型 | 描述 | 默认位置 | 设置 |
---|---|---|---|
bin | 二进制脚本包含启动节点的 Elasticsearch | {path.home}/bin | |
conf | 配置文件包含 elasticsearch.yml | {path.home}/config | path.conf |
data | 在节点上申请的每个 index/shard 的数据 ⽂件的位置。 可容纳多个位置 | {path.home}/data | path.data |
logs | ⽇志 ⽂件位置 | {path.home}/logs | path.logs |
plugins | 插件 ⽂件位置。每个插件将包含在 ⼀个 ⼦ ⽬录中。 | {path.home}/plugins | path.plugins |
Elastic Search 核 ⼼概念
- 索引(index):⼀个索引可以理解成 ⼀个关系型数据库。
- 类型(type):⼀种 type 就像 ⼀类表,⽐如 user 表,order 表。
1ES 5.x中⼀个index可以有多种type。
2ES 6.x中⼀个index只能有⼀种type。
3ES 7.x以后已经移除type这个概念。
- 映射(mapping):mapping 定义了每个字段的类型等信息。相当于关系型数据库中的表结构。
- ⽂档(document):⼀个 document 相当于关系型数据库中的 ⼀ ⾏记录。
- 字段(field):相当于关系型数据库表的字段。
- 集群(cluster):集群由 ⼀个或多个节点组成,⼀个集群有 ⼀个默认名称"elasticsearch"。
- 节点(node):集群的节点,⼀台机器或者 ⼀个进程。
- 分 ⽚和副本(shard)
1副本是分⽚的副的版本。
2分⽚有主分⽚(primary Shard)和副本分⽚(replica Shard)之分。
3⼀个Index数据在物理上被分布在多个主分⽚中,每个主分⽚只存放部分数据。
4每个主分⽚可以有多个副本,叫副本分⽚,是主分⽚的复制。
RESTFul 风格
RESTFul 是 ⼀种架构的规范与约束、原则,符合这种规范的架构就是 RESTFul 架构。英 ⽂ Representational state transfer 表述性状态转移,其实就是对 资源的表述性状态转移,即通过 HTTP 动词来实现资源的状态扭转:资源是 REST 系统的核 ⼼概念。 所有的设计都是以资源为中 ⼼。Elasticsearch 使 ⽤ RESTFul ⻛格 API 来设计的。
action | 描述 |
---|---|
HEAD | 只获取某个资源的头部信息 |
GET | 获取资源 |
POST | 创建或更新资源 |
PUT | 创建或更新资源 |
DELETE | 删除资源 |
1GET /user:列出所有的⽤户
2POST /user:新建⼀个⽤户
3PUT /user:更新某个指定⽤户的信息
4DELETE /user/ID:删除指定⽤户
5
6# 获取elasticsearch状态
7curl -X GET "http://localhost:9200"
8
9# 新增文档
10curl -X PUT "localhost:9200/soulboy/_doc/1" -H 'Content-Type: application/json' -d' { "user" : "louis", "message" : "louis is good" },
11
12# 删除文档
13curl -X DELETE "localhost:9200/soulboy/_doc/1"
索引的介绍和使用
1# 新增索引
2[root@localhost ~]# curl -X PUT "localhost:9200/nba"
3{
4 "acknowledged": true,
5 "shards_acknowledged": true,
6 "index": "nba"
7}
8
9# 获取
10[root@localhost ~]# curl -X GET "localhost:9200/nba"
11{
12 "nba": {
13 "aliases": { },
14 "mappings": { },
15 "settings": {
16 "index": {
17 "creation_date": "1572400849115",
18 "number_of_shards": "1",
19 "number_of_replicas": "1",
20 "uuid": "So0N7BVRQz6Kj7VaEdaJlA",
21 "version": {
22 "created": "7020199"
23 },
24 "provided_name": "nba"
25 }
26 }
27 }
28}
29
30# 批量获取索引
31[root@localhost ~]# curl -X GET "localhost:9200/nba,cba"
32
33# 获取所有索引
34[root@localhost ~]# curl -X GET "localhost:9200/_all"
35
36# 获取所有索引
37[root@localhost ~]# curl -X GET "localhost:9200/_cat/indices?v"
38health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
39yellow open cba kb0FGz0oT6WTT6zzIc5rgA 1 1 0 0 283b 283b
40yellow open nba So0N7BVRQz6Kj7VaEdaJlA 1 1 0 0 283b 283b
41
42# 判断索引是否存在
43[root@localhost ~]# curl -I "localhost:9200/nba"
44HTTP/1.1 200 OK
45content-type: application/json; charset=UTF-8
46content-length: 225
47
48# 关闭索引
49[root@localhost ~]# curl -X POST "localhost:9200/nba/_close"
50# 开启索引
51[root@localhost ~]# curl -X POST "localhost:9200/nba/_open"