microsoft - porta azure
Estrategia de ParticiĆ³n Azure Table (2)
¿Qué tal si usamos el componente de milisegundos de la marca de fecha y hora, mod 50. Eso le daría su distribución aleatoria a lo largo del día, el valor en sí mismo sería secuencial y podría calcular fácilmente la PartitionKey en el futuro dada la marca de tiempo original?
Estoy tratando de encontrar una estrategia de clave de partición basada en un DateTime que no resulte en el cuello de botella de Append-Only que a menudo se describe en las pautas de mejores prácticas.
Básicamente, si particiona por algo como AAAA-MM-DD, todas sus escrituras para un día en particular terminarán en la misma partición, lo que reducirá el rendimiento de escritura.
Idealmente, una clave de partición incluso debería distribuir escrituras en tantas particiones como sea posible.
Para lograr esto mientras sigo basando la clave en un valor de DateTime, necesito encontrar una forma de asignar lo que equivale a intervalos de valores de línea de tiempo, donde el número de cubos está predeterminado por intervalo de tiempo, digamos 50 por día. La asignación de una fecha a un segmento debe ser lo más aleatoria posible, pero siempre igual para un valor determinado. La razón de esto es que necesito poder obtener siempre la partición correcta dado el valor original de DateTime. En otras palabras, esto es como un hash.
Por último, y críticamente, necesito que la clave de partición sea secuencial en algún nivel agregado. Por lo tanto, mientras que los valores de DateTime para un intervalo dado, digamos 1 día, se distribuirán aleatoriamente a través de las claves de la partición X, todas las claves de partición para ese día estarían entre un rango consultable. Esto me permitiría consultar todas las filas para mi intervalo agregado y luego ordenarlas por el valor DateTime para obtener el orden correcto.
¿Pensamientos? Este debe ser un problema bastante conocido que ya ha sido resuelto.
Para agregar a la respuesta de Eoin, a continuación se muestra el código que utilicé para simular su solución:
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));
}
Por lo tanto, esto debería simular aproximadamente 1000 solicitudes, cada una entre 0 y 20 milisegundos de diferencia.
Esto dio como resultado una distribución bastante buena / uniforme entre los 53 "cubos". También resultó, como se esperaba, al evitar el antipatrón de solo agregar o preceder solo.