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

标签: 系统运维 | 发表时间:2013-10-15 13: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 开发工程师. 内推简历投递给: taowen@didichuxing.com. 推销Elasticsearch. 时间序列数据库的秘密(1)—— 介绍. 时间序列数据库的秘密(2)——索引.

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

- - 行业应用 - ITeye博客
一个ElasticSearch集群需要多少个节点很难用一种明确的方式回答,但是,我们可以将问题细化成一下几个,以便帮助我们更好的了解,如何去设计ElasticSearch节点的数目:. 打算建立多少索引,支持多少应用. elasticsearch版本: elasticsearch-2.x. 需要回答的问题远不止以上这些,但是第五个问题往往是容易被我们忽视的,因为单个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的日志处理模型是从 . 下面先是介绍几个关于elasticsearch的几个名词 . 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的. es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的.

Elasticsearch 学习笔记

- - 研发管理 - ITeye博客
安装  Elasticsearch. 1:解压下载的安装包 elasticsearch-1.7.2.zip. 修改  node.name: es(集群状态名字一致). 2:在https://github.com/elasticsearch/elasticsearch-servicewrapper下载该插件后,解压缩.

Elasticsearch集群入门

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