【翻译】用 elasticsearch 和 elasticsearch 为数十亿次客户搜索提供服务

标签: 系统运维 | 发表时间:2013-10-15 21:50 | 作者:三斗室
出处:http://www.blogread.cn/it/

标签:   elasticsearch   elasticsearch   搜索

   原文地址: http://www.elasticsearch.org/blog/using-elasticsearch-and-logstash-to-serve-billions-of-searchable-events-for-customers/


   今天非常高兴的欢迎我们的第一个外来博主,Rackspace软件开发工程师,目前为Mailgun工作的 Ralph Meijer。我们在 Monitorama EU 会面后,Ralph 提出可以给我们写一篇 Mailgun 里如何使用 Elasticsearch 的文章。他本人也早就活跃在 Elasticsearch 社区,经常参加我们在荷兰的聚会了。

   

    Mailgun 收发大量电子邮件,我们跟踪和存储每封邮件发生的每个事件。每个月会新增数十亿事件,我们都要展示给我们的客户,方便他们很容易的分析数据,也就是全文搜索。下文是我们利用Elasticsearch和Logstash技术完成这个需求的技术细节(很高兴刚写完这篇文章就听说《 Logstash加入Elasticsearch》了)。

事件

   在 Mailgun 里,event可能是如下几种:进来一条信息,可能被接收可能被拒绝;出去一条信息,可能被投递可能被拒绝(垃圾信息或者反弹);信息是直接打开还是通过链接点击打开;收件人要求退订。所有这些事件,都有一些元信息可以帮助我们客户找出他们的信息什么时候,为什么,发生了什么。这个元信息包括:信息的发送者,收件人地址,信息id,SMTP错误码,链接URL,geo地理位置等等。

   每个事件都是由一个时间戳和一系列字段构成的。一个典型的事件就是一个关联数组,或者叫字典、哈希表。

事件访问设计

   假设我们已经有了各种事件,现在需要一个办法来给客户使用。在Mailgun的控制面板里,有一个日志标签,可以以时间倒序展示事件日志,并且还可以通过域名和级别来过滤日志,示例如下:

   

   在这个示例里,这个事件的级别是”warn”,因为SMTP错误码说明这是一个临时性问题,我们稍后会重试投递。这里有两个字段,一个时间戳,一个还没格式化的非结构化文本信息。为了醒目,这里我们会根据级别的不同给事件上不同的底色。

   在这个网页之后,我还有一个接收日志的API,一个设置触发报警的hook页面。后面的报警完全是结构化了的带有很多元数据字段的JSON文档。比如,SMTP错误码有自己的字段,收件人地址和邮件标题等也都有。

   不幸的是,原有的日志API非常有限。他只能返回邮件投递时间和控制面板里展示的非结构化的文本内容。没办法获取或者搜索多个字段(像报警页面里那样),更不要说全文搜索了。简单说,就是控制面板缺乏全文搜索。

