刘关张的分布式计数器

刘关张的分布式计数器

最近,我读到了一篇有趣的tech blog,讲的是Uber如何进行大规模的Job Counting。

Uber遇到的问题:

  1. 数据量大:需要管理和处理由数百万个工作生成的大量数据。
  2. 实时需求:确保工作计数的实时准确性和性能。
  3. 复杂查询:在没有显著延迟的情况下高效处理复杂查询。
  4. 系统可扩展性:扩展系统以支持各种业务需求和未来增长。

 

今天我尝试利用三国的视角解读一下uber提出来的方案。

  

刘备、关羽和张飞在蜀国建立了一个庞大的商业帝国。每天,他们都被繁重的任务压得喘不过气。为了分派任务并确保数据的准确性,他们请来了聪明绝顶的诸葛亮,希望他能解决这个大难题。诸葛亮决定使用一种叫做Apache Pinot的技术来处理所有的数据。

Apache Pinot的部署:蜀国版

为了更好地管理这些任务,诸葛亮把蜀国划分成几个区域,每个区域都有自己的数据存储和处理系统(Pinot clusters)。每个集群有controller(总指挥官)、broker(传令官)和server(战斗部队)。这样,每个区域的数据都能独立处理,避免了数据混乱。想象一下,每个区域就是一个小蜀国,井井有条地运作着。

查询性能优化:诸葛亮的秘密武器

诸葛亮发现,查询大量数据的时候,速度特别慢。于是他采取了几种措施来加快速度:

  • Sorting the provider_id column: 这样可以把同一天同一个人的所有任务放在一起,减少查询时需要访问的数据段数量。
  • Adding Inverted Index: 给provider_id和requester_id列加上Inverted Index,让查询速度快了不少。
  • Using Bloom Filter: 这种概率型的数据结构,能快速判断数据是否存在,进一步加快查询速度。

Regular Index VS Inverted Index:刘备书房里的秘密

刘备书房里有很多书,每本书的封面上都贴有书名。每次刘备要找某本书时,他需要翻看书架上的每一本书的封面,直到找到目标书。这种方式虽然能找到书,但效率太低。普通索引就像书的目录,通过关键字段(如书名、页码等)快速定位到具体位置。但当涉及到多个字段或复杂查询时,效率会下降。

诸葛亮给刘备设计了一种新方法。他把每本书的内容按关键词拆分,并在每个关键词下记录对应的书名和页码。例如,如果刘备想找关于“战役”的内容,他只需查阅“战役”这个关键词,马上就能找到所有相关书籍和具体页码。这种方式大大提高了查找效率。倒排索引特别适用于全文搜索、多个字段的联合查询等场景,比如搜索引擎和大数据分析中。

Segment:刘备的军队管理策略

刘备将军队分为多个营,每个营都有自己的任务记录。诸葛亮每天根据任务量调整每个营的记录方式。开始时,每天只记录四次,但随着任务量增加,改为每天记录八次,甚至更多。这样每个营的记录变得更加精细,处理速度也更快。

Segment就是把大数据集分成较小的部分。通过增加数据段的数量,可以提高数据处理的效率。虽然增加数据段会带来一些管理上的开销,但可以显著减少查询延迟。

应对数据复杂性:诸葛亮的妙招

随着时间推移,蜀国的商业系统越来越复杂。有时一个任务可能会重新分派给另一个人(就像战场上的临时调兵)。为了保持数据的一致性,诸葛亮在任务记录中明确标记这些变化。

比如,有一次刘备派关羽去完成一项重要的护送任务。但在任务进行中,关羽遇到了紧急战事,不得不转交任务给张飞。诸葛亮在任务记录中加了一个字段,叫做“Job Status”。当关羽接到任务时,记录为“In Progress”。当任务转交给张飞时,记录变更为“Reassigned”,并在备注中注明变更原因和新的负责人。

处理突发流量:诸葛亮的应对策略

有时候,系统会遇到突发流量高峰,就像敌军突然发动的大规模进攻。诸葛亮在每次请求时加入了随机抖动(random jitter),确保系统能均匀地处理请求,避免系统过载。

通过这些措施,刘备、关羽和张飞成功地建立了一个高效、可靠的任务追踪系统,确保蜀国的每一场战役都能得到准确的记录和处理。

 

诸葛亮运用Apache Pinot技术,优化了数据查询和处理性能,通过排序、倒排索引和分段等方法,提高了查询速度和数据处理效率。同时,通过对复杂数据的标记和处理突发流量的策略,确保了系统的稳定性和一致性。这些措施有效解决了开头提到的任务繁重和数据管理问题。

Uber Tech Blog原文

Back to blog