Jestem pewien, że brakuje nam czegoś bardzo ważnego tutaj, więc mam nadzieję, że ktoś może wskazać mi właściwy kierunek. Z góry dziękuję :)StackExchange Redis niektóre klawisze zostały utracone podczas używania async do wstawiania/odczytu danych
Problem, który mamy obecnie: czasami operacja asynchroniczna (odczyt) nie zwraca nam wartości mieszania z db, która została napisana przez operację asynchroniczną. Na przykład, jedna operacja czasowa może zwrócić nam 600 kluczy, przy następnej liczbie kluczy może wynosić 598, następna: 596 i tak dalej. Występuje również ten sam problem z krótkimi zestawami (gdy mamy do 10 kluczy w zestawie i odczytujemy 10 obiektów hashowych w partii: czasami możemy uzyskać 8 obiektów, czasami 6, gdy otrzymamy tylko 2. Mamy problem z metodami asynchronicznymi w około 30-40% naszej działalności, migracja do synchronicznych operacji rozwiązany niektórych przypadkach. - być straciliśmy wydajność
Przykład naszych tworzonych/odczytu operacji wsadowych
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;
}
używamy zapisu operacje w następujący sposób:
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;
});
}
Czytamy dane jako partii, stosując kolejny przykładowy kod
IEnumerable<RedisKey> userKeys =
GetIdsByUserId(userId).Select(x => (RedisKey) KeysBuilders.Live.Dynamic.BuildDetailsKeyByUserId(x));
return GetBatch(userKeys, (batch, key) => batch.HashGetAllAsync(key), _dtoMapper.MapToDynamic);
Wiemy, że batch.Execute ma synchroniczny/asynchroniczny naprawdę nie operacja, w tym samym czasie musimy sprawdzić status każdej operacji później. Planujemy wykonać więcej operacji odczytu-zapisu na serwerze redis, ale korzystając z tego problemu, nie jesteśmy pewni, czy jesteśmy na dobrej drodze).
Wszelkie porady/próbki i punkty we właściwym kierunku są wysoko cenione!
Niektóre informacje dodatkowe: Używamy klienta redis StackExchange (najnowsza stabilna wersja: 1.0.481) w roli asp.mvc/worker (.NET w wersji 4.5) do nawiązywania połączenia i pracy z pamięcią podręczną Redis Azure (C1, Standard). W tej chwili mamy około 100 000 kluczy w bazie danych podczas małego przepływu testowego (głównie Hasch - na podstawie zaleceń podanych w redis.io (każdy klucz przechowuje do 10 pól dla różnych obiektów, bez dużych danych lub pól tekstowych przechowywanych w haśle) i zestawy (głównie odwzorowania, z których największy może zabrać rodzicowi do 10 000 kluczy)). Mamy około 20 małych pisarzy do pamięci podręcznej (każda instancja programu piszącego zapisuje własny podzbiór danych i nie pokrywa się z innym, liczba kluczy do zapisu na operację wynosi do 100 (hash)). Mamy również jednego pracownika "dużego człowieka", który może wykonać obliczenia na podstawie aktualnego stanu redis i zapisać dane z powrotem na serwerze redis (liczba operacji - do 1200 kluczy do odczytu/zapisu na pierwsze żądanie, a następnie pracować z 10 000+ kluczy (przechowuj i kalkuluj) W tym czasie wielki człowiek działa: nikt nie czyta i nie pisz do tego kluczowego obszaru, jednak małymi pisarzami ciągle piszą kilka kluczy stale W tym samym czasie mamy wielu małych czytelników (do 100 000), którzy mogą zażądać określonego fragmentu danych (na podstawie mapowań i złączeń 2 obiektów hashowych) Ilość elementów hash do zwrócenia czytelnikom wynosi około 100-500 rekordów. Z powodu pewnych ograniczeń w modelu domeny - mamy spróbuj przechowywać/czytać klucze jako operacje wsadowe (największa (najdłuższa) partia może mieć do 500-1000 odczytów/zapisów pól hashów do pamięci podręcznej. w tej chwili.