但我不认为对每个自动保存操作进行db调用是最好的方法.
这是真正的问题,让我们从这开始.你为什么那么想?你想要自动保存,对吧?这是唯一可以节省用户工作的东西.
您列出的所有其他选项(memcached/redis,进程内缓存) - 不仅不会保存用户工作,而且还会定时炸弹.想想那些可能在那里失败的事情:redis死亡,网络分裂,整个数据中心被闪电击中.
为什么在你可以......保存时创造所有的复杂性?您可能会发现它并不那么慢(如果这是您的担忧).
这是扩展架构时面临的一个非常经典的问题,但让我们稍后再扩展,因为本质上您的初始应用程序需要对数据库级别进行多次调用,让我们先对其进行优化。
由于您没有为您的 iops 提供任何详细信息,我将在下面描述解决它的方法,按照负载递增的顺序,所有方法都具有级联性质,即最后一种方法实际上是建立在所有以前的解决方案之上的:
直接数据库方法 {db 调用每个自动保存操作}:
客户端->应用层->数据库(这里直接存数据)
基本上在任何数据更新上,我们直接将其传播到数据库级别。此模式中的主要块是数据库中需要注意的事项:
对于最常用的关系数据库,如 Mysql :
但是在任何单个表单修改需要 30-40 个请求的中型应用程序中,更新查询会阻塞您的数据库资源。
因此,请保留一种附录类型的架构,例如可能会维护一个二级键,例如状态,该状态会跟踪用户填写表单的级别,但会为每次更新继续插入数据。并始终按照插入的最新状态读取。
为了进一步优化使用索引,如外键约束应该被应用
当这一步失败时,下一步是数据库本身,下一步要优化的是,您正在处理的数据类型,您可以为非事务数据选择无模式的数据库,如 mongo、dynamodb 等
使用无模式数据库对于大量非事务性数据非常有帮助,因为它们本质上允许对同一行数据使用增编方法。
涉及应用层方法{应用层缓存}:
客户端-> 应用层(这里保存一些数据,稍后传播)-> 数据库(最后保存在这里)
重新发明轮子:自定义级别的应用层缓存 + 数据库缓存 + 数据库优化
客户端->应用层(这里保存一些数据)->{添加你的数据库缓存}->数据库(最后在这里保存数据)
这就是我们使用 redis/Dynamodb/mongo 设计我们自己的东西来充当主数据库缓存的地方。(请注意,如果首先使用非事务性数据库,请采用附录方法 - 这纯粹更适合通过添加非事务性数据库的包装器来扩展事务性数据库)
此外,express session 实际上通过在应用层缓存 redis 上的数据以相同的方式工作,始终尽量减少对 db 的调用次数。
因此,如果您有一个功能齐全的应用程序层缓存和一个优化的数据库,那么请采用这种方法,因为它需要有经验的开发人员并且是资源密集型的,并且通常用于非常大规模的应用程序,例如我在快速会话之后有一层 redis 缓存平均每秒 30 万请求的 iops 的应用程序
这里的方法是保存用户会话上的数据,将延迟写回缓存。Maritain 缓存分类帐,然后写入您的主数据库。对于如此大规模系统中的排队方法,我编写了一个完整的独立微服务,它在后台工作以将数据从会话传输到 redis 到 mysql,如果您担心如何维护队列,请阅读有关优先级队列和后台工作人员的更多信息。我使用的Kue 是一个由 redis 支持的优先作业队列,为 node.js 构建。
| 归档时间: |
|
| 查看次数: |
436 次 |
| 最近记录: |