用elasticsearch存储和响应请求

   要给控制面板提供API和访问,我们需要一个新的后端来弥补前面提到的短板,包括下面几个新需求:

  • 允许大多数属性的过滤。

  • 允许全文搜索。

  • 支持存储至少30天数据,可以有限度的轮滚。

  • 添加节点即可轻松扩展。

  • 节点失效无影响。

  •    而Elasticsearch,是一个可以“准”实时入库、实时请求的搜索引擎。它基于Apache Lucene,由存储索引的节点组成一个分布式高可用的集群。单个节点离线,集群会自动把索引(的分片)均衡到剩余节点上。你可以配置具体每个索引有多少分片,以及这些分片该有多少副本。如果一个主分片离线,就从副本中选一个出来提升为主分片。

       Elasticsearch 是面向文档的,某种层度上可以说也是无模式的。这意味着你可以传递任意JSON文档然后就可以索引成字段。对我们的事件来说完全符合要求。

       Elasticsearch 同样还有一个非常强大的请求/过滤接口,可以对特定字段搜索,也可以做全文搜索。

    事件存入elasticsearch

       有很多工具或者服务可以用来记录事件。我们最终选择了 Logstash,一个搜集、分析、管理和传输日志的工具。

       在内部,通过webhooks推送来的event同时在我们系统的其他部分也有使用,目前我们是用Redis来完成这个功能。Logstash有一个Redis输入插件来从Redis列表里接收日志事件。通过几个小过滤器后,事件通过一个输出插件输出。最常用的输出插件就是 Elasticsearch 插件。

       利用 Elasticsearch 丰富的 API 最好的办法就是使用 Kibana,这个工具的口号是“让海量日志有意义”。目前最新的 Kibana 3 是一个纯粹的 JavaScript 客户端版,随后也会成为 Logstash 的默认界面。和之前的版本不同的是,它不在依赖于一个类Logstash模式,而是可以用于任意Elasticsearch索引。

       

    认证

       到这步,我们已经解决了事件集中的问题,也有了丰富的API来深入解析日志。但是我们不想把所有日志都公开给每个人,所以我们需要一个认证,目前Elasticsearch 和 Kibana 都没提供认证功能,所以寄希望于 Elasticsearch API 是不可能的了。

       我们选择了构建双层代理。一层代理用来做认证和流量限速,一层用来转义我们的事件 API 成 Elasticsearch 请求。前面这层代理我们已经以 Apache 2.0 开原协议发布在Github上,叫 vulcan 。我们还把我们原来的那套日志 API 也转移到了 Elasticsearch 系统上。

    索引设计

       有很多种方法来确定你如何组织自己的索引,基于文档的数目(每个时间段内),以及查询模式。

       Logstash 默认每天创建一个新索引,包括当天收到的全部时间。你可以通过配置修改这个时间,或者采用其他属性来区分索引,比如每个用户一个,或者用事件类型等等。

       我们这里每秒有1500个时间,而且我们希望每个账户的轮转时间段都是可配置的。可选项有:

  • 一个大索引。

  • 每天一个索引。

  • 每个用户账户一个索引。

  •    当然,如果需要的话,这些都可以在未来进一步切分,比如根据事件类型。

       管理轮滚的一个办法是在 Elasticsearch 中给每个文档设定 TTLs 。到了时间  Elasticsearch 就会批量删除过期文档。这种做法使得定制每个账户的轮转时间变得很简单,但是也带来了更多的 IO 操作。

       另一个轻量级的办法是直接删除整个索引。这也是 Logstash 默认以天创建索引的原因。过了这天你直接通过 crontab 任务删除索引即可。

       不过后面这个办法就没法定制轮转了。我们有很多用户账户,给每个用户每天保持一个索引是不切实际的。当然,给所有用户每天存一个索引又意味着我们要把所有数据都存磁盘上。如果一个账户是保持两天数据的轮转,那么在缓存中的数据就是有限的。在查询多天的垃圾邮件时,处理性能也就受限了。所以,我们需要保留更多的日志以供Kibana访问。

    映射

       为了定义文档(中的字段)如何压缩、索引和存储在索引里,Elasticsearch 有一个叫做 mapping 的概念。所以为每个字段它都定义了类型,定义了如何分析和标记字段的值以便索引和查询,定义了值是否需要存储,以及其他各种设置。默认的情况,mapping是动态的,也就是说 Elasticsearch 会从它获得的第一个值来尝试猜测字段的类型,然后正式应用这个设置到索引。

       如果你的数据来源单一,这样就很好了。但实际可能来源很复杂,或者日志类型根本就不一样,比如我们这,同一个名字的字段的数据类型可能都不一样。 Elasticsearch 会拒绝索引一个类型不匹配的文档,所以我们需要自定义 mapping 。

       通过我们的 Events API ,我给日志事件的类型定义了一个映射。不是所有的事件都有所有这些字段,不过相同名字的字段肯定是一致的。

    分析器

       默认情况下,字段的 mapping 中就带有 标准分析器。简单的说,就是字符串会被转成小写,然后分割成一个一个单词。然后这些标记化的单词再写入银锁,并指向具体的字段。

       有些情况,你可能想要些别的东西来完成不同的效果。比如说账户 ID,电子邮件地址或者网页链接 URL之类的,默认标记器会以斜线分割,而不考虑把整个域名作为一个单独的标记。当你通过 facet 统计域名字段的时候,你得到的会是域名中一段一段标签的细分结果。

       要解决这个问题,可以设置索引属性,给对应字段设置成 not_analyzed。这样在插入索引的时候,这个字段不再经过映射或者标记器。比如对 domain.name 字段应用这个设置后,每个域名都会完整的作为同一个标签统计 facet 了。

       如果你还想在这个字段内通过部分内容查找,你可以使用 multi-field type。这个类型可以映射相同的值到不同的核心类型或者属性,然后在不同名称下使用。我们对 IP 地址就使用了这个技术。默认的字段(比如叫sending-ip)的类型就是 ip,而另一个非默认字段(比如叫 sending-ip.untouched)则配置成 not_analyzed 而且类型为字符串。这样,默认字段可以做 IP 地址专有的范围查询,而 .untouched 字段则可以做 facet 查询。

       除此以外,绝大多数字段我们都没用分析器和标记器。不过我们正在考虑未来可以结合上面的多字段类型技巧,应用 pattern capture tokenfilter 到某些字段(比如电子邮件地址)上。

    监控

       要知道你的集群怎么样,你就必须要监控它。 Elasticsearch 有非常棒的 API 来获取 cluster statenode statistics。我们可以用 Graphite 来存储这些指标并且做出综合表盘,下面就是其中一个面板:

       

       为了收集这些数据并且传输到 Graphite,我创建了 Vör,已经在 Mochi Media 下用 MIT/X11 协议开源了。另外一个保证 Redis 列表大小的收集器也在开发中。

       除此以外,我们还统计很多东西,比如邮件的收发、点击数,API调用和耗时等等,这些是通过 StatsD 收集的,同样也添加到我们的 Graphite 表盘。

       

       这绝对是好办法来观察发生了什么。Graphite 有一系列函数可以用来在绘图前作处理,也可以直接返回JSON文档。比如,我们可以很容易的创建一个图片展示 API 请求的数量与服务器负载或者索引速度的联系。

    当前状况

       我们的一些数据:

  • 每天大概4kw 到 6kw 个日志事件。

  • 30天轮转一次日志。

  • 30个索引。

  • 每个索引5个分片。

  • 每个分片一个1副本。

  • 每个索引占 2 * 50 到 80 GB空间(因为有副本所以乘2)。

  •    为此,我们启动了一共 9 台 Rackspace 云主机,具体配置是这样的:

  • 6x 30GB RAM, 8 vCPUs, 1TB disk: Elasticsearch 数据节点。

  • 2x 8GB RAM, 4 vCPUs: Elasticsearch 代理节点, Logstash, Graphite 和 StatsD。

  • 2x 4GB RAM, 2 core: Elasticsearch 代理节点, Vulcan 和 API 服务器

  •    大多数主机最终会迁移到专属的平台上,同时保留有扩展新云主机的能力。

       Elasticsearch 数据节点都配置了 16GB 内存给 JVM heap。其余都是标准配置。此外还设置了 fieldcache 最大大小为 heap 的 40%,以保证集群不会在 facet 和 sort 内容很多的字段时挂掉。我们同时也增加了一点 cluster wide settings 来加速数据恢复和重均衡。另外,相对于我们存储的文档数量来说,indices.recovery.max_bytes_per_sec 的默认设置实在太低了。

    总结

       我们非常高兴用 Elasticsearch 来保存我们的事件,也得到了试用新 API 和新控制面板中新日志页面的客户们非常积极的反馈。任意字段的可搜索对日志挖掘绝对是一种显著的改善,而 Elasticsearch 正提供了这种高效无痛的改进。当然,Logstash,Elasticsearch 和 Kibana 这整条工具链也非常适合内部应用日志处理。

       如果你想了解更多详情或者对我们的 API 有什么疑问,尽管留言。也可以在 Mailgun 博客上 阅读更多关于事件 API 的细节

