我的任务是组合一个可以处理数据库中高级插入的解决方案。将会有许多来自网页的AJAX类型的调用。它不只是一个网站/页面,而是几个不同的网站/页面。
它将处理跟踪人们在网站上的行为,由各种javascript事件触发等。
对于该解决方案来说,能够处理繁重的数据库插入负载是很重要的。插入数据后,我不介意将数据迁移到替代/补充数据存储。
我们最初考虑将均值堆栈与MongoDB结合使用,并将一些数据迁移到MySql以用于报告目的。我还想知道如何在插入到db或缓存(如memcached )之前使用某种类型的队列。
在这方面,我在其他地方找不到太多帮助。我确实看过this post,但它现在已经有5年的历史了,感觉有点过时,不太会问同样的问题。
非常感谢您的想法和意见。谢谢。
发布于 2015-04-27 21:30:10
为什么你需要一个栈呢?您是否正在寻找web应用程序来执行插入操作?或者您已经有应用程序了吗?
在插入方面,任何缓存层都不能超过您的NoSQL数据库,但您可能应该确认您甚至需要一个NoSQL数据库。MySQL具有相当可靠的原始插入性能,只要您的负载可以在单个机器上处理即可。大多数NoSQL解决方案的水平伸缩性更好。This可能值得一读。但实际上,如果您已经在内部安装了MySQL,并且将报表与insert实例分开,那么使用MySQL可能没什么问题。
发布于 2015-04-27 22:33:30
一些初始理论
为了了解如何针对繁重的插入工作负载进行优化,我建议先了解在数据库中插入数据所涉及的主要开销。一旦理解了各种开销,所有的优化都会自然而然地来到你的身边。额外的好处是,你们将对解决方案更有信心,对数据库有更多的了解,并且可以将这些优化应用于多个引擎(MySQL、PostgreSQl、Oracle等)。
我首先列出了一个非详尽的插入开销列表,然后展示了避免此类开销的简单解决方案。
1. SQL查询开销:为了与数据库通信,您首先需要创建到服务器的网络连接,传递凭据,验证凭据,序列化数据并通过网络发送,等等。一旦接受了查询,就需要对其进行解析,验证其语法,必须解析和验证数据类型,以及对象(表、索引等)。所有这些步骤(我确信我在这里忘记了相当多的事情)在插入单个值时代表了显著的开销。开销如此之大,以至于一些数据库,例如Oracle,有一个SQL缓存来避免其中的一些开销。
解决方案:重用数据库连接,使用准备好的语句,并在每个SQL查询(1000到100000s)中插入许多值。
2.确保强ACID保证: DB的ACID属性是以提前将所有逻辑和物理修改记录到数据库为代价的,并且需要复杂的同步技术(细粒度锁定和/或快照隔离)。处理ACID保证所需的实际时间可能比在数据库页中实际复制200B行所需的时间高出几个数量级。
解决方案:在表导入数据时禁用撤消/重做日志记录。或者,您还可以(1)降低隔离级别,以牺牲较弱的ACID保证来换取较低的开销,或者(2)使用异步提交(此功能允许DB引擎在将重做日志正确固定到磁盘之前完成插入)。
3.更新物理设计/数据库约束:在表中插入值通常需要更新多个索引、物化视图和/或执行各种触发器。这些开销很容易在插入时间内占据主导地位。
解决方案:可以考虑在插入/导入期间删除所有辅助数据结构(索引、实体化视图、触发器)。一旦完成了批量插入,您就可以重新创建它们。例如,从头开始创建索引要比通过单独插入来填充索引快得多。
实践中的
现在,让我们看看如何将这些概念应用到您的特定设计中。我在您的例子中看到的主要问题是,insert请求是由许多分布式客户端发送的,因此对插入进行批量处理的可能性很小。
您可以考虑在您最终拥有的任何数据库引擎前面添加一个缓存层。我认为memcached不适合实现这样的缓存层-- memcached通常用于缓存查询结果,而不是新的插入。我有使用VoltDB的个人经验,我绝对推荐它(我与该公司没有任何联系)。VoltDB是一种内存中的、横向扩展的关系型数据库,它针对事务性工作负载进行了优化,可以为您提供比MongoDB或MySQL高出几个数量级的插入性能。它是开源的,但并不是所有功能都是免费的,所以我不确定你是否需要付费购买许可证。如果你不能使用VoltDB,你可以看看MySQL的内存引擎或者其他类似的内存引擎。
您可以考虑的另一个优化是使用不同的数据库进行分析。最有可能的情况是,具有高数据摄取量的数据库在执行OLAP风格的查询方面相当糟糕,反之亦然。回到我的建议,VoltDB也不例外,在执行冗长的分析查询时也是次优的。我们的想法是创建一个后台进程,该进程读取前端DB中的所有新数据(即,这将是一个VoltDB集群),并将其批量移动到后端DB进行分析(MongoDB或其他更有效的方法)。然后,您可以为批量数据移动应用上面的所有优化,创建一组丰富的附加索引结构以加快数据访问,然后运行您喜欢的分析查询,并将结果保存为一组新的表/物化以供以后访问。导入/分析过程可以在后台连续重复。
发布于 2015-04-28 23:53:26
表的设计通常隐含着这样一种假设,即查询的数量将远远超过各种DML。因此,该表针对带有索引的查询等进行了优化。如果您有一个表,其中DML (特别是Inserts)的数量将远远超过查询,那么只需删除任何索引,包括主键,就可以大有作为。可以将键和索引添加到表中,数据将移动到表中并随后从中进行查询。
在web应用程序前面使用NoSQL表来处理高插入率,然后在空闲时或多或少地将数据移动到标准关系数据库进行进一步处理,这是一个好主意。
https://stackoverflow.com/questions/29890957
复制相似问题