狼厂项目实践:通用检索框架准实时流的设计与实现

背景

检索对实时性的要求很高,不仅是对索引建立、结果召回、策略干扰等核心部分,也包括数据录入的部分。检索的数据流主要包括全量数据与增量数据,其中全量数据是在运行前就已经生成好的,在检索进程运行开始时就直接解析加载了,后面不会再产生,所以不会对录入有高实时性的需求;而增量数据理论上在整个检索进程运行过程中随时都可能新增,新增了就需要录入。所以,提高增量数据录入的实时性,对提升整个检索的性能有重要作用。

设计思路与折衷

目前搜索引擎实现增量更新的方案主要有这几种:(1)提供写接口,(2)使用文件,(3)使用消息队列。

方案1即检索框架本身提供写数据的接口,数据发布方直接调用,写入数据。这种方式应该是单次写入速度最快的,但会使两方代码过于耦合,不易扩展和维护。且检索框架需要提供数据接收读取的完整机制,也要消耗很多资源。对于发布方来说,发布操作也必须依赖接收方的进度。如果数据更新频率很低,数据量很小,可以考虑使用这种方式。

方案2主要是通过文件形式,即每次有新数据到来时,都先写入一个文件中,然后定期将文件配送到检索进程本地。检索服务运行时,会监控本地文件夹的inode变化,一旦有文件产生或修改,就执行回调函数,读取该文件,进行增量加载。这种方式一定程度上实现了数据发布方和接收方的解耦,但代价是要增加对文件的操作,并且实际应用中需要依赖数据配送,这是个很耗时的过程。文件本身的产生,拷贝,读写,效率也不算高,尤其在文件内容堆积得很大的时候。所以这种方案,实时性很难保证。

方案3是通过消息队列。数据发布方将数据推到消息队列中,接收方自己读取。这种方式很好地实现了双方业务的解耦,且无需维护对文件的一系列操作,也无需数据配送,实时性大大提升。对于发布方来说,不用再记录数据到底要发给哪几个检索实例,只需发布一份数据到消息队列中即可,检索实例的增加、减少也都不需要在发布方进行修改,更加灵活。对于接收方,不用再定期处理堆积得很多的数据,资源使用也更平衡。同时也可以方便地实现流量控制等。不过稳定性需要依赖于消息队列本身。

目前糯米的检索使用的是方案2,框架成熟,运行稳定,容错容灾也都很完整。但针对糯米本身的业务特点,仍有可以改进的空间。糯米主要是提供生活服务类的检索,特点就是数据更新频繁,数据量大。而文件形式的更新,第一是实时性较差,第二是灵活性不高。而这些都可以通过消息队列的特点进行优化。

消息队列大都分为队列模式和订阅模式,根据业务需求,多个检索实例都需要相同的一份数据,所以选择订阅模式。

针对业务特点,最终选择方案3,使用消息队列的订阅模式,来实现数据的实时加载。

具体实现

糯米现有检索框架一般都是在一个单独的线程中监控文件变化,通过回调实现增量数据加载。主线程只需在其时传入需要的配置以及对数据进行处理的回调函数即可,耦合度很低。所以消息队列的添加理论上只需对这个线程所做的工作进行相应修改即可。

糯米现有检索框架中,增量数据加载的工作流程大致如下:


首先读取配置文件信息,包括增量文件的命名规则以及读到的行数等,这是为了后面打开文件及移动读指针做准备。这些配置放在本地一个单独的文件中。之后注册监控的回调函数,在文件夹inode发生变化时,会触发raise唤醒wait中的处理线程,从指定行开始逐个字节读文件,每读完一条数据就进行一次处理,读完整个文件后,就wait直到下个文件产生。

可见,整个流程都是围绕着文件展开的。改为使用消息队列读取数据后,这些和文件相关的操作就都不需要了,改为接入相应消息队列的订阅相关接口。下面描述一种使用消息队列(Kafka)的订阅模式进行数据加载的大致流程:

首先添加一个消息队列的订阅类,定义实现异步订阅的基本方法。

init中,主要实现对各个参数的配置,以及订阅起始点的读取。这个起始点是由数据发布方给出的,所以要在发起订阅前就设定好。目前的做法和上面一样,单独在本地建一个配置文件,里面存放了起始点的相关数据,init中直接读取即可。

StartSubscribe主要包含两个方法:获取要订阅的消息队列的子通道的数量,然后对每个子通道发起订阅请求。

之后进入SubscribeMainloop,在while循环中接收、处理数据。接收事件通过epoll_wait,只要有可读或报错事件触发,epoll_wait就会返回,否则会阻塞直到超时或有新事件到来。

epoll_wait返回后,如果包含可读事件,就调用回调函数进行处理即可。如果包含报错事件,会根据报错尝试重新发起订阅请求。

这样一条增量数据的加载就完成了,while循环会一直重复这个流程,直到加载完消息队列里最新的一条数据。之后就会阻塞在epoll_wait上,直到有新的数据发布进来。

总结

  本文简单介绍了一种使用消息队列的订阅模式实现通用检索框架增量数据加载的新方案,及其设计与实现。糯米现有检索框架文件形式的更新,由于数据配送系统本身的复杂性,需要至少半小时才能更新一次数据。而使用消息队列更新一条数据的用时在0.5秒以内,更新1000条数据也可在2秒以内完成,实现了准实时流,值得全面推广在检索框架的增量数据录入部分使用。

