c# - 在数据库中保存非常繁忙的计数器的最佳实践
问题描述
我正在开发一个非常繁忙的 Web 服务,它应该每秒收到数千个请求。我希望每个请求都会更新一个计数器字段。我该怎么做?将计数器保存在 db 中非常重要,因此在服务器死机的情况下我不会丢失信息。我已经尝试过以下代码,但这对于每秒数千个请求来说将是一个巨大的瓶颈。你会怎么做?
public void Upload(int organizationId)
{
try
{
lock (UpadateLock)
{
using (var db = new DbContext())
{
Counter counter = db.Counters.Where(c => c.OrganizationId == organizationId).FirstOrDefault();
counter.count++;
db.SaveChanges();
}
}
}
catch (Exception ex)
{
}
}
解决方案
如果您在服务器死机时绝对不能丢失数据,那么您必须为每个增量写入持久存储。
问题是使用什么商店。
您当然可以使用 SQL 来完成。像这样的简单查询并不太昂贵。您可以对此进行基准测试以查看开销是否可以接受。测量 Web 服务器和 SQL 服务器上的 CPU 使用率。还测量磁盘使用情况和事务日志大小。
Redis 可能会成为一个非常好的数据库。众所周知,它速度很快,并且支持服务器端增量。
您还可以通过将增量写入多个服务器(随机选择一个)来扩展此工作负载。
您也可以使用任何其他数据存储。如果它本身不支持递增,您可以改为插入新行。然后,有一个后台进程定期聚合这些行,这样它们就不会继续累积。
推荐阅读
- ios - Swift:UILabel,闪烁 textColor 动画
- firebase - 开始使用适用于 Firebase 和 Firestore 的 Cloud Functions
- javascript - 如何使用ajax访问两个不同的对象?
- vue.js - 如何在 VueJS 中制作图像网格堆栈?
- python - 将 tf.data.Dataset 包装到 tf.function 中会提高性能吗?
- javascript - 如何管理 Vue 反应性?
- java - 转换为字符串到json
- java - azure-sql 中不允许使用 Hibernate 调用的 USE 语句,如何避免?
- c# - 在 C# 中使用 LINQ 从 localdb 获取数据时出现问题
- primefaces - 使用回车键保存 p:inplace