我目前正在开发一种Web API,在存储和发送数据时必须快速高效。首先,我尝试了Entity Framework Core
,然后尝试了ADO.NET
,这大大提高了速度。
为了提高速度,我尝试设置Redis。但是,与ADO.NET
相比,它的运行速度让我感到震惊。具体来说,ADO.NET
541ms
和Redis
直至2.5s
都可以通过邮递员检索具有32
属性的5
对象!
以下是我为优化Redis而做的一些事情:
- 使我所有的
HashGet
异步 - 关闭持久性存储(尽管无论如何都已关闭)
- 将
save
中的config
设置为""
- 创建了一个
IDatabase
的全局实例,因此仅使用了一个连接 - 在启动时创建了我的所有哈希(请参见
RedisConnectionHelper.Instance.Hashes
)
我代表每个数据行的实际哈希(RedisConnectionHelper.Instance.Hashes
)从device1:input1
到device32:input12
,共384
。
这是我的CRUD部分课程:
namespace StateAPI.RedisContext
{
public class RedisCRUD : IRedisCRUD
{
// ^^^ store and re-use this!!!
IDatabase db = RedisConnectionHelper.Instance.Connectionmultiplexer.GetDatabase();
public async Task<IEnumerable<StateRedis>> AllStatesAsync()
{
List<StateRedis> returnedDevices = new List<StateRedis>();
foreach (string h in RedisConnectionHelper.Instance.Hashes)
{
StateRedis state = new StateRedis
{
Id = await db.HashGetasync(h,"id"),InputState = await db.HashGetasync(h,"state"),OnPhrase = await db.HashGetasync(h,"onphrase"),OffPhrase = await db.HashGetasync(h,"offphrase"),When = await db.HashGetasync(h,"when")
};
returnedDevices.Add(state);
}
return returnedDevices;
}
}
}
这是我的api控制器:
// GET api/getallstates
[HttpGet]
[Route("getallstates")]
public async Task<IEnumerable<StateRedis>> GetallStates()
{
return await _redisCRUD.AllStatesAsync(); // DI injected in
}
这是我的StateRedis模型:
namespace StateAPI.Models
{
public class StateRedis
{
public string Id { get; set; }
public string InputState { get; set; }
public string OnPhrase { get; set; }
public string OffPhrase { get; set; }
public string When { get; set; }
}
}
请注意,这是Docker的Redis容器,在内部运行Docker的linux服务器上运行。 SQL Server也在同一Docker服务器上运行,通常该服务器可以很好地运行我们所有的容器。请注意,我在这里读到,当某人的Web项目与Redis
位于同一位置时,他们的问题就消失了吗?
时间似乎在1
秒和2.5
秒之间波动,因此显然某个地方存在主要瓶颈。
更新
我的Redis连接助手:
namespace StateAPI.Helpers
{
public class RedisConnectionHelper
{
private static RedisConnectionHelper _instance = null;
public Connectionmultiplexer Connectionmultiplexer { get; set; }
public List<string> Hashes { get; set;}
public static RedisConnectionHelper Instance
{
get
{
if (_instance == null) _instance = new RedisConnectionHelper();
return _instance;
}
protected set
{
_instance = value;
}
}
public RedisConnectionHelper()
{
// ^^^ store and re-use this!!!
Connectionmultiplexer = Connectionmultiplexer.Connect("dell-docker"); // Note that Connectionmultiplexer implements IDisposable and can be disposed when no longer required
// create hashes for each device and input e.g. device1:input12
Hashes = new List<string>();
int deviceCount = 1;
int inputCount = 1;
int numOfInputs = 12;
int numOfDevices = 32;
for (int i = 0; i < (numOfDevices * numOfInputs); i++)
{
if (i % numOfInputs == 0 && i != 0)
{
inputCount = 1;
deviceCount = deviceCount + 1;
}
string deviceHash = $"device{deviceCount}:input{inputCount}";
inputCount = inputCount + 1;
Hashes.Add(deviceHash);
}
}
}
}