您可能还对下面的文章感兴趣:

  1. 更极致的搜索推荐——“去哪儿酒店”搜索体验【2013年9月版】 [2013-09-05 23:17:25]
  2. 基于Solr的空间搜索(3) [2013-08-15 13:40:09]
  3. 基于Solr的空间搜索(2) [2013-08-15 13:39:11]
  4. 基于Solr的空间搜索(1) [2013-08-15 13:38:28]
  5. 淘宝搜索中Query下拉推荐技术 [2013-08-12 13:35:08]
  6. Learning to rank在淘宝的应用 [2013-08-12 13:32:35]
  7. 从概念的角度审视一淘商品搜索的Online系统架构 [2013-08-08 23:30:13]
  8. 基于用户行为分析的搜索引擎自动性能评价 [2013-05-29 22:35:23]
  9. 垂直搜索新问题 [2012-09-20 13:48:29]
  10. 索引页链接补全机制的一种方法 [2012-08-17 13:20:11]
  11. 让搜索跨越语言的鸿沟——谈跨语言信息检索技术 [2012-06-19 23:56:24]
  12. 怎样用好Google进行搜索 [2012-04-15 16:05:01]
  13. 百度搜索URL参数解析 [2012-02-05 15:33:49]
  14. 百度解构第一季 - 理解用户搜索行为 [2012-01-03 23:35:01]
  15. 搜索背后的奥秘――浅谈语义主题计算 [2011-11-23 23:47:15]
  16. 简析搜索引擎中网络爬虫的搜索策略 [2011-07-30 21:23:53]
  17. 淘宝搜索:定向抓取网页技术漫谈 [2011-07-09 22:45:26]
  18. 附近地点搜索初探 [2011-06-20 13:46:22]
  19. 浅析视频搜索中的清晰度识别过程 [2011-06-01 23:59:26]
  20. 如何预测用户query意图 [2011-01-10 23:19:10]
  21. 从狄仁杰的测字占卜到一淘网的Query分析之大结局 [2011-01-05 22:26:37]
  22. Query Forwarding in Geographically Distributed Search Engines [2010-12-28 20:46:49]
  23. 百度这个公司 [2010-11-22 21:17:57]
  24. 几种常见的基于Lucene的开源搜索解决方案对比 [2010-11-21 19:52:27]
  25. 信息时代的双峰 [2010-10-31 20:16:18]
  26. 挑战邮箱搜索(续一) [2010-09-28 09:20:54]
  27. 挑战邮箱搜索 [2010-09-25 09:42:51]
  28. 用搜索的倒排轻松搞定“好友的文章”类相关推荐功能 [2010-09-06 08:46:04]
  29. 排头兵PHP中文分词,纯PHP版实现 [2010-08-05 09:52:57]
  30. 从细节看知识搜索 [2010-07-21 23:38:41]
  31. 用sphinx轻松搞定方便管理的多节点过亿级数据搜索 [2010-07-14 09:53:06]
  32. 用Sphinx快速搭建站内搜索功能 [2010-06-23 12:59:33]
  33. Xapian搜索体系结构 [2010-06-02 11:48:45]
  34. 搜索引擎停用词 [2010-04-06 13:51:08]
  35. 搜索引擎爬虫蜘蛛的USERAGENT收集 [2010-01-15 14:47:25]
  36. 搜索结果显示:栅格视图还是列表视图? [2009-12-18 15:41:07]
  37. 向搜索引擎举报作弊网站地址 [2009-11-20 21:03:31]
  38. 音乐搜索的极致 [2009-11-16 23:21:51]
  39. 关于音乐搜索 [2009-11-04 13:31:24]
  40. 整合搜索,阿拉丁,云计算,以及框计算 [2009-11-04 09:23:54]
  41. 互联网网站的反爬虫策略浅析 [2009-10-31 00:53:36]

