构建高性能的“插入解决方案”

时间:2015-04-27 08:41:10

标签: database database-design architecture mean-stack

我的任务是整合一个可以处理高水平插入数据库的解决方案。网页上会有很多AJAX类型的调用。它不仅是一个网站/页面,还有几个不同的网站。

它将处理跟踪人们在网站上的行为,由各种javascript事件触发等。

解决方案能够处理繁重的数据库插入负载非常重要。 插入后,我不介意将数据迁移到备用/补充数据存储。

我们首先考虑将MEAN堆栈与MongoDB一起使用,并将一些数据迁移到MySql以进行报告。我也想知道在插入db之前使用某种排队或像memcached这样的缓存

我无法在其他地方找到很多帮助。我确实看到了this post,但现在已经接近5岁了,感觉有点过时了,并没有提出同样的问题。

非常感谢您的想法和意见。感谢。

3 个答案:

答案 0 :(得分:2)

为什么你需要一个堆栈?您是否正在寻找一个Web应用程序来插入?或者您已经有申请?

令人怀疑的是,任何缓存层都会超出NoSQL数据库的插入范围,但您应该确认您甚至需要NoSQL数据库。 MySQL具有非常可靠的原始插入性能,只要您的负载可以在一个盒子上处理。大多数NoSQL解决方案都可以横向扩展This可能值得一读。但实际上,如果你已经在内部拥有MySQL,并且将报告与插入实例分开,那么你可能对MySQL没问题。

答案 1 :(得分:2)

一些初步理论

为了理解如何针对繁重的插入工作负载进行优化,我建议了解在数据库中插入数据所涉及的主要开销。一旦理解了各种开销,所有优化的国王都会自然而然地找到你。奖励是您将对解决方案更有信心,您将对数据库有更多了解,并且您可以将这些优化应用于多个引擎(MySQL,PostgreSQl,Oracle等)。

我首先制作一个非详尽的插入开销列表,然后显示简单的解决方案以避免此类开销。

1。 SQL查询开销:为了与数据库通信,首先需要创建与服务器的网络连接,传递凭据,验证凭据,序列化数据并通过网络发送,等等。 一旦接受了查询,就需要对其进行解析,验证语法,解析和验证数据类型,搜索查询引用的对象(表,索引等)以及检查访问权限等。所有这些步骤(我确定我在这里忘了很多东西)代表插入单个值时的重大开销。开销很大,以至于一些数据库,例如Oracle,有一个SQL缓存来避免这些开销。

解决方案:重用数据库连接,使用预准备语句,并在每个SQL查询(1000s到100000s)中插入许多值。

2。确保强大的ACID保证:数据库的ACID属性的代价是提前记录对数据库的所有逻辑和物理修改,并需要复杂的同步技术(细粒度锁定和/或快照隔离)。处理ACID保证所需的实际时间可能比实际复制数据库页中的200B行所需的时间高几个数量级。

解决方案:在表中导入数据时禁用撤消/重做日志记录。或者,您还可以(1)删除隔离级别以抵消较弱的ACID保证以降低开销或(2)使用异步提交(允许数据库引擎在重做日志正确加固到磁盘之前完成插入的功能)

3。更新物理设计/数据库约束:在表中插入值通常需要更新多个索引,物化视图和/或执行各种触发器。这些开销在插入时间内可以再次轻易占据主导地位。

解决方案:您可以考虑在插入/导入期间删除所有辅助数据结构(索引,物化视图,触发器)。完成大量插入后,您可以重新创建它们。例如,从头开始创建索引要快得多,而不是通过单独插入来填充索引。

在实践中

现在让我们看看如何将这些概念应用到您的特定设计中。我在您的案例中看到的主要问题是插入请求是由许多分布式客户端发送的,因此几乎没有机会批量处理插入。

您可以考虑在最终拥有的数据库引擎前添加缓存层。我不认为memcached有利于实现这样的缓存层 - memcached通常用于缓存查询结果而不是新插入。我有VoltDB的个人经验,我绝对推荐它(我与公司没有关系)。 VoltDB是一个内存中,横向扩展的关系数据库,针对事务工作负载进行了优化,可以提供比MongoDB或MySQL更高的插入性能。它是开源的,但并非所有功能都是免费的,所以我不确定你是否需要支付许可证。如果您不能使用VoltDB,您可以查看MySQL或其他类似的内存引擎的内存引擎。

您可以考虑的另一个优化是使用不同的数据库来进行分析。最有可能的是,具有高数据摄取量的数据库在执行OLAP样式查询时非常糟糕,反之亦然。回到我的建议,VoltDB也不例外,在执行长分析查询时也不是最理想的。我们的想法是创建一个后台进程,读取前端数据库中的所有新数据(即这将是一个VoltDB集群)并将其批量移动到后端数据库进行分析(MongoDB或更高效的东西)。然后,您可以应用上面的所有优化进行批量数据移动,创建一组丰富的附加索引结构以加速数据访问,然后运行您喜欢的分析查询并将结果保存为一组新表/物化以供以后访问。导入/分析过程可以在后台连续重复。

答案 2 :(得分:0)

通常使用隐含的假设来设计表,即查询将远远超过所有种类的DML。因此,该表针对具有索引等的查询进行了优化。如果你有一个表格,其中DML(特别是插入)将远远超过查询,那么你可以通过消除任何索引(包括主键)来做很多事情。可以将键和索引添加到数据将被移动到的表中,然后从中查询。

使用NoSQL表来处理您的Web应用程序以处理高插入率,然后在闲暇时将数据或多或少地移动到标准关系数据库以进行进一步处理是个好主意。