刘备三顾茅庐,请Elasticsearch出山
之前分享的一篇《赤壁之战,曹操大败只因缺了Service Mesh》受到不少好评,今天我们继续通过“三国”学技术,讲的是 Elasticsearch 的前世今生。
话说吧,有这么三个人,刘备、关羽和张飞,刘备是老大,关羽是二哥,张飞是老三,三兄弟每天玩在一起,打魔兽玩星际,一起吃鸡,整天无所事事。
于是在一个白天不见月亮的早上,三人从网吧出来,刘备就说,咱们这样下去也不是事啊,这互联网是个机会,要不咱们做电商吧!
三人一商量,说干就干,于是乎,他们三人合伙在桃园注册成立了一家公司,起名叫徐州草鞋,主要是通过网络做天然有机草鞋生意(其实啊,刘备一堆草鞋卖不出去,也只能做这个业务,汗)。
刘备是总经理,负责商务,负责开拓客户市场。既然是搞电子商务,还得开发一个电子商务网站,于是关羽自告奋勇说他负责后端技术,张飞绣过花,会画画,说他可以负责前端。
好戏刚刚开始......
需求的诞生
刘备一大早就来到了公司,一看张飞和关羽已经在公司了,就问道:“两位贤弟,今天来的还蛮早啊。”
张飞一听就炸毛了,“大哥,你让我和二哥去做什么搜索功能,我们已经一晚没睡了,昨天就没回去好嘛。”
关羽也来气,“大哥,是啊,我们刚刚才上线电商网站,你这边又要加什么需求,现在用数据库检索不是好好的么,能不能让我们歇口气。”
“两位兄弟辛苦了,我也不想啊,最近咱们一单生意都没有啊。昨天我和一位朋友聊,他说我们的网站很不好用,找不到他想要的鞋,结果只好去别的地方买了。不过他给我推荐了一位黑客高手,叫诸葛亮的家伙,说是啥都懂,我们今天找他取经去。”
三顾茅庐
三人一行来找诸葛亮,不过前面两次都碰了壁。据诸葛亮书童说,诸葛亮不在家,到了第三次,还是不在家。
张飞仔细一听,明明是有人在家啊,而且玩游戏喊的声音还这么大,张飞怒了,搭梯子把诸葛亮家的保险给拔了。
诸葛亮正郁闷呢,咋停电了呢?算了,今天没得玩了,于是让书童请他们进来。
“在下诸葛名亮,字孔明,不知三位...”,三人一说,是这么这么回事。
诸葛亮一听,“哦,原来是这么这么回事啊,你们的网站我刚看了,你们家的草鞋品种确实不 Nan 少 Kan。如今客户上网站找东西,都是先用网站的搜索来搜一下,但是你们网站的搜索功能实在是太 La 弱 Ji,明摆在那里的商品我都搜不出来,实在是大问题啊。”
“这样啊,我看你们仨都是好人,给你们推荐一个好东西,叫做 Elasticsearch,这个肯定可以帮助你们。”
“翼德,把先生放下来吧。”
“是,大哥。二哥,你把刀也放下吧。”
关羽一听,好像在哪里听说过 Elasticsearch,“大哥,这个东西好像有点耳熟啊,哦,诸葛亮先生这一说,我倒是记起来了,隔壁公司的吕布最近神神秘秘的,好像就是在用这个,难怪他们最近公司业务好的很”。
Elasticsearch 的故事
诸葛亮清了清嗓子,又从抽屉里摸出一把扇子,“还是让我来给你们讲讲吧”。
“Elasticsearch 以前叫 Elastic Search。顾名思义,就是“弹性的搜索”。
很明显,它一开始是围绕着搜索功能,打造了一个分布式搜索引擎,底层是基于开源的搜索引擎库 Lucene,是由 Java 语言编写的,项目大概是 2010 年 2 月份在 Github 正式落户的。
咳咳,有必要首先给你介绍一下 Lucene。Lucene 是一个非常古老的搜索引擎工具包,也是用 Java 编写,主要用来构建倒排索引(一种数据结构)和对这些索引进行检索,从而实现全文检索功能。
Lucene 很强大,使用起来也非常灵活,缺点是它仅仅是一个基础类库,也没有考虑到高并发和分布式的场景。
如果你想在自己的程序里面使用 Lucene,还是需要做很多工作,并且涉及很多搜索原理和索引数据结构的知识,这就给我们带来了不少挑战。所以,Lucene 的上手时间一般都比较长。”
关羽插了一句,“Lucene 我知道,确实贼难用,使用起来一堆问题啊,我之前试过来着。” 关羽说完,脸又红了。
诸葛亮接着说:“时间一晃来到 2004 年,有一个以色列小伙子,名字叫谢伊·班农( Shay Banon),他成亲不久来到伦敦,因为当时他的夫人正好在伦敦学厨师。
初来乍到,也没有找到工作,于是班农就打算写一个叫作 iCook 的小程序来管理和搜索菜谱,一来练练手,方便找工作;二来这个小工具还可以给其夫人用。
班农在编写 iCook 的过程中,使用了 Lucene,感受到了直接使用 Lucene 开发程序的各种暴击和痛苦。
于是他在 Lucene 之上,封装了一个叫作 Compass 的程序框架,与 Hibernate 和 JPA 等 ORM 框架进行集成,通过操作对象的方式来自动地调用 Lucene 以构建索引。
这样做的好处是,可以很方便地实现对‘领域对象’进行索引的创建,并实现‘字段级别’的检索,以及实现‘全文搜索’功能。
可以说,Compass 大大简化了给 Java 程序添加搜索功能的开发。Compass 开源出来,变得很流行。
在 Compass 编写到 2.x 版本的时候,社区里面出现了更多需求,比如需要有处理更多数据的能力以及分布式的设计。
班农发现只有重写 Compass ,才能更好地实现这些分布式搜索的需求,于是 Compass 3.0 就没有了,取而代之的是一个全新的项目,也就是 Elasticsearch。”
让人砰然心动的 Elasticsearch
看到刘备三人听的入迷,诸葛亮轻挥羽扇,继续说了下去。
“得益于 Compass 项目的积累,Elasticsearch 问世之初就考虑到了功能的易用性。
Elasticsearch 作为一个独立的搜索服务器,提供了非常方便的搜索功能。用户完全不用关心底层 Lucene 的细节,只需要通过标准的 HTTP+RESTful 风格的 API,就可以进行索引数据的增删改查。数据的输入输出采用 JSON 格式,以文档和面向对象的方式,这样就能非常方便地理解和表达领域数据。”
张飞一拍桌子,“Elasticsearch 简直就是一个 Compass 的 RESTful 实现啊!”
“没错。同时,Elasticsearch 基于分片和副本的方式实现了一个分布式的 Lucene Directory,再结合 Map-reduce 的理念,实现了一个简单的搜索请求分发合并的策略,能轻松化解海量索引和分布式高可用的问题。
可以说,仅仅依靠这两点,Elasticsearch 就已经秒杀了当时市面上所有的搜索引擎服务或是程序库,我当时看到 Elasticsearch 也眼前一亮。
如今,Elasticsearch 基本上已经是搜索引擎市场排名第一的产品了,从 DB-Engines 网站的排名可以看到,Elasitcsearch 基本上是一骑绝红尘,拉开第二名远远一大截。”
统计数据来源:https://db-engines.com/en/ranking/search+engine
ELK 横空出世
诸葛亮口水狂飙,显得很兴奋,“如果只是 Elasticsearch 单独使用,那我们的故事也就结束了,事实上好戏这才刚刚开始。俗话说,一个好汉三个帮,开源社区亦是如此。”
“这一个好汉三个帮,说的不就是咱仨嘛。” 刘备接过话茬。
“别打岔,”诸葛亮继续说,“这里我要说的是 ‘ELK’ 的出现,不过首先我要给你们讲讲 Logstash。”
“Logstash 是一个开源的日志处理工具,用 JRuby 写的,主要特点是基于灵活的 Pipeline 管道架构来处理数据。
什么意思呢?可以理解为将数据放进一个管道内进行处理,并且就跟真正的自来水管一样,管道由一截一截管子组成,每一个小管代表着一个数据处理的流程,每一个流程只做一件事情,然后可以根据数据的处理需要,选择多个不同类型的管子灵活组装。
Logstash 社区非常活跃,支持多种输入数据源和多种输出数据源。一开始, Elasticsearch 只是作为其中一个输出的存储,主要用于日志数据的存储。
不过,随着大家把日志发送到 Elasticsearch 之后,大家发现这家伙用起来很方便嘛,不仅能够存储大量的数据,水平伸缩还很方便。更关键的是,你能够很方便地把数据找出来,也就是进行全文搜索。
全文搜索在日志分析里面是非常基础的一个功能,通过一个关键字就能定位具体的详细日志,相比存放到关系型数据库和普通的文件存储,Elasticsearch 优势非常明显。于是 Logstash 搭配 Elasticsearch 变得很受欢迎。
Kibana 的故事
不过 Logstash 自带的 UI 查询日志的界面有点简陋,于是有一个叫作 Rashid Khan 的运维工程师表示完全忍不了了,用 PHP 写了一个叫作 Kibana 的程序,一个更好看和更好用的前端界面。
PHP 写完一版,他又用 Ruby 写一版,后面又用 AngularJS 写了一版,不仅有日志的搜索和查看,还加上了一些统计展示功能。
Kibana 的名字其实是俩个水果的名字的组合(Kiwi+Banana)。
张飞听到这里:“工作不饱和啊这家伙”。孔明瞪了他一眼,继续说道。
“这个时候,Elasticsearch 已经有 Facet 概念,也就是分面统计( 注:1.0 之后推出了 Aggregation 来代替 Facet),可以对数据里面的某个字段进行单个维度的统计,支持多种统计类型。
比如,Term Facet 可以计算字段里面某些值出现了多少次;Histogram Facet 还可以按时间区间进行汇总统计等。
这些统计功能在前端 UI 就可以被利用起来,展示一些饼图、时间曲线等等,在运维的分析里面自然也都是需要的。
慢慢的 Kibana 越做越复杂,支持的功能越来越多,Kibana 3 变得流行起来。
于是乎,ELK 横空出世(Elasticsearch、Logstash 和 Kibana 这三个产品的首字母缩写),风靡了整个运维界。
故事讲到这里,相信你们对于 Elasticsearch 就有了一个大概的认识,可以用它做搜索,也可以用它做日志。”
张飞点点头,“还是相当的强悍嘛。”
Elastic Stack 平台的魅力
“不过,这还没完。”诸葛亮吞了吞口水,继续说。
“Elastic 后面又引入了 Beats 家族。这是一系列非常轻量级的数据收集端,我给你介绍几个比较典型的,比如:
- Packetbeat 可以实时监听网卡流量,并实时解析网络协议数据,可用来做 NPM 网络数据分析。
- Metricbeat 可以用来收集服务器,以及服务器上部署的应用服务的各项监控指标数据,这样就可以替代 Zabbix 等传统的监控软件,来做服务器的性能指标分析。
- Auditbeat 可以实时收集服务器的行为事件,用于安全方面的入侵检测和安全日志审计分析。
- Winlogbeat 用于 Windows 平台的事件日志收集。
- Filebeat 用于日志文件的收集等。
Elasticsearch、Logstash、Kibana、Beats ,这几个放在一起,就叫作 Elastic Stack。
如今,Elastic 的版图越来越大,前年,Elastic 收购 Opbeat,开源了业界第一个完整的 APM 解决方案,通过探针可以实现无侵入的代码级别的应用性能监控。
去年 7 月又收购了代码搜索 Insight.IO,后续可以实现代码级别的语义检索。今年又收购了一个做终端安全的厂商 Endgame。
这样 Elastic Stack 这一个平台就可以同时做到:
- 日志分析
- 性能指标分析
- 安全日志分析
- APM 应用性能分析
- NPM 网络性能分析
- 网站站内搜索
- 企业级搜索
- 代码搜索
- 实时 BI 业务分析
- SIEM 解决方案
- 终端设备安全
- ......
试想一下:在一个风和日丽的下午,你手机上收到一条告警短信,于是点击链接,打开 Kibana 的监控仪表盘,发现某台服务器的 CPU 达到 100% 了。
于是,你顺手点击过滤这台服务器的所有相关信息,可以看到相关的日志显示,是这台服务器上面部署的某一个业务服务的 QPS 有显著下降,然后过滤到这个业务的日志,发现有很多异常的日志信息,前端 Nginx 代理日志还显示有很多请求被拒绝,看样子是后端的微服务处理能力达到瓶颈。
这个时候,继续点击 APM 的分析面板,切换到事务和会话分析界面,看到有很多数据库链接处于开启状态。
你点击查看调用代码,立马就找到了性能瓶颈的原因,原来是某个类的某个方法调用 MySQL 却没有及时释放链接造成了泄露,于是修改这行代码,提交上线,问题解决。然后,你可以若无其事地继续浏览相亲网站啦。
尽管这是一个假想的例子,但是可以看到,基于 Elastic Stack ,你可以覆盖一整套完整的,从全局性能监控到具体代码级别的排障和解决问题的过程,并且使用起来要比很多现有的方案更加高效和便捷。
好了,现在你们是否对 Elasticsearch 已经有了一个初步的了解呢?是不是也有跃跃欲试的打算?”
刘备点点头:“今天来先生这里真的是收获不少,之前多有冒犯,还请多多包涵啊。”
关羽也说:“大哥,明天我就和三弟开始研究 Elasticsearch,争取早日改造好咱们的网站。”
“刚说的相亲网站要不也发我一下”,张飞连忙问道。刘备没好气白了一眼张飞。
“天色已晚,告辞了!”
刘备三人作别孔明,各自高兴的回家了。
“慢走不送,有空来喝茶啊。”
孔明抹了一把额头,总算送走这仨了,恐怕从此江湖上估计要不平静喽。
Elasticsearch 的基本概念
张飞带着笔记本来到会议室(今天的位置是关羽家),因为关羽今天要给大家讲讲 Elasticsearch 的调研成果。
关羽部门的其他成员也都来了,其实也就关平和周仓(隔壁村硬拽的)两个人。
没办法,创业初期,徐州草鞋网一共就这么几条枪,这不刘总经理今天去城门口摆摊搞线下直销业务去了,因为线上网站不是还在开发中嘛。
关羽把投影仪摆弄好,就开场了:“兄弟们,大哥、翼德和我前些日子见过茅庐的诸葛先生,诸葛先生给我们介绍了非常不错的工具,叫做 Elasticsearch(简称:ES),可以用来改进我们的网站搜索,非常有前途,今天我给大家介绍一下。”
张飞点点头:“二哥,你能不能给我们讲讲 Elasticsearch 和咱们用的的数据库有什么区别啊?”
“三弟,你不按套路出牌啊,我还没开始讲,你就问问题,我这不都准备了 PPT 么?”
“二哥,别整这些花里胡哨的,大哥今天又不在,我昨晚和兄弟们喝酒喝大了,头痛的要命,简单点,能不能简单点。”
“丫给老子出去。”关羽气的脸红脖子粗,张飞一听就老实了,“是是是,我不说话行了吧。”
ES 与数据库比较
“要说 Elasticsearch 和咱们现有数据库的区别,先从我们的数据库说起吧。”
“我们的数据库主要用来存储草鞋网的业务数据,如订单、商品介绍、会员等信息,数据库是由表组成的结构,一张表里面存放若干条记录,一张表有若干个列,每列就是一个字段。
他们之间有各种关系,所以传统的这类数据库也叫关系型数据库, 因为我们可以进行多张表的联合查询。关平你上次写的几百行的 SQL 还记得吗,很溜啊,你这是在用 SQL 写散文啊。”
“就是速度稍微有点慢,呵呵。”关平挠了挠头,不好意思地说。
“呵,好笑,那是相当慢好吗。咱们先来看看这个 Elasticsearch 是干嘛的。它是一个专门的搜索引擎,大家平常用的曹阿蛮公司家的汉搜,就是搜索引擎的技术,底层技术原理都是一样的。
大家用的数据库里面不是可以对字段创建索引嘛,这样查起来才快,而 Elasticsearch 则是专门存索引的,索引就是为了优化查询而生的,有了索引,查询起来自然就快啦。
在 Elasticsearch 中也有和库表类似的概念,不过叫作索引(Index),索引里面的每一条记录叫做一个文档,每个文档里面有多个字段,和数据库相比,Elasticsearch 不支持索引间的任意关联查询(Join),也不支持数据库的事务操作,无法满足对数据有强一致性要求的场景。”
周仓举手道:“少爷,看样子,Elasticsearch 和数据库不是一个东西哈,但是这些事务一致性可都是基本要求啊,Elasticsearch 居然不支持。”
“没错,咱们引入 Elasticsearch 本来就不是要替换掉咱们目前的数据库,我们只需要借助它提升我们的搜索查询性能就可以了。Elasticsearch 是一个Java 程序,运行在 JVM 虚拟机之上,可以说是跨平台的。”
RESTful+HTTP+JSON
“Java 的啊,咱们没人会 Java 啊!”张飞又叫起来,“又要学一门新语言啊,坑人不?”
“急什么啊。”关羽继续说,“虽然 Elasticsearch 是 Java 写的,但是它对外提供的是 RESTful API,所以,也就是我们都熟悉的 HTTP 协议,通过使用标准的 HTTP 接口来访问 Elasticsearch,不用 Java 语言也能用的。可以说是跨语言的。”
“妈呀,吓俺一跳,我们前端界的新东西我都忙不过来了,什么 React、Angular、Vue 已经把我累得够呛,可别再让我学什么 Java 了。”张飞这下总算是松了一口气。
“另外,Elasticsearch 各种语言的 SDK 也有提供,根本不用担心语言调用的问题,就算是自己封装一个 API 调用,也就是拼接出一个 HTTP 请求就可以了。
Elasticsearch 的输入输出都是 JSON 数据结构,这是一种 JavaScript 里面常用的数据结构,翼德应该非常熟悉了。”
“JSON 当然熟练了,今天晚上谁请我喝酒,我就教他” 张飞一脸得意。
“额,地球人都知道,还要你教,让我给你们看看一个在 Elasticsearch 里面创建索引的例子啊。”
只见关羽快速的切换了一张早已准备好的幻灯片:
- POST index/doc/1
- {
- "name":"关羽",
- "age":32,
- "address":"徐州大道201号",
- "date":"2018-11-11"
- }
张飞一看兴奋了:“恩,JSON 这个好,简洁易懂,也支持复杂的结构表达,一个对象包含若干属性,属性又可以是另外一个 JSON 对象,用来描述业务对象真的是非常方便。这个例子的双十一也比较符合二哥的身份。”
分布式、可伸缩
“找抽是吧,你还不是一样”,讲完了 ES 和数据库的区别,打消了语言调用的疑虑,关羽接着说了下去。
“咱们业务刚起步,没有多少数据量,可是咱大哥的目标是把咱徐州草鞋做到全国。
你想想咱们全国有多少双脚,要是每个人脚上都是穿咱的草鞋,那业务量有多大啊,那订单,那客户资料还不海了去啊,所以咱们要考虑后续的扩容升级的问题。这时从门口进来一位打扫卫生的大娘,“来来来,抬脚,让一让”。
被突如其来的干扰影响,关羽脸色有点不悦,无奈,打扫卫生的大娘就是他老娘。
“Elasticsearch 支持集群部署,Elasticsearch 的每一个进程叫做一个节点(Node),如果再启动另外一个节点,它们相互之间能够自动组成一个集群。”
“牛群倒是听说过,什么鸡群鸭群的。”大娘一脸疑惑。“小关,今天叫兄弟们在家里吃了晚饭再走啊”。
“这位大娘,你扫完就撤好吧,真是的,啥也不懂。",“兔崽子,回头收拾你”。
关羽继续给大家讲道"集群啊,就是让服务器在一起协作完成一件任务,也就是说,它们可以共享服务器资源,相互之间进行通信。
在 Elasticsearch 的集群里,咱们通过访问任意节点的 RESTful API 端口,就可以访问到整个集群里面的所有索引信息,而不用去关心数据的具体分布,另外数据也有副本,能够自动分布和进行故障处理,就算其中一个机器节点挂了,另外的节点也还能继续对外提供服务,同时也能保证数据也是完整的不受故障影响,不丢数据,你们说是不是很神奇啊?”
“嗯,高级、高级!”几个人异口同声。
“Elasticsearch 里面的索引是以分片的方式来组织的,一个索引底层会有多个分片,以分片为单位分布在集群中。
这样的分布方式,跟数据库的 Sharding 有一拼,同样的原理,目的是避免单个索引太大,拆分成若干分片就可以解决单个大索引的问题。
未来如果我们要支持搜索业务的增长,我们只需要增加 Elasticsearch 的节点,就能够给集群添加资源,Elasticsearch 还会自动迁移旧机器的部分数据到新节点上,从而充分利用硬件资源,扩充处理能力。我听说西域有人部署过成百上千个节点的规模呢,这么大规模,好家伙。”
QueryDSL、查询与聚合分析
“二哥,你快说说,Elasticsearch 到底怎么用,刚刚听你说了这么多,感觉牛逼轰轰的,像我一搞前端打杂的,能不能很快也用起来?”张飞有点着急地说。
“三弟,你是前端大将军,不是前端打杂好嘛,Elasticsearch 对外提供的是 RESTful API,你用它的时候,不用关心底层的诸多细节。
你要创建索引,你就往里面 POST 一条 JSON 数据,你要查询,你就写一个查询的 GET 请求就行了。
在 Elasticsearch 里面,有一个专门的查询表达式叫做 QueryDSL,也是用 JSON 描述的,支持很多的查询类型。
此外,我们还能对数据进行统计分析,比如可以对咱们网站的访问者统计分析他们的访问时段、所在州郡、以及点击过哪些页面,这些在 Elasticsearch 通过一个叫作“聚合”的功能就能实现。
不管是查询还是聚合,Elasticsearch 给你返回的结果也是 JSON 格式的文档,拿到返回结果之后,咱们就可以在前端进行展示了。这块儿主要是三弟你的工作了。”
“如此甚好,这个小 Case ,交给俺了,前端对于俺那还不是分分钟的事情。”张飞拍着胸脯说。
插件与扩展
“Elasticsearch 功能还比较多,周仓、关平,你们俩要好好研究一下,我们的一些需求不一定都能满足,不过 Elasticsearch 有非常好的插件机制,它自己就提供了很多功能,就是以插件形式放出来的。
从前面的 API 查询到底层的网络通信都可以通过写插件来进行扩展,有些需求 Elasticsearch 没有提供的,我们也可以通过自己写插件来实现,不过插件需要用 Java 来编写。另外就是 Elasticsearch 的部署安装你们俩研究一下。”
“遵命,关将军!”周仓和关平一起点头。
“二哥,我好像有点饿了,你们家有啥吃的不。”
“拳头吃不吃?”
“来俩呗。”
“哎呀,不敢了。”......
刘备在城门口卖完今天的第五双草鞋,抬头看到徐州今天上空的月亮感觉特别圆,心想明天肯定又是晴朗的一天。