初探ElasticSearch

123 阅读8分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

前言

        目前大多数的系统都是把数据存储在MySQL中,并且对数据的操作也是读多写少的情况,在这种情况下,仅仅只通过数据库来支撑大量的查询是不可取的。而且对于一些复杂的查询,MySQL支持得也不是很好,当然毕竟术业有专攻,数据库终究只适合做存储,查询服务还是要用更为专业的组件去做,这就是本文的主角:ElasticSearch

         Elasticsearch是一款基于Lucene,功能强大的分布式搜索引擎,支持近实时的存储、搜索数据,它的定位是全文搜索引擎。提供垂直搜索功能,

        全文检索的工作原理就是计算机索引程序通过扫描文本中的每一个词,对每一个词建立一个索引,并且记录这个词在文本中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找并返回。类似于通过字典中的检索字表查字的过程。

        垂直搜索则是在特定行业特定领域对专门的数据进行搜索整合,相比较通用搜索引擎的海量信息无序化,垂直搜索引擎则更加深入、具体。例如企业OA查询订单、人员、部门,电商网站内部搜索商品等。

应用场景

        那么ES的应用场景主要分为两大类,主要是搜索类和日志类:

  • 搜索服务:也就是前面所提到的全文检索,例如站内搜索,检索/搜索的基本原理就是对语句进行分词,然后再形成倒排索引,再根据词项出现次数对文档进行打分,最终按分数倒序展示给用户。

  • 日志实时分析:没有日志系统的情况下,开发人员只能登陆到机器去一台一台寻找可能的错误日志,日志系统的工作就是把日志汇集到一起,并提供统一的查询入口。ES支持各种日志的采集和分析,通过logstash进行转换,输送到ES中,然后通过Kibana进行展示。这也是ES的日志分析解决方案ELK。

搜索服务

        例如百度搜索,根据关键字去查找内容,这就是全文检索,通过关键字在库中匹配内容。如果想实现这个功能,传统的数据库此时就不太能满足了,因为并不适合:

  1. 数据库字段太多会导致查询太慢,索引也没有办法再做优化。
  2. 数据库一个count就拖死全表,现在最流行的innodb之类的存储引擎在计算count的时候非常的慢。有人说myIsam会更快,但其实只要在select语句的where条件中有表达式时,这两种存储引擎本质上都是一样的,都会很慢。
  3. MySQL的limit翻到几十几百万页后实在太慢,因为他会把所有的数据都读取到内存中,再去取limit的那几条,如果在加order by 的话,又会涉及到磁盘的读取和排序,只会更慢。
  4. 数据库like实在太慢,本质还是查询内容去和数据库字段做字符串匹配,会导致整个服务器cpu内存飙高。

        此时再使用传统数据库去实现,就会显得鸡肋,因为一般传统的关系型数据库,在全文索引方面,做的都不怎么好,毕竟关系型数据库的使用重点也不在这上面,自然也不会有人用关系型数据库去存储这种非结构化数据,更不会有人去用它做全文检索。此时就需要更专业,更定向的搜索引擎去实现这些需求。

对比示例

对数据的查询一般可以分为三种:

  1. 列表查询:列表页对应的查询,一些表单信息。
  2. 详情查询:针对具体id对应的详情查询。
  3. 统计查询:一些数值之类的报表,也就是一堆count值。

        这三种查询里,MySQL做起来最困难的就是是列表查询和统计查询。因为列表查询会对应各种各样的查询条件,例如字段等于/小于/大于/不等判断,或者像字符串的严格匹配/前后缀模糊查询,时间字段的范围查询,in查询等等。这些查询都可以翻译为ES中的bool查询,举一个简单的例子:

select * from db/table where create_time between ('2016-08-11 00:00:00' and '2016-08-11 23:59:59')
 and user_id = 37540 and status in (2, 1, 0);

上面sql语句翻译为ES的bool查询就是如下:

{
    "from" : 0,
    "size" : 15,
    "query" : {
        "bool": {
            "must" : [{"range" : {"create_time" : {"from":"2016-08-11T00:00:00+0800","to":"2016-08-11T23:59:00+0800"}}},{"term" : {"user_id" : "37540"}},{"terms" : {"status" : [2,1,0]}}]
        }
    },
    "sort" : [{"create_time" : "desc"}],
    "highlight" : {
    }
}

        在统计查询这方面的话,因为ES本身会把单个字段的一种值当作一个term,然后会记录这个term出现的所有文档和出现次数。所以在count的时候,es也就只是去读了一下这个值。

        通过上面例子与对比可以看出,他和mysql的关系更像是一种互补的关系,相比与mysql来说,ES显得更专一,深入,更适合某些特定的场景下使用。

日志服务

        ELK是一个免费开源的日志分析框架,官网。包含三大基础组件,分别是Elasticsearch、Logstash、Kibana。但实际上ELK不仅仅适用于日志分析,它还支持其它任何数据搜索、分析和收集的场景,日志分析和收集只是更有代表性。应用还非常广泛。如下是ELK的架构:

image.png

        随着ELK框架的发展,又有新成员Beats、elastic cloud的加入,所以就形成了Elastic Stack。所以说,ELK是旧的称呼,Elastic Stack是新的名字。

16352523881.png

  • 组件介绍:
  1. Elasticsearch:使用java开发,基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。

  2. Logstash:也是基于java开发,是一个数据抽取转化工具。一般工作方式为c/s架构,client端安装在需要收集信息的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch或其他组件上去。

  3. Kibana:基于nodejs开发,一款开源和免费的可视化工具。它为 Logstash 和 ElasticSearch 的日志分析提供了友好的 Web 界面,可以汇总、分析和搜索重要数据日志。

  4. Beats:集合了多种单一用途数据采集器。它们从成百上千或成千上万台机器和系统向 Logstash 或 Elasticsearch 发送数据。

优点与劣势

  • 优点
  1. 处理方式灵活
  2. 配置简单:安装elk的每个组件,仅需配置每个组件的一个配置文件即可。因为大量参数已经默认配在系统中,按需修改即可。
  3. 接口简单:采用json形式RESTFUL API接受数据并响应,无关语言。
  4. 性能高效:elasticsearch基于优秀的全文搜索技术Lucene,采用倒排索引,可以轻易地在百亿级别数据量下,搜索出想要的内容,并且是秒级响应。
  5. 灵活扩展:elasticsearch和logstash都可以根据集群规模线性拓展,elasticsearch内部自动实现集群协作。
  6. 展示美观:kibana作为前端展现工具,图表美观,配置简单。
  • 劣势
  1. es的查询语法设计还是有点别扭,从传统的sql转化为dsl会很麻烦。
  2. 当数据量上亿的时候,也会很慢。
  3. 实现联表查询会很难,实现事务也难上加难。

总结

        本文只是简单的了解了一下ElasticSearch的一些基本概念和主要的两个应用场景,它是一款很优秀的工具,在实际工作中,能利用这些工具,让我们的系统变得更完善更人性化,是一件非常有成就感的事。

        当然好工具,好框架也要花心思去深入研究,在日后也会更新关于ES的一些核心概念的内容。