在现代分布式系统中,数据常常分布在不同的工作机上,每个机器上都存储着大量且频繁变化的数据集。当需要对这些分布在不同机器上的数据进行排序并查询时,传统的解决方案往往因为数据传输量大、处理时间长而变得不适用。本文提出了一种优化方案,通过将数据分类到不同的桶中,并在查询时仅传输必要的数据,从而减少了数据传输量和提高了查询效率。
假设有多个数据存储分布在不同的工作机上,每个存储中都包含大量未排序的同类型对象。这些对象集是庞大且易变的,意味着对象经常被插入或从集合中移除(可以控制插入/移除过程)。系统需要响应以下查询:在聚合器机器上展示一个页面的对象,这些对象是从所有集合中合并排序后的列表中,从某个偏移量开始的p个对象。
为了解决这个问题,提出了以下解决方案:
Sx ≤ offset & Sx+1 > offset
Sy ≤ offset + p & Sy+1 > offset + p
该算法使用C#语言实现,并通过一个名为AggregatedSortedPage的动态链接库(DLL)来提供。该库包含一个名为IDataStoreBucketsContainer
IDataStoreBucketsContainer
聚合器是一个无状态的静态类。它唯一的公共方法GetPage
上述软件不强制要求可排序对象的类型T。将对象分配到桶中、对象比较和查询的规则与对象的类型和算法实现是分离的。为了在每个索引(标准)上提供查询,需要提供两个外部实体,即按桶分类对象的方法(在DataStoreBucketsContainer
这些方法在不同的地方使用,因为在现实生活中,DataStoreBucketsContainer
DataStoreBucketsContainer
为了测试AggregatedSortedPage程序集,使用了一个名为TestApp的控制台应用程序。Item类表示要排序的对象类型。它根据其公共字符串属性Word的字母顺序进行排序。ComparerItem类包含了将Word属性分类到桶中的方法,以及实现System.Collections.Generic.IComparer
使用包含威廉·莎士比亚所有著作的文本文件t8.shakespeare.txt作为单词源,从这里下载,并删除了逗号、撇号等辅助符号。只取测试中的不同单词(没有单词重复)。在这些修改之后,列表中剩下29541个单词。文件应该下载并放置在与TestApp.exe或TestApp.csproj相同的文件夹中。文件名在Program.cs中是硬编码的(当然,任何足够大的文本文件都可以用来测试——只需在代码中更改名称)。为了便于随后检查查询执行的正确性,所有项目都按字母顺序排序,它们的序列号和数据存储被放置在它们的适当属性中,用于测试目的,并在下面描述。
Item类有两个辅助属性,仅用于测试目的。属性DataStore指示包含此项目的Data Store,属性Num表示项目在完整排序列表中的序列号(即,文件中所有不同单词按字母顺序排序的列表)。这两个属性允许有效地检查查询执行结果。请注意,在现实生活中,这些属性是无用的。