自动保存服务器架构

ami*_*mit 8 php mysql redis node.js server

我想在服务器上保存一个冗长的表单输入.但我不认为对每个自动保存操作进行db调用是最好的方法.

什么构成解决这个问题的好方法?

另一个问题是我有3个app服务器.所以内存缓存不起作用.

我正在考虑将数据保存在redis中并在每次调用时更新它,最后更新数据库.但由于我有3台服务器,我如何确保呼叫在队列中?

任何人都可以帮助建筑吗?

Ser*_*sev 7

但我不认为对每个自动保存操作进行db调用是最好的方法.

这是真正的问题,让我们从这开始.你为什么那么想?你想要自动保存,对吧?这是唯一可以节省用户工作的东西.

您列出的所有其他选项(memcached/redis,进程内缓存) - 不仅不会保存用户工作,而且还会定时炸弹.想想那些可能在那里失败的事情:redis死亡,网络分裂,整个数据中心被闪电击中.

为什么在你可以......保存时创造所有的复杂性?您可能会发现它并不那么慢(如果这是您的担忧).

  • @amit:由你来决定.正确配置的现代数据库如果配置得当,可以承受很多. (5认同)

Sal*_*med 5

这是扩展架构时面临的一个非常经典的问题,但让我们稍后再扩展,因为本质上您的初始应用程序需要对数据库级别进行多次调用,让我们先对其进行优化。

由于您没有为您的 iops 提供任何详细信息,我将在下面描述解决它的方法,按照负载递增的顺序,所有方法都具有级联性质,即最后一种方法实际上是建立在所有以前的解决方案之上的:

直接数据库方法 {db 调用每个自动保存操作}:

客户端->应用层->数据库(这里直接存数据)

基本上在任何数据更新上,我们直接将其传播到数据库级别。此模式中的主要块是数据库中需要注意的事项:

  • 对于最常用的关系数据库,如 Mysql :

    • 插入查询比更新查询花费的时间更少,对于大学项目,您可以根据相同的主键不断更新行,它会很好地工作。
    • 但是在任何单个表单修改需要 30-40 个请求的中型应用程序中,更新查询会阻塞您的数据库资源。

    • 因此,请保留一种附录类型的架构,例如可能会维护一个二级键,例如状态,该状态会跟踪用户填写表单的级别,但会为每次更新继续插入数据。并始终按照插入的最新状态读取。

    • 为了进一步优化使用索引,如外键约束应该被应用

    当这一步失败时,下一步是数据库本身,下一步要优化的是,您正在处理的数据类型,您可以为非事务数据选择无模式的数据库,如 mongo、dynamodb 等

  • 使用无模式数据库对于大量非事务性数据非常有帮助,因为它们本质上允许对同一行数据使用增编方法。

    • 对于额外的优化,使用二级索引来更快地查询数据。

涉及应用层方法{应用层缓存}:

客户端-> 应用层(这里保存一些数据,稍后传播)-> 数据库(最后保存在这里)

  • 当简单的数据库无法根据需要提供服务和扩展时,最简单的方法是将一些负载转移到您的 API 服务器上。由于水平扩展相同,更容易和更便宜。
  • 这与您理解的内存缓存方法完全一样,尽管不要自己设计 - 需要多年了解大型 Web 基础架构,然后人们也无法在应用程序层设计有效的缓存。
  • 使用类似Express Session 的东西,我将它用于具有 10 个 ec2 nodejs 实例的 Web 应用程序,每个会话存储大约 15mb 的用户数据。它可以很好地扩展,在所有服务器上维护唯一的用户会话数据 - 因此在每次自动更新时将数据保存到用户会话 - 在表单提交从会话写入数据库。可以通过添加更多 api 服务器轻松扩展,最佳用例是使用它在 redis 上保存数据{为什么要重新发明轮子?}

重新发明轮子:自定义级别的应用层缓存 + 数据库缓存 + 数据库优化

客户端->应用层(这里保存一些数据)->{添加你的数据库缓存}->数据库(最后在这里保存数据)

  • 这就是我们使用 redis/Dynamodb/mongo 设计我们自己的东西来充当主数据库缓存的地方。(请注意,如果首先使用非事务性数据库,请采用附录方法 - 这纯粹更适合通过添加非事务性数据库的包装器来扩展事务性数据库)

  • 此外,express session 实际上通过在应用层缓存 redis 上的数据以相同的方式工作,始终尽量减少对 db 的调用次数。

  • 因此,如果您有一个功能齐全的应用程序层缓存和一个优化的数据库,那么请采用这种方法,因为它需要有经验的开发人员并且是资源密集型的,并且通常用于非常大规模的应用程序,例如我在快速会话之后有一层 redis 缓存平均每秒 30 万请求的 iops 的应用程序

  • 这里的方法是保存用户会话上的数据,将延迟写回缓存。Maritain 缓存分类帐,然后写入您的主数据库。对于如此大规模系统中的排队方法,我编写了一个完整的独立微服务,它在后台工作以将数据从会话传输到 redis 到 mysql,如果您担心如何维护队列,请阅读有关优先级队列和后台工作人员的更多信息。我使用的Kue 是一个由 redis 支持的优先作业队列,为 node.js 构建。

  • 维护并行和顺序队列

  • KUE的php客户端
  • 后台服务