大数据的蓬勃发展要求搜索引擎能够处理不断增长的数据。当我们实现Cloudera搜索时,一个重要的考量点就在于如何利用ApacheSolr与Apache Hadoop实现真正意义上的大规模数据近实时(NRT)搜索。
最终,我们在Solr与Apache Lucene的基础上实现了Cloudera搜索。尽管Solr与Lucene在不断演变以适应越来越多的数据,然而,在处理极大规模数据的案例中尚未出现一个非常高效的办法。用户往往会听到类似“这个得看具体情况”的答案。一个契合用户案例的架构也取决于很多因素,受到需求、资源等所带来的约束。
我们希望通过Cloudera搜索为用户提供一个简单、通用、适合处理大规模时间序列数据的搜索解决方案。这里的时间序列数据是指类似于日志、微博等随着时间源源不断新增的,带有时间戳的数据。为了实现这一目标,Cloudera实现了“文档集别名(Collection aliasing)”新功能,并将它开源贡献到Solr社区。
文档集别名
文档集别名允许用户创建一个虚拟文档集,并将该虚拟文档集映射到一个或者多个物理文档集。例如,你可以创建一个别名叫作“文章”,而当用户查询时,搜索引擎会在后台实际搜索“杂志”与“博客”。使用别名意味着读操作将被映射到一个或者多个物理文档集,而写操作则只会被映射到一个物理文档集。当前,用户可以在任何使用物理文档集的地方使用别名(虚拟文档集)。
别名的一大好处在于用户可以在客户端应用程序中直接使用别名,如果想要切换不同的物理文档集,只需要修改别名的映射即可,而且这个过程对客户端程序完全透明,换句话说,就是完全不需要对客户端程序进行修改。
当前文档集别名只在SolrCloud模式下有效,并且可以通过HTTPAPI直接进行操作:
创建别名: http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=AliasName&collection=ListOfCollections
删除别名: http://localhost:8983/solr/admin/collections?action=DELETEALIAS&name=AliasName
虚拟文档集
虚拟文档集往往被映射到多个物理文档集(逻辑索引分片)。当你将时间序列数据放入虚拟文档集时,这种方法允许用户对不同时间段生成的物理文档集进行定制化处理,帮助用户有效控制物理文档集的大小以满足近实时搜索功能的需求。

一开始,虚拟文档集中只包含一个物理文档集。用户可以采用任意的规则统一为物理文档集命名。为了说明的方便,这里使用ColN这个模式进行命名。物理文档集可以使用完全相同的配置文件,有助于用户保持文档集的一致性,提高运维的效率。

最新的文档集将接收新增的时间序列数据。用户可以使用Apache Flume+Morphline的方式,或者HBase+Lily的方式,或者其他的任意方式从数据源中实时导入数据。以下的技术讨论并不对数据导入的方法作任何约束。为了实现对时间序列数据的处理,该方案需要至少两个别名用于处理虚拟文档集:“更新别名”与“查询别名”。
更新别名
创建别名 TSCUpdate -> Col1
http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=TSCUpdate&collection=Col1
无论用户使用什么方法来导入数据,用户都需要创建该别名指定新增的时间序列数据应该写入哪个物理文档集。

用户可以使用更新别名在不同的物理文档集之间进行无缝切换。在以上示例中,Col1是唯一的一个物理文档集,而TSCUpdate指向它。当新增数据到达TSCUpdate虚拟文档集时,这些数据会被重定向到Col1。经过一段时间X (用户可以根据实际需要设定)后,用户创建新的物理文档集Col2并将更新别名指向它。现在Col1变成了旧数据的静态索引,而Col2用于接收、处理新增的数据(这个策略的一个假设是认为数据到达后不会作修改)。
注意,为了更新别名,用户可以在一个现存的别名上再次使用CREATEALLIAS
http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=TSCUpdate&collection=Col2

再过一段时间X,Col3将被创建出来,并对TSCUpdate进行相应修改。
http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=TSCUpdate&collection=Col3

最新到达的数据往往是最近搜索最频繁的。使用这个策略,用户可以将最新的数据保存在一个相对较小的文档集中,而将相对比较久远的数据进行索引的合并。用户还可以为包含最新数据的物理文档集配置更多的备份以提高查询吞吐量。因此,通过这种策略,用户可以根据案例的需要定制不同时间段的数据集。
注意:创建物理文档集需要一些时间,因此一般建议用户在更新别名之前预先将物理文档集创建完毕,届时只是简单的修改别名即可(非常快)。
查询别名
创建别名 TCS -> Col1
http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=TSC&collection=Col1
有时用户可能需要读取某些特定时间窗口内的数据。为此用户可以创建多个别名,分别映射到不同的时间窗口。有时用户希望忽略一些过期的数据,仅仅搜索最新部分的物理文档集。例如,用户只想搜索Col2与Col3,忽略Col1。以微博为例,用户关心的一般是近1、2年的数据。
http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=TSC&collection=Col2,Col3

为了满足那些搜索时间跨度更大的查询,用户也可以将别名映射到Co1、Col2与Col3。
http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=TSC&collection=Col1,Col2,Col3

在实际应用中,最常见的策略是使用滚动窗口,即将别名映射到最近的N个物理文档集合。
索引重建
文档集别名对索引重建也有很大的价值,尤其是处理那些静态索引。文档集别名允许用户在提供查询服务的同时对文档集进行索引重建,当新索引创建完毕后,用户只需要将别名映射到新索引,删除旧索引即可。整个过程零宕机(Zero Downtime)。
调度
该策略的实现需要调度工具的帮助,以自动化文档集的创建、删除,文档集别名的修改,静态索引的合并等。调度逻辑可以很简单,也可以很复杂,但无论如何,我们建议将调度逻辑实现在一个或者两个驱动程序中。用户可以使用任何能够触发HTTP请求的编程语言,包括Java、Python、Perl、Shell…… 接着利用使用熟悉的调度工具定期触发驱动程序即可。其中cron是UNIX/Linux中一种比较常用的、可靠的选择。不过我们更建议用户使用Cloudera企业版中的ApacheOozie。
总结
这篇文章介绍了一种用于处理大规模近实时数据的通用架构。时间序列数据仅仅是它的一个简单案例。请关注这个技术的发展趋势,或许很快它将在一个物理文档集的不同数据分片中实现类似的功能!
引文: http://blog.cloudera.com/blog/2013/10/collection-aliasing-near-real-time-search-for-really-big-data/




