初探Elasticsearch的学习之路
1. Elasticsearch 概述
1.1 Elasticsearch 是什么
Elastic Stack包含Elasticsearch、Kibana、Beats和Logstash(也叫ELK Stack)。它能够安全可靠地获取来自任何来源、任何格式的数据,然后实时对数据进行搜索、分析和可视化。
Elasticsearch,简称ES,是一个开源的高扩展性分布式全文搜索引擎,是Elastic Stack技术栈的核心。它能近乎实时地存储和检索数据,自身扩展性良好,可扩展到上百台服务器,处理PB级别的数据。
1.2 全文搜索引擎
像Google、百度这类网站搜索,它们依据网页中的关键字生成索引,用户输入关键字时,会将匹配该关键字的所有网页返回;还有项目中的应用日志搜索等情况。对于非结构化的数据文本,传统关系型数据库的搜索支持不佳。
一般传统数据库的全文检索功能很不理想,因为通常没人用数据库存储文本字段。进行全文检索得扫描整个表,数据量大时即便优化SQL语法,效果也有限。而且建立索引后维护麻烦,Insert和Update操作都得重新构建索引。
基于这些情况能分析出,在一些生产环境中,用常规搜索方式性能很差:
– 搜索对象是大量非结构化文本数据
– 文件记录量达数十万甚至更多
– 支持大量交互式文本查询
– 需求灵活的全文搜索查询
– 对高度相关搜索结果有特殊需求,而现有关系数据库无法满足
– 对不同记录类型、非文本数据操作或安全事务处理需求较少
为解决结构化和非结构化数据搜索的性能问题,就需要专业、健壮、强大的全文搜索引擎。
这里说的全文搜索引擎是目前广泛应用的主流搜索引擎。其工作原理是计算机索引程序扫描文章中的每个词,为每个词建立索引,标明该词在文章中的出现次数和位置,用户查询时,检索程序依据事先建立的索引查找,并将结果反馈给用户,这过程类似通过字典检索字表查字。
1.3 Elasticsearch And Solr
Lucene是Apache软件基金会Jakarta项目组的子项目,提供简单却强大的应用程序接口,能做全文索引和搜索。在Java开发环境中,Lucene是成熟的免费开源工具。就其本身而言,Lucene是近年最受欢迎的免费Java信息检索程序库。但Lucene只是提供全文搜索功能类库的核心工具包,真正使用还需搭建完善服务框架。
目前市面上流行的搜索引擎软件,主流的有两款:Elasticsearch
和Solr
,它们都基于Lucene
搭建,是可独立部署启动的搜索引擎服务软件。由于内核相同,两者在服务器安装、部署、管理、集群等方面,以及对数据的操作(修改、添加、保存、查询等)十分相似。
使用时通常会对比Elasticsearch和Solr并进行选型。这两个搜索引擎都是流行且先进的开源搜索引擎,都围绕核心底层搜索库 – Lucene构建,但又各有不同。和所有事物一样,它们各有优缺点:
1.4 Elasticsearch Or Solr
Elasticsearch和Solr都是开源搜索引擎,使用时该如何选择呢?
-
Google搜索趋势显示,Elasticsearch比Solr更具吸引力,但这并不意味着Apache Solr已过时。尽管有人这么认为,但Solr仍是最受欢迎的搜索引擎之一,拥有强大社区和开源支持。
-
相比Solr,Elasticsearch易于安装且轻巧,能在几分钟内安装并运行。不过若管理不当,这种易部署易用性可能成问题。基于JSON的配置简单,但若要为文件中的每个配置添加注释,它可能不适用。总体而言,若应用使用JSON,Elasticsearch是更好选择;否则,用Solr,因其schema.xml和solrconfig.xml文档记录良好。
-
Solr有更大、更成熟的用户、开发者和贡献者社区。ES虽用户社区规模较小但活跃,贡献者社区在不断增长。Solr贡献者和提交者来自多个不同组织,而Elasticsearch提交者来自单个公司。
-
Solr更成熟,而ES增长迅速且更稳定。
-
Solr文档非常详尽,有清晰示例和API用例场景。Elasticsearch文档组织良好,但缺乏好示例和清晰配置说明。
那么,到底选Solr还是Elasticsearch?
有时很难找到明确答案。无论选Solr还是Elasticsearch,首先要了解正确用例和未来需求。总结它们的各属性:
– 因易用性,Elasticsearch在新开发者中更受欢迎,下载一个命令就能启动。
– 若除搜索文本外还需处理分析查询,Elasticsearch更合适。
– 若需分布式索引,选Elasticsearch。对于需要良好可伸缩性和性能的分布式环境,Elasticsearch是更好选择。
– Elasticsearch在开源日志管理用例中占主导,许多组织用Elasticsearch索引日志使其可搜索。
– 若喜欢监控和指标,用Elasticsearch,因其比Solr暴露更多关键指标。
1.5 Elasticsearch 应用案例
- GitHub:2013年初,放弃Solr,采用Elasticsearch处理PB级搜索。“GitHub用Elasticsearch搜索20TB数据,包括13亿文件和1300亿行代码”。
- 维基百科:构建基于Elasticsearch的核心搜索架构。
- SoundCloud:“SoundCloud用Elasticsearch为1.8亿用户提供即时精准的音乐搜索服务”。
- 百度:广泛使用Elasticsearch进行文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过多维分析展示辅助定位分析实例或业务层面异常。目前覆盖百度内部20多个业务线(包括云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,每天导入30TB+数据。
- 新浪:用Elasticsearch分析处理32亿条实时日志。
- 阿里:用Elasticsearch构建日志采集和分析体系。
- Stack Overflow:解决Bug问题的全英文编程人员交流网站。
2. Elasticsearch 安装
2.1 下载软件
- 官方地址:https://www.elastic.co/cn/
- 下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
2.2 安装软件
Windows版Elasticsearch安装简单,解压即完成。解压后的Elasticsearch目录结构如下:
目录 | 含义 |
---|---|
bin | 可执行脚本目录 |
config | 配置目录 |
jdk | 内置JDK目录 |
lib | 类库 |
logs | 日志目录 |
modules | 模块目录 |
plugins | 插件目录 |
解压后,进入bin目录,点击elasticsearch.bat文件启动ES服务。
注意:9300
端口是Elasticsearch集群间组件通信端口,9200
端口是浏览器访问的Http协议RESTful端口。
打开浏览器(推荐谷歌浏览器),输入地址:http://localhost:9200
,测试结果。
2.3 问题解决
- Elasticsearch用Java开发,7.8版本的ES需JDK1.8及以上,默认安装包带jdk环境,若系统配置JAVA_HOME,用系统默认JDK,否则用自带JDK,一般建议用系统配置的JDK。
- 双击启动窗口闪退,通过路径访问追踪错误,若为“空间不足”,修改config/jvm.options配置文件:
# 设置JVM初始内存为1G。此值可设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
# Xms represents the initial size of total heap space
# 设置JVM最大可用内存为1G
# Xmx represents the maximum size of total heap space
-Xms1g
-Xmx1g
3. Elasticsearch 基本操作
3.1 RESTful
REST指一组架构约束条件和原则,满足这些条件的应用或设计就是RESTful。Web应用程序最重要的REST原则是客户端和服务器间交互在请求间无状态。
客户端到服务器的每个请求须包含理解请求所需信息。若服务器在请求间重启,客户端不被通知。此外,无状态请求可由任何可用服务器响应,适合云计算环境。客户端可缓存数据提升性能。
服务器端应用程序状态和功能可分为各种资源,资源是向客户端公开的有趣概念实体。
资源例子有应用程序对象、数据库记录、算法等。每个资源用URI(统一资源标识符)获唯一地址。所有资源共享统一接口在客户端和服务器间传输状态,使用标准HTTP方法,如GET、PUT、POST和DELETE。
简单说,若要访问互联网资源,须向资源所在服务器发请求,请求体含资源网络路径及对资源的操作(增删改查)。
3.2 客户端安装
若直接用浏览器向Elasticsearch服务器发请求,需在请求中含HTTP标准方法,而HTTP大部分特性仅支持GET和POST方法。为方便客户端访问,可用Postman软件。
Postman是强大网页调试工具,提供功能强大的Web API和HTTP请求调试。软件功能强,界面简洁,操作方便,人性化。Postman中文版可发送任何类型HTTP请求(GET, HEAD, POST, PUT等),不仅能表单提交,还可附带任意类型请求体。
- Postman官网:https://www.getpostman.com
- Postman下载:https://www.getpostman.com/apps
3.3 数据格式
Elasticsearch是面向文档型数据库,一条数据是一个文档。为方便理解,将Elasticsearch存储文档数据与关系型数据库MySQL存储数据概念类比:
ES里的Index可看作库,Types相当于表,Documents则相当于表的行。这里Types概念逐渐弱化,Elasticsearch 6.X中一个index下只能有一个type,7.X中Type概念已删除。
6用JSON作为文档序列化格式,比如一条用户信息:
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"birthDate": "1990/05/01",
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
3.4 HTTP 操作
3.4.1 索引操作
1. 创建索引
对比关系型数据库,创建索引相当于创建数据库。
在Postman中,向ES服务器发PUT
请求:http://127.0.0.1:9200/shopping
请求后,服务器响应:
{
"acknowledged"【响应结果】: true, # true表示操作成功
"shards_acknowledged"【分片结果】: true, # 分片操作成功
"index"【索引名称】: "shopping"
}
注意:创建索引库的分片数默认1片,7.0.0之前版本默认5片。重复添加索引会报错。
2. 查看所有索引
在Postman中,向ES服务器发GET
请求:http://127.0.0.1:9200/_cat/indices?v
_cat
表示查看,indices
表示索引,即查看当前ES服务器所有索引,类似MySQL的show tables
。服务器响应结果表头及含义:
表头 | 含义 |
---|---|
health | 当前服务器健康状态:green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) |
status | 索引打开、关闭状态 |
index | 索引名 |
uuid | 索引统一编号 |
pri | 主分片数量 |
rep | 副本数量 |
docs.count | 可用文档数量 |
docs.deleted | 文档删除状态(逻辑删除) |
store.size | 主分片和副分片整体占空间大小 |
pri.store.size | 主分片占空间大小 |
3. 查看单个索引
在Postman中,向ES服务器发GET
请求:http://127.0.0.1:9200/shopping
查看索引的请求路径与创建索引一致,但HTTP方法不同,体现RESTful意义。请求后服务器响应:
{
"shopping"【索引名】: {
"aliases"【别名】: {},
"mappings"【映射】: {},
"settings"【设置】: {
"index"【设置 - 索引】: {
"creation_date"【设置 - 索引 - 创建时间】: "1614265373911",
"number_of_shards"【设置 - 索引 - 主分片数量】: "1",
"number_of_replicas"【设置 - 索引 - 副分片数量】: "1",
"uuid"【设置 - 索引 - 唯一标识】: "eI5wemRERTumxGCc1bAk2A",
"version"【设置 - 索引 - 版本】: {
"created": "7080099"
},
"provided_name"【设置 - 索引 - 名称】: "shopping"
}
}
}
}
4. 删除索引
在Postman中,向ES服务器发DELETE
请求:http://127.0.0.1:9200/shopping
重新访问该索引时,服务器返回索引不存在。
3.4.2 文档操作
1. 创建文档
索引创建好后,创建文档并添加数据,文档类似关系型数据库表数据,数据格式为JSON。
在Postman中,向ES服务器发POST
请求:http://127.0.0.1:9200/shopping/_doc
请求体内容:
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
此处请求方式须为POST
,不能是PUT
,否则报错。服务器响应:
{
"_index"【索引】: "shopping",
"_type"【类型-文档】: "_doc",
"_id"【唯一标识】: "Xhsa2ncBlvF_7lxyCE9G", # 类似MySQL主键,随机生成
"_version"【版本】: 1,
"result"【结果】: "created", # 创建成功
"_shards"【分片】: {
"total"【分片 - 总数】: 2,
"successful"【分片 - 成功】: 1,
"failed"【分片 - 失败】: 0
},
"_seq_no": 0,
"_primary_term": 1
}
若自定义唯一性标识,创建时指定:http://127.0.0.1:9200/shopping/_doc/1
,此时请求方式也可为PUT
。
2. 查看文档
查看文档需指明唯一性标识,类似MySQL主键查询。
在Postman中,向ES服务器发GET
请求:http://127.0.0.1:9200/shopping/_doc/1
查询成功后服务器响应:
{
"_index"【索引】: "shopping",
"_type"【文档类型】: "_doc",
"_id": "1",
"_version": 2,
"_seq_no": 2,
"_primary_term": 2,
"found"【查询结果】: true, # true表示查找到,false表示未查找到
"_source"【文档源信息】: {
"title": "华为手机",
"category": "华为",
"images": "http://www.gulixueyuan.com/hw.jpg",
"price": 4999.00
}
}
3. 修改文档
与新增文档相同,输入相同URL地址请求,若请求体变化,会覆盖原有数据。
在Postman中,向ES服务器发POST
请求:http://127.0.0.1:9200/shopping/_doc/1
请求体内容:
{
"title":"华为手机",
"category":"华为",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4999.00
}
修改成功后服务器响应:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version"【版本】: 2,
"result"【结果】: "updated", # 数据被更新
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}
4. 修改字段
修改数据时可只修改局部信息。
在Postman中,向ES服务器发POST
请求:http://127.0.0.1:9200/shopping/_update/1
请求体内容:
{
"doc": {
"price": 3000.00
}
}
修改成功后,查询文档数据已更新。
5. 删除文档
删除文档只是标记为已