1、ElasticSearch 学习资料内部文件:1.0颁布时间:2014.1.21公司 Logo 内部文件:输入文件名和版本号第 1 页 共 60 页目 录 文件版本说明 .3 参考资料 .3 手册目的 .3 声明 .3 名词定义和缩略语说明 .31. 总述 .41.1. 简介 .41.2. 国外的使用案例 .41.3. 基本概念解析 .61.3.1. Cluster.61.3.2. Shards.61.3.3. Replicas.61.3.4. Recovery .71.3.5. River.71.3.6. Gateway .71.3.7. discovery.zen .71.3.8. Tra
2、nsport.72. 服务器搭建 .82.1. 单机环境 .82.2. 服务器环境 .82.3. 中文分词集成 .92.4. 配置详解 .123. Java API.153.1. 与集群交互 .153.1.1. Node 方式 .153.1.2. TransportClient 方式 .163.2. put Mapping 定义索引字段属性 .163.3. 索引数据 .19公司 Logo 内部文件:输入文件名和版本号第 2 页 共 60 页3.4. 删除索引数据 .193.5. 搜索 .203.6. 批量添加索引 .213.7. 与 MongoDB 同步数据 .223.8. 使用 More l
3、ike this 实现基于内容的推荐 .25公司 Logo 内部文件:输入文件名和版本号第 3 页 共 60 页 文 件 版 本 说 明表 1 版本说明版本 发布时间 修订章节 作者1.0 2014.1.21 第一版 虞晶 参 考 资 料1. Elasticsearch 官网:http:/ 手 册 目 的ElasticSearch 学习资料 声 明无 名 词 定 义 和 缩 略 语 说 明表 2 名词定义及缩略语说明序号 缩写 说明1 ES Elasticsearch,一种设计用于云计算的分布式全文索引解决方案。公司 Logo 内部文件:输入文件名和版本号第 4 页 共 60 页1. 总述1.
4、1.简介ElasticSearch 是一个基于 Lucene 构建的开源,分布式,RESTful 搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。支持通过 HTTP 使用JSON 进行数据索引。我们建立一个网站或应用程序,并要添加搜索功能,令我们受打击的是:搜索工作是很难的。我们希望我们的搜索解决方案要快,我们希望有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用 JSON 通过 HTTP 的索引数据,我们希望我们的搜索服务器始终可用,我们希望能够一台开始并扩展到数百,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。Elasticsea
5、rch 旨在解决所有这些问题和更多的。1.2.国外的使用案例Github“Github 使用 Elasticsearch 搜索 20TB 的数据,包括 13 亿的文件和 1300 亿行的代码”这个不用介绍了吧,码农们都懂的,Github 在 2013 年 1 月升级了他们的代码搜索,由solr 转为 elasticsearch,目前集群规模为 26 个索引存储节点和 8 个客户端节点(负责处理搜索请求) ,详情请看官方博客 https:/ 5 千万地点信息?Foursquare 每天都用 Elasticsearch 做这样的事“Foursquare 是一家基于用户地理位置信息的手机服务网站,并
6、鼓励手机用户同他人分享自己当前所在地理位置等信息。与其他老式网站不同,Foursquare 用户界面主要针对手机而设计,以方便手机用户使用。SoundCloud“SoundCloud 使用 Elasticsearch 来为 1.8 亿用户提供即时精准的音乐搜索服务”SoundCloud 是一家德国网站,提供音乐分享社区服务,成长很快,Alexa 世界排名已达第 236 位。你可以在线录制或上传任何声音到 SoundCloud 与大家分享,可在线上传也可公司 Logo 内部文件:输入文件名和版本号第 5 页 共 60 页以通过软件客户端来上传音乐文件,没有文件大小限制,但免费版限制上传音频总长不
7、可超过 2 个小时播放时长,每首歌曲限最多 100 次下载。SoundCloud 允许音乐通过 Flash 播放器方式嵌入到网页中。Fog Creek“Elasticsearch 使 Fog Creek 可以在 400 亿行代码中进行一个月 3 千万次的查询“StumbleUpon”Elasticsearch 是 StumbleUpon 的关键部件,它每天为社区提供百万次的推荐服务“StumbleUpon 是个能发现你喜欢的网页的网站,进去时先注册,注册完就选择你感兴趣的东西,它会自动帮你推荐一些网页,如果你喜欢这个网页就点喜欢按钮,按 stumble按钮就会推荐下一个网页。目前其数据量达到
8、25 亿,基本数据存储在 HBase 中,并用 elasticsearch 建立索引,elasticsearch 在其中除了用在搜索功能还有在推荐和统计功能。之前他们是使用 solr 作为搜索,由于 solr 满足不了他们的业务增长需要而替换为 elasticsearch。MozillaMozilla 公司以火狐著名,它目前使用 WarOnOrange 这个项目来进行单元或功能测试,测试的结果以 json 的方式索引到 elasticsearch 中,开发人员可以非常方便的查找 bug。Socorro 是 Mozilla 公司的程序崩溃报告系统,一有错误信息就插入到 Hbase 和Postgr
9、es 中,然后从 Hbase 中读取数据索引到 elasticsearch 中,方便查找。SonySony 公司使用 elasticsearch 作为信息搜索引擎Infochimps“在 Infochimps,我们已经索引了 25 亿文档,总共占用 4TB 的空间” 。Infochimps 是一家位于德克萨斯州奥斯丁的创业公司,为大数据平台提供商。它主要提供基于 hadoop 的大数据处理方案。公司 Logo 内部文件:输入文件名和版本号第 6 页 共 60 页1.3.Scaling Lucene怎样在 Lucene 之上构建一个分布式、高度伸缩、接近实时的搜索引擎呢?让我们回顾一下在搜索引擎
10、(基于 lucene)伸缩性这条路上都做了那些尝试,并且elasticsearch 是如何尝试并去解决这些挑战的。首先我们了解下最基础的理论知识 building blocks (这些理论基础是构建分布式近实时搜索引擎的基础) 。 接着我们研究一下到底哪种才是最佳的分区策略 partitioning (将lucene 索引文档分割到多个分布式的分片中去) 。 然后我们同样需要决定使用哪种分区复制方式 replication (复制能够保证系统的高可用以及提高搜索的吞吐) 。 最后,我们再看一下事务日志 transaction log (事务日志在 elasticsearch 里面是一个保证数据
11、一致性的非常酷的功能) 。1.3.1. Building Blocks当我们要构建一个分布式接近实时的搜索引擎,并且要让 lucene 可伸缩可扩展,必须首先知道 lucene 的关键概念以及它们与我们要达成目标的一些局限性. DirectoryLucene Directory 是一个抽象的文件系统的接口,用来允许你读写文件,不管 lucene的索引是存放在内存中还是在物理磁盘上,它都是通过 lucene 的 Directory 抽象层来访问和公司 Logo 内部文件:输入文件名和版本号第 7 页 共 60 页维护的。 IndexWriterIndexWriter 用来添加、删除和更新 luc
12、ene 里面的索引文档。这些操作是在内存中完成以保证更好的性能,但是如果要保证这些操作的持久化,这些操作是需要 flush 到磁盘的。并且,flush 操作或者是显式的 commit 提交开销都是比较大的,因为这些操作通常需要处理很多的文件,而处理这些文件又涉及到大量的磁盘 io。此外, 每次只能有一个 IndexWriter 对象来对一个索引目录进行索引操作,并且创建这个对象的开销很大,所以必须尽可能去重用这个对象. Index SegmentsLucene 索引被分解为很多段(segments) 。每个索引段实际上是一个功能完整的 lucene索引,一旦一个索引段创建完成,它将是不可变的,
13、并且不能删除段里面的索引文档。commit 提交操作用来往索引里面添加一个新段。lucene 内部会来对这些段进行合并,所以我们必须要有策略来控制这些合并(MergePolisy, MergeScheuler, etc)。Because segments need to be kept at bay they are being merged continuously by internal Lucene processes (MergePolisy, MergeScheuler, etc)。因为段是不可变的,所以用来做缓存(caching)是一个很好的选择,你可以加载所有的 term 词条并
14、且创建一个跳跃列表( skip lists ) ,或者用来构造 FieldCache,如果段没有变化,你就不需要重新加载。 IndexReaderIndexReader 用来执行搜索索引。这个对象通过 IndexWriter 来提供,并且创建代价也是比较高。一旦 IndexReader 打开之后,它就不能够发现打开之后的索引变化,如果要知道这些由 IndexWriter 产生的索引变化,除非刷新 IndexReader 对象(当然前提需要 flush 操作) 。搜索操作在内部其实是按段来进行的(每次一个段). Near Real-Time Search获取一个新的 IndexReader 开销
15、很大,所以也是我们不能每次一有索引操作就真的去获取一个新的 IndexReader,你可以隔一段时间去刷新一下,比如每隔一秒钟等等,这也是我们在这里称之为接近实时( near real-time )的原因.公司 Logo 内部文件:输入文件名和版本号第 8 页 共 60 页1.3.2. Partitioning可能用来伸缩 Lucene 的途径( Possible approach to Scale Lucene): Distributed Directory其中一个途径用来伸缩 Lucene 就是使用分布式文件系统,大文件会被拆分成 chunks块并且会保存到分布式存储系统(比如 Coher
16、ence, Terracota, GigaSpaces or Infinispan 等等)。这样 IndexWriter 和 IndexReader 都是工作在一个自定义的 Directory 分布式实现上,每个操作后面其实是分布了很多个节点,每个节点上面存储了索引文件的一部分.但是这种方案有一些问题:首先,这种方案会产生密集的网络流量。尽管可以用一些高级的方法如本地缓存等,但仍然会产生大量的网络请求,因为最主要的原因是因为这种将文件拆分为块的想法与lucene 索引文件构建方式和使用方式实在相隔太远,结论就是使用这种方式来做大规模索引和搜索是不切实际的。 (ps:所以 solandra 这种
17、玩意还是不要去考虑了) 。其次,大的索引必然会使 IndexReader 变的无法分布式。IndexReader 是一个很重的对象,并且 term 词条越多,其消耗的内存也会越多。最后,索引操作也会变的非常困难,因为只有一个单一的 IndexWriter 能够写索引。所以,我们把目光投向另一种方式。 Partitioning有 2 种通过将数据分区方式来 scale 搜索引擎: 基于文档( Document based partitioning) and 基于词条(Term based partitioning ). Elasticsearch 使用的基于文档的分区方式。基于文档的分区(Doc
18、ument Based Partitioning)每一个文档只存一个分区,每个分区持有整个文档集的一个子集,分区是一个功能完整的索引。优点:每个分区都可以独立的处理查询。可以非常简单的添加以文档为单位的索引信息。网络开销很小,每个节点可以分别执行搜索,执行完了之后只需用返回文档的 ID 和评分信息就可以了,然后在其中一个我们执行分布式搜索的节点上执行合并就可以了。公司 Logo 内部文件:输入文件名和版本号第 9 页 共 60 页缺点:查询如果需要在所有的分区上执行,那么它将执行 O(K*N) 次磁盘操作(K 是词条(Term ,或者理解为 Field)的数量, N 是分区的数量) 。在实用性
19、的角度来看基于文档的分区方式已经被证明是一个构建大型的分布式信息检索系统的一种行之有效的方法, 关于这方面的详细内容,可以看 这里 talk by Jeffrey Dean (Google)。基于词条的分区(Term Based Partitioning)每个分区拥有一部分词条,词条里面包含了整个 index 的文档数据。一些基于词条分区的系统,如 Riak Search (built on top of Riak key-value store engine) 或是 Lucandra/Solandra (on top of Cassandra). 尽管这些系统不是完全一样,但是它们都面临一个
20、相似的挑战,当然也得益于相同的设计理念。优点:一般来说,你只需要在很少的部分分区上执行查询就行了,比如,我们有 5 个 term 词条的查询,我们将至多命中 5 个分区,如果这 5 个 term 词条都保存同一个分区中,那么我们只需用访问一个分区即可,而不管我们是不是实际上有 50 个分区。另外一个优势就是对应 K 个 Term 词条的查询,你只需用执行 O(K) 次磁盘查找(假设我们使用的优化过的实现) 。缺点:最主要的问题是 Lucene Segment 概念里面固有的很多结构都将失去。The main problem is that whole notion of Lucene Segm
21、ent which is inherent to a lot of constructs in Lucene is lost.对于那些复杂的查询,网络开销将会变得非常高,并且可能使得系统可用性大大降低,尤其是那些会 expand 出大量的 term 词条的查询,如 fuzzy 或者 prefix 查询。另外一个问题就是获取每个文档的信息将会变得非常困难,举例来说,如果你想获取文档的一部分数据来做进一步的控制,比如(google 的 PageRank 算法) ,获取每个文档的这些数据都会变得非常困难,因为这种分区的方式使得文档的数据被分散到了不同的地方,所以实现 faceting、评分、自定义评分等等都将变得难以实现。