2

我试图提出一个基于 DateTime 的分区键策略,它不会导致最佳实践指南中经常描述的 Append-Only 写入瓶颈。

基本上,如果您按 YYYY-MM-DD 之类的方式进行分区,那么您在特定日期的所有写入都将结束于同一个分区,这将降低写入性能。

理想情况下,分区键甚至应该将写入分布在尽可能多的分区上。

为了实现这一点,同时仍然基于 DateTime 值的键,我需要想出一种方法来分配相当于日期线值的桶,其中桶的数量是每个时间间隔的预定数量 - 比如每天 50 个。将日期线分配给存储桶应尽可能随机 - 但对于给定值始终相同。这样做的原因是,在给定原始 DateTime 值的情况下,我需要能够始终获得正确的分区。换句话说,这就像一个哈希。

最后,也是至关重要的,我需要分区键在某个聚合级别上是连续的。因此,虽然给定时间间隔(例如 1 天)的 DateTime 值将随机分布在 X 个分区键中,但当天的所有分区键都将位于可查询范围之间。这将允许我查询所有行的聚合间隔,然后按 DateTime 值对它们进行排序以获得正确的顺序。

想法?这一定是一个众所周知的问题,已经解决了。

4

2 回答 2

3

使用日期时间戳的毫秒部分怎么样,mod 50。这会给你全天的随机分布,值本身是连续的,并且你可以在给定原始时间戳的情况下轻松计算 PartitionKey?

于 2013-07-16T09:51:27.800 回答
0

为了添加到 Eoin 的答案,下面是我用来模拟他的解决方案的代码:

   var buckets = new SortedDictionary<int,List<DateTime>>();
   var rand = new Random();

   for(int i=0; i<1000; i++)
   {
          var dateTime = DateTime.Now; 
          var bucket = (int)(dateTime.Ticks%53);
          if(!buckets.ContainsKey(bucket))
                 buckets.Add(bucket, new List<DateTime>());

          buckets[bucket].Add(dateTime);
          Thread.Sleep(rand.Next(0, 20));
   }

所以这应该模拟大约 1000 个请求进来,每个请求间隔在 0 到 20 毫秒之间。

这导致 53 个“桶”之间的分布相当好/均匀。正如预期的那样,它还避免了仅附加或仅前置反模式。

于 2013-07-17T13:45:48.790 回答