原文地址:http://blog.51cto.com/13732225/2175348

时间: 2024-11-09 06:30:35

狼厂项目实践:通用检索框架准实时流的设计与实现的相关文章

第三中情况可以用Storm分布式处理框架处理实时流式数据

http://www.blogbus.com/hrl-logs/296460063.htmlhttp://www.blogbus.com/anylt-logs/296460134.htmlhttp://www.blogbus.com/anylt-logs/296460131.htmlhttp://www.blogbus.com/hrl-logs/296460199.htmlhttp://www.blogbus.com/anylt-logs/296460425.htmlhttp://www.blo

Django项目实践4 - Django网站管理(后台管理员)

http://blog.csdn.net/pipisorry/article/details/45079751 上篇:Django项目实践3 - Django模型 Introduction 对于某一类站点, 管理界面 是基础设施中很重要的一部分. 这是以网页和有限的可信任管理者为基础的界面,它能够让你加入,编辑和删除站点内容. 常见的样例: 你能够用这个界面公布博客,后台的站点管理者用它来润色读者提交的内容,你的客户用你给他们建立的界面工具更新新闻并公布在站点上.这些都是使用管理界面的样例. 创

Hangfire项目实践

Hangfire项目实践分享 Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(Delayed jobs) 定时任务执行(Recurring jobs) 延续性任务执行(Continuations) 与quartz.net对比 Hangfire扩展 Hangfire Dashborad日志查看 Hangfire Dashborad授权 IOC容器之Au

iOS项目生成通用Windows应用

WinObjc - 使用iOS项目生成通用Windows应用 Github上一周年的WinObjc项目最近发布了预览版本,终于等到了这一天.WinObjc项目就是Build 2015大会上微软宣布的Project IslandWood项目,致力于将iOS应用快速移植成UWP应用.废话不多说,让我们来看看WinObjc项目到底如何使用. 开始之前 开始转制iOS项目前我们要先部署好WinObjc工具,工具链如下: 一台安装了Visual Studio的Windows 10 PC,2015社区版可以

搜索引擎 (一)全文资源检索框架Lucene

今天来写写搜索,现在做的这个项目中涉及到了很多的搜索大部分是我做的,有次经理问我有没有用过luence这个搜索引擎,这个还真没有用过只是听说过有这么个搜索工具包,一直没有接触过,利用做项目空闲的时间也在逐渐了解搜索方面的东西,对搜索也重新认识了一下觉得搜索方向还是很值得我们研究和应用的. 在学习方面有时选择好一个正确的学习方向是比较重要的,在我们学的过程中米老师给我指明了方向所以你不会迷茫,也知道下一步将要学习什么,但慢慢的你需要自己确定学习什么,转变角色,互联网这么发达信息量如海一般在你面前呈

linux驱动开发重点关注内容--摘自《嵌入式Linux驱动模板精讲与项目实践》

本文摘自本人拙著 <嵌入式Linux驱动模板精讲与项目实践> 初步看起来Linux设备驱动开发涉及内容非常多,而须要实现驱动的设备千差万别.事实上做一段时间驱动之后回首看来主要就是下面几点: (1)对驱动进行分类.先归纳为哪个类型的驱动.归类正确再利用内核提供的子系统进行开发,往往会发现事实上非常多通用的事情内核已经帮我们做了,一个优秀的驱动project师应该最大程度上利用内核的资源.内核已经实现的毕竟稳定性强.可移植性高. (2)找到内核的提供的子系统.接下来就是要制作该子系统对该类设备提

第六周作业:《人月神话》对我做项目实践的启示(一)

<人月神话>这本书有两个老师都有给我们推荐,第一个老师推荐时不以为然,第二个老师也推荐时,自己感觉应该是挺重要的吧,于是去图书馆借了这本书来看,刚借回来时,总觉得时间不够.作业很多,也没来的及看,就一直搁置在了那里,直到上周,在我们的项目实践开始近三周,但进度却一直赶不上来的情况下,看到了这本书,才拿起来看.目前还没看完,先写一点儿领悟到的东西. 作者从焦油坑,提出项目失败的表现,把过去几十年的大型系统开发比作一个炼焦坑,各种团队一个个地淹没在焦油坑,他们都试图解决面对的问题,但他们都必须去了

Unity3D通用UI框架

目标:编写一个简单通用UI框架用于管理页面和完成导航跳转最终的实现效果请拉到最下方查看 框架具体实现的功能和需求 加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 提供界面显示隐藏动画接口 单独界面层级,Collider,背景管理 根据存储的导航信息完成界面导航 界面通用对话框管理(多类型Message Box) 便于进行需求和功能扩展(比如,在跳出页面之前添加逻辑处理等) 编写UI框架意义 打开,关闭,层级,页面跳转等管理问题集中化,将外部切换等逻辑交给UIManager处理 功能逻辑分散

MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管理.图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离.本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能. 本篇为系列第二篇,包括: ■ 4.三层架构设计    □ 4.2 创建DbSession层 数据访问层的统一入口