ale*_*exx 6 c# asynchronous azure redis stackexchange.redis
我相信我们在这里缺少一些非常重要的东西,所以希望有人可以指出我正确的方向.先感谢您 :)
我们目前遇到的问题:有时异步操作(读取)不会从通过异步操作写入的db返回我们的哈希值.例如,一次操作可以返回600个键,下一次键的数量可以是598,下一个是596,依此类推.我们也遇到了与短集相同的问题(当我们在集合中有多达10个键并且在批处理中读取10个哈希对象时:有时我们可以获得8个对象,有时是6个,一旦我们只得到2个.我们遇到了异步方法问题大约30-40%的运营,迁移到同步操作解决了一些情况 - 我们已经失去了性能.
我们的创建/读取批处理操作的示例
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;
}
Run Code Online (Sandbox Code Playgroud)
我们下一步使用写操作:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
我们使用下一个代码示例批量读取数据
IEnumerable<RedisKey> userKeys =
GetIdsByUserId(userId).Select(x => (RedisKey) KeysBuilders.Live.Dynamic.BuildDetailsKeyByUserId(x));
return GetBatch(userKeys, (batch, key) => batch.HashGetAllAsync(key), _dtoMapper.MapToDynamic);
Run Code Online (Sandbox Code Playgroud)
我们知道batch.Execute不是同步/不是真正的异步操作,同时我们需要稍后检查每个操作的状态.我们计划在redis服务器上进行更多的读写操作,但是使用这个问题,我们不确定我们是否走在正确的道路上.
任何建议/样品和指向正确方向的人都非常感谢!
一些附加信息:我们在asp.mvc/worker角色(.NET版本4.5)中使用StackExchange redis客户端(最新稳定版本:1.0.481)来连接和使用Azure redis缓存(C1,标准版).目前,在小测试流程中我们在数据库中有大约10万个密钥(主要是哈希 - 基于redis.io中提供的建议(每个密钥最多可存储10个不同对象的字段,哈希中不存储大数据或文本字段)和设置(主要是映射,最大的一个可以占用父母的10 000个密钥)).我们有大约20个小写入缓存(每个编写器实例写入它自己的数据子集,不与另一个重叠,每个操作写入的密钥数量最多为100(散列)).我们还有一个"大个子"
小智 0
也许你可以用
List<T> result = new List<T>(keyList.Count);
Run Code Online (Sandbox Code Playgroud)
像这样的东西吗?
ConcurrentBag<T>result = new ConcurrentBag<T>();
Run Code Online (Sandbox Code Playgroud)
ConcurrentBag 表示线程安全的、无序的对象集合。
归档时间: |
|
查看次数: |
1146 次 |
最近记录: |