小土刀

Elasticsearch 入门指南

日志作为运维中非常重要的一环,往往只有在出了问题的时候才被重视起来,不同部门,不同项目的不同日志如果能够统一规范管理,对日常的开发和业务的运营都是有很大帮助的,这里我们来了解一下实时日志处理领域开源第一选择 - ELK 套餐中的 E - Elasticsearch


更新记录

  • 2016.07.24: 初稿
  • 2016.11.19: 更新通天塔之日志分析平台系列文章链接

通天塔之日志分析平台系列文章

简介

如果前些年涉及过搜索相关技术,一定对 Lucene 不陌生,作为最知名的用于全文检索的开源库,在其上出现了很多非常方便的应用,本文所说的 Elasticsearch 就是其中之一。Elasticsearch 是一个实时分布式搜索和分析引擎,可以用来全文搜索、结构化搜索内容并对其进行分析。Elasticsearch 基于 RESTful API 原则设计,稳定可靠的同时,做到了安装部署方便,不仅可以在笔记本上跑,也可以在服务器集群上运行。

具体的特性我就直接搬运官网的介绍吧,具体为:

  • 分布式高可用的搜索引擎
    • 每个索引根据配置的分片数量完成完全分片
    • 每个分片都可以有一个或多个副本
    • 读/搜索操作可以在任何复制的分片上执行
  • 支持多租户与多种类型
    • 支持多个索引
    • 每个索引支持多个类型
  • 支持各类 API
    • HTTP RESTful API
    • Java API
  • 基于 Lucene
    • 每个分片都是一个功能齐全的 Lucene 索引
    • 可以轻松访问每个 Lucene
  • 单文档级别的操作满足操作系统的事务性

安装配置

在 Mac 下安装非常简单,直接 brew install elasticsearch 即可

$ brew install elasticsearch
==> Downloading https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearc
######################################################################## 100.0%
==> Caveats
Data: /usr/local/var/elasticsearch/elasticsearch_dawang/
Logs: /usr/local/var/log/elasticsearch/elasticsearch_dawang.log
Plugins: /usr/local/Cellar/elasticsearch/2.3.3/libexec/plugins/
Config: /usr/local/etc/elasticsearch/
plugin script: /usr/local/Cellar/elasticsearch/2.3.3/libexec/bin/plugin
To have launchd start elasticsearch now and restart at login:
brew services start elasticsearch
Or, if you don't want/need a background service you can just run:
elasticsearch
==> Summary
🍺 /usr/local/Cellar/elasticsearch/2.3.3: 59 files, 29.4M, built in 1 minute 40 seconds

具体什么文件夹放什么还是非常清晰的,这里就不赘述了。因为我是在自己的电脑上测试,就不弄成开机启动了,需要的时候,在命令行中执行 elasticsearch 即可。

运行起来后,在浏览器中访问 localhost:9200 就可以看到如下界面:

其他常用插件,比如 Marvel 等,会在后面的文章中介绍,这里主要介绍基本入门。

基本概念

面向文档

和 Mongodb 的思路类似,Elasticsearch 中保存的是整个文档(document),并且还会根据文档的内容进行索引,于是我们得以进行搜索、排序和过滤等操作。在 Elasticsearch 中,利用 JSON 来表示文档。举个例子,下面的 JSON 文档就表示一个用户对象:

{
"email": "dawang@wdxtub.com",
"name": "Da Wang",
"info": {
"bio": "Sharp Blade, Shape Mind",
"age": "25",
"interests": ["games", "music"]
},
"birthday": "1990/09/11"
}

不同的『索引』

在 Elasticsearch 中存储数据的行为就叫做索引(indexing),而前面提到的文档,属于一种类型(type),这里类型会存在索引(index)中,如果列一个表来和传统数据库比较,大概是这样的:

关系型数据 Elasticsearch
Databases Indices
Tables Types
Rows Documents
Columns Fields

一个 Elasticsearch 集群可以包含多个索引(indices,对应于『数据库』),每个索引可以包含多个类型(types,对应于『表』),每个类型可以包含多个文档(document,对应于『行』),每个文档可以包含多个字段(fields,对应于『列』)