相关 [翻译 elasticsearch elasticsearch] 推荐:

【翻译】用 elasticsearch 和 elasticsearch 为数十亿次客户搜索提供服务

- - IT技术博客大学习
标签:   elasticsearch   elasticsearch   搜索.    原文地址: http://www.elasticsearch.org/blog/using-elasticsearch-and-logstash-to-serve-billions-of-searchable-events-for-customers/.

[译]elasticsearch mapping

- - an74520的专栏
es的mapping设置很关键,mapping设置不到位可能导致索引重建. 请看下面各个类型介绍^_^. 每一个JSON字段可以被映射到一个特定的核心类型. JSON本身已经为我们提供了一些输入,支持 string,  integer/ long,  float/ double,  boolean, and  null..

Elasticsearch as Database - taowen - SegmentFault

- -
【北京上地】滴滴出行基础平台部招聘 Elasticsearch 与 Mysql binlog databus 开发工程师. 内推简历投递给: [email protected]. 推销Elasticsearch. 时间序列数据库的秘密(1)—— 介绍. 时间序列数据库的秘密(2)——索引.

ElasticSearch 2 的节点调优(ElasticSearch性能)

- - 行业应用 - ITeye博客
一个ElasticSearch集群需要多少个节点很难用一种明确的方式回答,但是,我们可以将问题细化成一下几个,以便帮助我们更好的了解,如何去设计ElasticSearch节点的数目:. 打算建立多少索引,支持多少应用. elasticsearch版本: elasticsearch-2.x. 需要回答的问题远不止以上这些,但是第五个问题往往是容易被我们忽视的,因为单个ElasticSearch集群有能力支持多索引,也就能支持多个不同应用的使用.

