ElasticSearch
全文搜索引擎
全 ⽂搜索引擎是 ⽬前 ⼴泛应 ⽤的主流搜索引擎。它的 ⼯作原理是计算机索引程序通过扫描 ⽂章中的每 ⼀个词,对每 ⼀个词建 ⽴ ⼀个索引,指明该词在 ⽂章中出现的次数和位
置,当 ⽤户查询时,检索程序就根据事先建 ⽴的索引进 ⾏查找,并将查找的结果反馈给 ⽤户的。
数据分类
- 结构化数据:通常可以通过 TRDB 以表的方式存储和搜索、也可以建立索引,通过 b-tree 等数据结构快速搜索数据。
- 非结构化数据:全文数据,不定长或无固定格式的数据。例如:邮件、word 文档等。对非结构化数据的搜索方法有两种:顺序扫描法、全文搜索法。
顺序扫描法
按字 ⾯意思,我们可以了解它的 ⼤概搜索 ⽅式,就是按照顺序扫描的 ⽅式查找特定的关键字。⽐如让你在 ⼀篇篮球新闻中,找出"科 ⽐"这个名字在哪些段落出现过。那你肯定需要从头到尾把 ⽂章阅读 ⼀遍,然后标记出关键字在哪些地 ⽅出现过。这种 ⽅法毋庸置疑是最低效的,如果 ⽂章很 ⻓,有 ⼏万字,等你阅读完这篇新闻找到"科 ⽐"这个关键字,那得花多少时间。
全文搜索法
对 ⾮结构化数据进 ⾏顺序扫描很慢,可以将 ⾮结构化数据中的 ⼀部分信息提取出来,重新组织,使其变得有 ⼀定结构,然后对这些有 ⼀定结构的数据进 ⾏搜索,从 ⽽达到搜索相对较快的 ⽬的。这种 ⽅式就构成了全 ⽂搜索的基本思路。这部分从 ⾮结构化数据中提取出的然后重新组织的信息,我们称之索引。
为什么不用 MySQL 做全文搜索?
- 数据类型:全 ⽂索引搜索很好的 ⽀持 ⾮结构化数据的搜索,可以更好地快速搜索 ⼤量存在的任何单词 ⾮结构化 ⽂本。
例如 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,并且配置好相 关的
- 创建用户与组
[root@localhost bin]# groupadd elsearch
[root@localhost bin]# useradd elsearch -g elsearch
[root@localhost bin]# passwd elsearch
[root@localhost software]# chown -R elsearch:elsearch elasticsearch-7.2.1
- 环境变量 mac/linux,打开软件的安装路径,进 ⼊到 bin⽬录,
启动方式
sh elasticsearch.sh
守护进程的⽅ 式可以使⽤
sh elasticsearch.sh -d -p pid
sh elasticsearch -d -p 9999
验证
[elsearch@localhost bin]$ curl http://localhost:9200
{
"name" : "localhost.localdomain",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "qu8IpbtWTQes05d5dnVUvQ",
"version" : {
"number" : "7.2.1",
"build_flavor" : "oss",
"build_type" : "tar",
"build_hash" : "fe6cb20",
"build_date" : "2019-07-24T17:58:29.979462Z",
"build_snapshot" : false,
"lucene_version" : "8.0.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
目录结构
类型 | 描述 | 默认位置 | 设置 |
---|---|---|---|
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 表。
ES 5.x中⼀个index可以有多种type。
ES 6.x中⼀个index只能有⼀种type。
ES 7.x以后已经移除type这个概念。
- 映射(mapping):mapping 定义了每个字段的类型等信息。相当于关系型数据库中的表结构。
- ⽂档(document):⼀个 document 相当于关系型数据库中的 ⼀ ⾏记录。
- 字段(field):相当于关系型数据库表的字段。
- 集群(cluster):集群由 ⼀个或多个节点组成,⼀个集群有 ⼀个默认名称"elasticsearch"。
- 节点(node):集群的节点,⼀台机器或者 ⼀个进程。
- 分 ⽚和副本(shard)
副本是分⽚的副的版本。
分⽚有主分⽚(primary Shard)和副本分⽚(replica Shard)之分。
⼀个Index数据在物理上被分布在多个主分⽚中,每个主分⽚只存放部分数据。
每个主分⽚可以有多个副本,叫副本分⽚,是主分⽚的复制。
RESTFul 风格
RESTFul 是 ⼀种架构的规范与约束、原则,符合这种规范的架构就是 RESTFul 架构。英 ⽂ Representational state transfer 表述性状态转移,其实就是对 资源的表述性状态转移,即通过 HTTP 动词来实现资源的状态扭转:资源是 REST 系统的核 ⼼概念。 所有的设计都是以资源为中 ⼼。Elasticsearch 使 ⽤ RESTFul⻛格 API 来设计的。
action | 描述 |
---|---|
HEAD | 只获取某个资源的头部信息 |
GET | 获取资源 |
POST | 创建或更新资源 |
PUT | 创建或更新资源 |
DELETE | 删除资源 |
GET /user:列出所有的⽤户
POST /user:新建⼀个⽤户
PUT /user:更新某个指定⽤户的信息
DELETE /user/ID:删除指定⽤户
# 获取elasticsearch状态
curl -X GET "http://localhost:9200"
# 新增文档
curl -X PUT "localhost:9200/soulboy/_doc/1" -H 'Content-Type: application/json' -d' { "user" : "louis", "message" : "louis is good" },
# 删除文档
curl -X DELETE "localhost:9200/soulboy/_doc/1"
索引的介绍和使用
# 新增索引
[root@localhost ~]# curl -X PUT "localhost:9200/nba"
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "nba"
}
# 获取
[root@localhost ~]# curl -X GET "localhost:9200/nba"
{
"nba": {
"aliases": { },
"mappings": { },
"settings": {
"index": {
"creation_date": "1572400849115",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "So0N7BVRQz6Kj7VaEdaJlA",
"version": {
"created": "7020199"
},
"provided_name": "nba"
}
}
}
}
# 批量获取索引
[root@localhost ~]# curl -X GET "localhost:9200/nba,cba"
# 获取所有索引
[root@localhost ~]# curl -X GET "localhost:9200/_all"
# 获取所有索引
[root@localhost ~]# curl -X GET "localhost:9200/_cat/indices?v"
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open cba kb0FGz0oT6WTT6zzIc5rgA 1 1 0 0 283b 283b
yellow open nba So0N7BVRQz6Kj7VaEdaJlA 1 1 0 0 283b 283b
# 判断索引是否存在
[root@localhost ~]# curl -I "localhost:9200/nba"
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 225
# 关闭索引
[root@localhost ~]# curl -X POST "localhost:9200/nba/_close"
# 开启索引
[root@localhost ~]# curl -X POST "localhost:9200/nba/_open"