这里有一点需要强调一下,前面出现了两种『索引』,第一种,索引(indexing,动词,对应于关系型数据库的插入 insert)指的是把一个文档存储到索引(index,名词) 中;第二种的索引(index,名词)对应于关系型数据库的数据库,这里一定要根据上下文来进行理解。一般来说,我们会对数据库增加索引(这里是第三种意思,就是传统的索引的定义)来提高检索效率,Elasticsearch 和 Lucene 使用『倒排索引』的数据结构来完成这个工作(传统数据库一般用红黑树或者 B 树来完成)。默认情况下,文档中的每个字段都会拥有其对应的倒排索引,Elasticsearch 也是通过这个来进行检索的。

Hello World

我们用一个简单的例子来感受一下 Elasticsearch 的威力吧。设定一个场景,有一天我开了一家名为 “ohmywdx” 的公司,我需要为每个公司里的员工创建记录,我需要做的是:

  • 为每个员工的文档(document)建立索引,每个文档包含一个员工的各类信息,类型为 wdxtuber
  • wdxtuber 类型属于索引 ohmywdx(这里的索引对应于数据库)
  • ohmywdx 索引存储在 Elasticsearch 集群中

存储(索引,动词)

我们来插入几条员工记录

PUT /ohmywdx/wdxtuber/1
{
"name": "Da Wang",
"age": 25,
"about": "First one who is stupid enough to join this company",
"interests": ["game", "music"]
}
PUT /ohmywdx/wdxtuber/2
{
"name": "Tracy Bryant",
"age": 20,
"about": "First basketball robot for our company",
"interests": ["guard", "forward"]
}
PUT /ohmywdx/wdxtuber/3
{
"name": "Shadow Mouse",
"age": 50,
"about": "Secret agent for our company",
"interests": ["guitar", "sugar"]
}

具体怎么插入呢,我们可以用一个名叫 Postman 的 Chrome 插件来完成,如下图所示

点击发送,就可以看到如下的响应:

{
"_index": "ohmywdx",
"_type": "wdxtuber",
"_id": "1",
"_version": 1,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}

按照这个套路,继续把其他两个人的资料发送给 Elasticsearch。

搜索

我们来看看如何搜索,简单来说,按照存储的方式来检索即可,不过这里我们使用 GET 方法,如下图所示:

我们可以看到,原始文档内容包含在 _source 字段中。如果说这个搜索太明确了,啥都指定了没意思,我们可以来试试看下面几条搜索

  • GET /ohmywdx/wdxtuber/_search
  • GET /ohmywdx/wdxtuber/_search?q=name:Da

这里我们来看看第二个搜索的结果

{
"took": 76,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.19178301,
"hits": [
{
"_index": "ohmywdx",
"_type": "wdxtuber",
"_id": "1",
"_score": 0.19178301,
"_source": {
"name": "Da Wang",
"age": 25,
"about": "First one who is stupid enough to join this company",
"interests": [
"game",
"music"
]
}
}
]
}
}

除了 _source 的信息之外,我们可以看到有一个 _score,敏感的同学大概会意识到,Elasticsearch 是根据相关性来对结果进行排序的,这个得分就是相关性分数。

除了前面说明的搜索,我们还可以使用 DSL 语句来组合更加复杂的搜索,什么过滤、组合条件、全文、短语搜索,都不在话下,我们甚至可以高亮搜索结果,这些都可以在 Elasticsearch 权威指南 找到,这里我就不赘述了。

另外我们还可以利用『聚合』来实现关系型数据库中『Group By』类似的操作。其他诸如推荐、定位、渗透、模糊及部分匹配同样也支持,不过这些以后会结合实际开发的过程慢慢写。

分布式

这里简单说一下 Elasticsearch 的分布式吧。开发人员花了很多心思,尽量让一台机上运行和集群上运行的体验一致,具体说,Elasticsearch 在底层主要做的工作有:

  • 根据配置进行数据分片(sharding),并且保存在一个或者多个节点中
  • 将分片均匀分配到各个节点,对索引和搜索做负载均衡
  • 分片冗余,提高容错性
  • 将集群中任意一个节点上的请求路由到相应数据所在的节点
  • 增加或者移除节点时无缝迁移数据

总结

本文中我们简单了解了 Elasticsearch 的基本用法,接下来会在工作的同时继续写一系列深入理解 ELK Stack 的文章,希望大家喜欢。

参考链接

捧个钱场?

热评文章