Sono sicuro che ci manca qualcosa di molto importante qui, quindi spero che qualcuno possa indicarmi la giusta direzione. Grazie in anticipo :)StackExchange Redis alcuni tasti sono stati persi durante l'utilizzo async per inserire/leggere i dati
Problema che attualmente riscontriamo: a volte operazione asincrona (leggi) non restituire valore hash da db che è stato scritto dall'operazione asincrona. Ad esempio, un'operazione di una volta può restituire 600 chiavi, la quantità di chiavi successiva può essere 598, la successiva: 596 e così via. Inoltre riscontriamo lo stesso problema con i set brevi (quando abbiamo 10 chiavi nel set e leggiamo 10 oggetti hash nel batch: a volte possiamo ottenere 8 oggetti, a volte 6, una volta ottenuto solo 2. Abbiamo problemi con i metodi asincroni in circa il 30-40% delle nostre operazioni, migrazione alle operazioni sincrone risolto alcuni dei casi -. essere abbiamo perso prestazioni
Esempio dei nostri creare/operazioni batch lettura
protected void CreateBatch(Func<IBatch, List<Task>> action)
{
IBatch batch = Database.CreateBatch();
List<Task> tasks = action(batch);
batch.Execute();
Task.WaitAll(tasks.ToArray());
}
protected IEnumerable<T> GetBatch<T, TRedis>(
IEnumerable<RedisKey> keys,
Func<IBatch, RedisKey, Task<TRedis>> invokeBatchOperation,
Func<TRedis, T> buildResultItem)
{
IBatch batch = Database.CreateBatch();
List<RedisKey> keyList = keys.ToList();
List<Task> tasks = new List<Task>(keyList.Count);
List<T> result = new List<T>(keyList.Count);
foreach (RedisKey key in keyList)
{
Task task = invokeBatchOperation(batch, key).ContinueWith(
t =>
{
T item = buildResultItem(t.Result);
result.Add(item);
});
tasks.Add(task);
}
batch.Execute();
Task.WaitAll(tasks.ToArray());
return result;
}
usiamo write operazioni in corso:
private void CreateIncrementBatch(IEnumerable<DynamicDTO> dynamicDtos)
{
CreateBatch(
batch =>
{
List<Task> tasks = new List<Task>();
foreach (DynamicDTO dynamicDto in dynamicDtos)
{
string dynamicKey = KeysBuilders.Live.Dynamic.BuildDetailsKeyByIdAndVersion(
dynamicDto.Id,
dynamicDto.Version);
HashEntry[] dynamicFields = _dtoMapper.MapDynamicToHashEntries(dynamicDto);
Task task = batch.HashSetAsync(dynamicKey, dynamicFields, CommandFlags.HighPriority);
tasks.Add(task);
}
return tasks;
});
}
Leggiamo i dati come in batch utilizzando il codice di esempio seguente
IEnumerable<RedisKey> userKeys =
GetIdsByUserId(userId).Select(x => (RedisKey) KeysBuilders.Live.Dynamic.BuildDetailsKeyByUserId(x));
return GetBatch(userKeys, (batch, key) => batch.HashGetAllAsync(key), _dtoMapper.MapToDynamic);
Sappiamo che batch.Execute è alcuna operazione sincrona/asincrona non veramente, allo stesso tempo, abbiamo bisogno di controllare lo stato di ogni operazione in seguito. Abbiamo in programma di fare molte più operazioni di lettura-scrittura sul server redis, ma usando questo problema, non siamo sicuri di essere sulla strada giusta.
Tutti i consigli/campioni e punti nella giusta direzione sono molto apprezzati!
Alcune informazioni Additonal: Stiamo usando StackExchange Redis cliente (ultima versione stabile: 1.0.481) in asp.mvc/ruolo dei lavoratori (.NET versione 4.5) per connettersi e lavorare con Azure Redis cache (C1, Standard). Al momento abbiamo circa 100.000 chiavi nel Database durante un piccolo flusso di test (principalmente Hash - basate su raccomandazioni fornite in redis.io (ciascuna chiave memorizza fino a 10 campi per oggetti diversi, nessun dato grande o campi di testo memorizzati nell'hash) e set (principalmente i mapping, il più grande può richiedere fino a 10.000 chiavi per il genitore)). Abbiamo circa 20 piccoli scrittori nella cache (ogni istanza del writer scrive il proprio sottoinsieme di dati e non si sovrappone a un altro, la quantità di chiavi da scrivere per operazione è fino a 100 (hash)). Inoltre, abbiamo un lavoratore "grande uomo" che può eseguire alcuni calcoli basati sullo stato redis corrente e archiviare i dati nel server redis (quantità di operazioni: fino a 1200 chiavi da leggere/scrivere per prima richiesta, quindi lavorare con 10 000+ chiavi (memorizza e calcola) Al momento il grande uomo lavora: nessuno legge-scrive in questo spazio tasti esatto, tuttavia i piccoli scrittori continuano a scrivere alcune chiavi costantemente. Allo stesso tempo abbiamo molti piccoli lettori (fino a 100.000) che possono richiedere il loro specifico pezzo di dati (basato su mapping e join di 2 entità hash. La quantità di entità hash da restituire ai lettori è di circa 100-500 record. A causa di alcune restrizioni nel modello di dominio - noi prova a memorizzare/leggere le chiavi come operazioni batch (il batch più grande (il più lungo) può contenere fino a 500-1000 letture/scritture di campi hash nella cache. Non usiamo transazioni a t il momento.