目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

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}/configpath.conf
data在节点上申请的每个 index/shard 的数据 ⽂件的位置。 可容纳多个位置{path.home}/datapath.data
logs⽇志 ⽂件位置{path.home}/logspath.logs
plugins插件 ⽂件位置。每个插件将包含在 ⼀个 ⼦ ⽬录中。{path.home}/pluginspath.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"

作者:Soulboy