实时或者准实时的说法

简介: 假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。本文从个人理解出发,探探实时或者准实时搜索。

究竟什么算实时

实时或者准实时的说法,没有对错,毕竟不停的听众,对相应的信息的理解是不一样的。有说2分钟执行数据client 开始导入也是实时,有说秒级别更新可见,有说<35ms 更新可见。个中种种说法,仿佛说,我的qps达到6000,我的qps达到600,我的qps达到300一样,只有数字,没有上下文,没有任何条件。而对于做搜索的,这么说某种程度是不科学,甚至是错误的。

什么样的数据,字段类型是什么?分词是什么?数据条数规模如何,单机100w数据,单机1000w数据,单机1亿数据?索引体积规模如何?什么配置硬件设施,48g16core 物理机 ,4core 8g虚拟机,全ssd什么查询?key-value查询? 区间查询?统计查询?group 查询?高亮?只是某个极端场景、最佳的配置这样的请求qps,只是那种特殊场景的情况。query特征不同,相同的索引也是不一样的性能。笼统的说自己的qps,并依此去PK另外的系统,完全是不科学、不尊重引擎的实际特点,放大说就是自我封闭,自我的level认识不够。当然,实际过程往往这个能忽悠倒一大批不懂行情的人员,并博得赞赏。还是那句话,同行的看法才是相对客观的。

实时索引可见一般流程

路线1

1--1--> client开始组装结构化数据<结构化数据这是引擎需要的>
--2-->
传入中间层(消息队列或者本地日志系统)<缓冲或者持久化,确保性能和数据最终一致性>
--3-->
检索结点异步去拉取增量数据,然后进入内存增量索引--4--> 当设置的时间阀值或者记录条数或者内存大小<批量提交>,开始重新打开内存reader试图,这样最新的数据就可见了。


路线2

--1--> client开始组装结构化数据<结构化数据这是引擎需要的>
--2-->
传入中间层(消息队列或者本地日志系统)<缓冲或者持久化,确保性能和数据最终一致性>
--3-->
固定的build或者dump结点,异步去拉取增量数据,在离线构建完整的增量索引,当然包括删除的信息,并且build或者dump结点保留完整的全量索引--4--> 检索结点去build或者dump结点,同步已经离线好的增量索引,在线执行增量索引的加载和卸


对于路线1    

由于是增量和检索是合体的,那么资源无疑会发生争抢(查询和构建索引的内存和cpu以及io争抢)    

一条一次reopen内存索引试图,意味着单条记录的更新非常快。记住,提交并重新打开reader是非常昂贵的操作,尽管内存的绝对开销值比磁盘小很多。reopen频率更短,意味着吞吐量有影响。reopen执行批量doc时候,批量性能提升。意味着,reopen频率不能太小,否则批量性能没法体现。到此,说更新可见时间单纯这个维度看,看不到系统的整体吞吐量。    

重新打开索引视图,一方面,在重新打开前执行merger判断,在条件满足的时候执行内存压缩,当然意味着内存merger发生时候的额外峰值。这样内存的利用率更高。另一方面,在重新打开前不执行merger判断,紧紧打开新生成的segment对应的reader,这样reopen速度更快,内存更快的饱满,因为散的segment不够紧凑。只好在flush时刻合并了。并且,如果一条doc一个segment,那么非常槽糕,如果多条记录那么必须结合时间参数,例如35ms,那么这一批的doc量多大? 是否 内存的快速饱满,内存利用率不高,flush更频繁,这样IO资源争抢厉害,系统整体吞吐量如何保证?


对应路线2  

比较难实现秒级别更新。   这种实现可以达到更大的吞吐量和更好的稳定性。   相同的增量数据只需一次增量构建,和多次分发,并且分发的时候还可以共享内存。数据到达后只有内存加载的工作,而索引往往紧凑,IO效率更高。这个比在线构建时候CPU消耗可能更低,网络传输可以大块,直接内存对内存。    另外一个优势,离线的build不停的增量,从而使得离线的全量也更加最近当前时间,一旦替换全量索引,也更加快捷(补增量时间更短)。容灾和恢复优势明显。


实际系统需要权衡的点    

实时为了整体的吞吐量,client的实时数据需要缓冲和落地,从而不会受下游索引构建阻塞主流程。缓冲可以是消息队列,也可以直接落地磁盘。然后异步拉 或者推的方式执行消费。推荐拉的方式,这样每个消费者知道自己消费的点,并且可以根据本身的消费能力而调整消费速度和节奏,包括重启。当然也例如扩容源头 数据的分发。     实时为了整体的稳定性,能尽力离线搞定的,尽力离线搞定,然后离线数据同步到线上,线上只是简单的loadunload,而无其他的索引写计算开销。整个系统确保了查询的稳定性。     实时为了扩容和容灾,保存离线的索引备份和离线的源数据备份是必要的。资源允许的情况下,每个node都有对应的同等角色的node提供服务或者接管服务。     实时有时序要求,那么单线程或者多线程下的时间戳必须考虑。


实例lucene NRT  

  lucene indexWriter updateDocument 之后,执行commit可以使得索引更新的数据可见。而commit操作有可能触发mergermerger之后重新reopen内存索引试图。并且内存索引越大,reopen时间开销更短。通常1-5ms搞定。    如果不直接走commit接口实现索引试图更新,那么直接内存reopen。此时,内存零散的segment更多,内存利用率稍低,空间换得了更高的 reopen可见速度。flush时候的merger开销会有所增加。

目录
相关文章
|
5月前
|
消息中间件 存储 NoSQL
离线与实时数据开发方案
离线与实时数据开发方案
61 0
|
5月前
|
存储 SQL 缓存
实时数仓宽表加工解决方案
实时数仓宽表加工解决方案
76 0
实时数仓宽表加工解决方案
|
8月前
|
消息中间件 存储 Java
kafkaStream处理实时流式计算
kafkaStream处理实时流式计算
122 0
|
7月前
|
传感器 数据采集 监控
实时数仓的特点
实时数仓的特点
85 0
|
7月前
|
传感器 数据采集 监控
实时数仓的应用
实时数仓的应用
67 1
|
7月前
|
数据采集 存储 监控
实时数仓的可控范围
实时数仓的可控范围
42 0
|
SQL 分布式计算 监控
漫谈实时数仓
漫谈实时数仓
328 0
漫谈实时数仓
|
数据采集 大数据
用户行为分析大数据平台之(三)实时数据采集
用户行为分析大数据平台之(三)实时数据采集
148 0
用户行为分析大数据平台之(三)实时数据采集
|
数据采集 大数据
用户行为分析大数据平台之(二)离线数据采集
用户行为分析大数据平台之(二)离线数据采集
152 0
用户行为分析大数据平台之(二)离线数据采集
|
存储 消息中间件 分布式计算
Lindorm在实时归因场景下的挑战与应用
关联文章 Streams -Lindorm实时数据同步的新篇章 1 什么是归因分析 归因分析说明 (Attribution Analysis)归因分析就是从客户的行为轨迹(Customer Journey)中去分析营销策略成功的原因(Attribution of Success)。举例来讲就是小明购买天猫精灵的消费行为是由哪些渠道广告促成的?这些渠道的贡献占比多少?
692 0