Elasticsearch:使用 Elasticsearch 进行语义搜索

- - 掘金 后端
在数字时代,搜索引擎在通过浏览互联网上的大量可用信息来检索数据方面发挥着重要作用. 此方法涉及用户在搜索栏中输入特定术语或短语,期望搜索引擎返回与这些确切关键字匹配的结果. 虽然关键字搜索对于简化信息检索非常有价值,但它也有其局限性. 主要缺点之一在于它对词汇匹配的依赖. 关键字搜索将查询中的每个单词视为独立的实体,通常会导致结果可能与用户的意图不完全一致.

elasticsearch的javaAPI之query

- - CSDN博客云计算推荐文章
elasticsearch的javaAPI之query API. the Search API允许执行一个搜索查询,返回一个与查询匹配的结果(hits). 它可以在跨一个或多个index上执行, 或者一个或多个types. 查询可以使用提供的 query Java API 或filter Java API.

Elasticsearch基础教程

- - 开源软件 - ITeye博客
转自:http://blog.csdn.net/cnweike/article/details/33736429.     Elasticsearch有几个核心概念. 从一开始理解这些概念会对整个学习过程有莫大的帮助.     接近实时(NRT).         Elasticsearch是一个接近实时的搜索平台.

ElasticSearch索引优化

- - 行业应用 - ITeye博客
ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用tranlog进行各节点之间的数据平衡. 所以从上我可以通过索引的settings进行第一优化:. 这两个参数第一是到tranlog数据达到多少条进行平衡,默认为5000,而这个过程相对而言是比较浪费时间和资源的. 所以我们可以将这个值调大一些还是设为-1关闭,进而手动进行tranlog平衡.

elasticsearch集群搭建

- - zzm
之前对于CDN的日志处理模型是从 . logstash agent==>>redis==>>logstash index==>>elasticsearch==>>kibana3,对于elasticsearch集群搭建,可以把索引进行分片存储,一个索引可以分成若干个片,分别存储到集群里面,而对于集群里面的负载均衡,副本分配,索引动态均衡(根据节点的增加或者减少)都是elasticsearch自己内部完成的,一有情况就会重新进行分配.

Elasticsearch集群入门

- - 编程语言 - ITeye博客
欢迎来到Elasticsearch的奇妙世界,它是优秀的全文检索和分析引擎. 不管你对Elasticsearch和全文检索有没有经验,都不要紧. 我们希望你可以通过这本书,学习并扩展Elasticsearch的知识. 由于这本书也是为初学者准备的,我们决定先简单介绍一般性的全文检索概念,接着再简要概述Elasticsearch.