简体   繁体   English

服务器端的javascript函数在mongoDB中是否存在性能问题?

[英]Does server-side javascript function have performance issues in mongoDB?

Does running server-side JavaScript have performance issues in MongoDB? 在MongoDB中运行服务器端JavaScript是否存在性能问题? Does V8 solve said performance issues? V8能解决上述性能问题吗?

Why does the MongoDB documentation recommended not using server-side functions? 为什么MongoDB文档建议不使用服务器端功能?

When you ask about the viability of server-sided javascript, you first have to make clear what kind of server-sided javascript you are talking about. 当你询问服务器端javascript的可行性时,首先要弄清楚你在谈论什么样的服务器端javascript。 According to the documentation , there are four different kinds of server-sided code execution. 根据文档 ,有四种不同的服务器端代码执行。 Unfortunately they all are kind of hackish workarounds for situations where the native API is insufficient: 不幸的是,对于本机API不足的情况,它们都是一种hackish变种:

The eval command eval命令

eval has the drawback that it only runs on one node. eval的缺点是它只能在一个节点上运行。 This greatly reduces its usefulness in a clustered environment. 这大大降低了它在集群环境中的实用性。 With sharded collections, it doesn't work at all! 使用分片集合,它根本不起作用!

By default, it also creates a global lock which makes the database completely unusable until the script has run. 默认情况下,它还会创建一个全局锁,这使得数据库在脚本运行之前完全无法使用。 This can be prevented with the nolock argument (unless the script itself does something which creates a global lock). 使用nolock参数可以防止这种nolock (除非脚本本身执行创建全局锁定的操作)。

The answer by Sammaye also explains some serious security concerns. Sammaye的答案也解释了一些严重的安全问题。

It's really more of a test- and administration tool than something you should use for any regular operation. 它实际上是一个测试和管理工具,而不是你应该用于任何常规操作的东西。

Running .js files via a mongo shell Instance on the Server 通过服务器上的mongo shell实例运行.js文件

In this case, the code isn't executed on the database, but rather on another independent process on one of the servers. 在这种情况下,代码不会在数据库上执行,而是在其中一个服务器上执行另一个独立进程。 This means that all the required data from other shards must be transfered to the server which runs the javascript code, no matter what's actually returned by the script. 这意味着必须将来自其他分片的所有必需数据传输到运行javascript代码的服务器,无论脚本实际返回什么。

It appears as another application to the mongodb server, so it can't do anything you couldn't also do from within your regular application. 它似乎是mongodb服务器的另一个应用程序,因此它无法在常规应用程序中执行任何操作。 It's another test- and administration tool you shouldn't use in regular operation. 它是另一种不应在常规操作中使用的测试和管理工具。

Find with the $where -operator 使用$ where -operator查找

The $where operator in a find-command allows to pass a javascript function which is used to filter values. find-command中的$ where运算符允许传递用于过滤值的javascript函数。 For most trivial cases, this is a lot less performant than what the other tools of the find query have to offer, especially because it can't make use of any indices. 对于大多数琐碎的情况,这比查找查询的其他工具所提供的要低得多,特别是因为它不能使用任何索引。

When usage of $where can't be avoided, at least try to use some of the normal tools of the find-query to reduce the set of documents which need to be passed to the $where function. 当$ where的使用无法避免时,至少尝试使用find-query的一些常规工具来减少需要传递给$ where函数的文档集。

MapReduce MapReduce的

MapReduce uses two javascript functions to create aggregated data. MapReduce使用两个javascript函数来创建聚合数据。 It used to be the primary data-mining tool for MongoDB, but most of its usual use-cases are now fulfilled by the much more user-friendly aggregation framework . 它曾经是MongoDB的主要数据挖掘工具,但它的大多数常用用例现在都由更加用户友好的聚合框架来实现

It also has the same drawback as $where: Unless you filter, you will have to run not one but at least two javascript functions for each document. 它也有与$ where相同的缺点:除非你过滤,否则你必须为每个文档运行一个但不至少两个javascript函数。

But MapReduce can at least run distributed and it can be parallelized. 但MapReduce至少可以运行分布式并且可以并行化。

tl;dr: TL;博士:

Using Javascript is a last resort measure for very unusual queries which can not be made with the normal query language and which require access to too much data to be implemented in the application. 对于非常不寻常的查询,使用Javascript是最后的手段,这些查询无法使用普通查询语言进行,并且需要访问要在应用程序中实现的过多数据。 When possible, do what you want to do with the specialized tools you have available or implement your logic on the application layer. 如果可能,使用您可用的专用工具执行您想要的操作,或在应用程序层上实现您的逻辑。

It is recommended within the documentation not to use stored JavaScript procedures within MongoDB. 在文档中建议不要在MongoDB中使用存储的JavaScript过程。

I kind of still refuse to call it "server-side" since that denotes that it works "in" MongoDB which it does not, they are not stored procedures. 我仍然拒绝将其称为“服务器端”,因为这表示它在“MongoDB”中工作但它不是,它们不是存储过程。

Anyway, by default JavaScript functions take global lock, which can be mitigated with nolock and V8 (default since 2.4) can multithread; 无论如何,默认情况下JavaScript函数采用全局锁定,可以使用nolock和V8(默认自2.4)可以缓解多线程; so it does seem as though this is usable but there are other problems: 所以它似乎可以使用,但还有其他问题:

  • eval runs on the primary of a replica set and only the primary eval在副本集的主节点上运行,仅在主节点上运行
  • eval does not work with sharded collections still eval仍然不适用于分片集合
  • eval must have full admin access to run at all with auth enabled (this means using an admin user in your application) eval必须具有完全管理员权限才能在启用auth的情况下运行(这意味着在您的应用程序中使用管理员用户)
  • eval runs in a self contained JavaScript environment which when run with admin acess has full access to your database. eval在一个自包含的JavaScript环境中运行,当使用admin acess运行时,它可以完全访问您的数据库。 That, in itself, rings alarm bells for me, mainly due to quirks that could be used to compromise my system from the inside. 这本身就为我敲响了警钟,这主要是因为可以用来从内部危害我的系统的怪癖。

Honestly the V8 change adds some awesomeness for Map Reduce and stuff but I would not say it changes much in terms of attempt to replace stored procedures with stored JavaScript functions. 老实说,V8的改变为Map Reduce和东西添加了一些很棒的功能,但我不会说它在尝试用存储的JavaScript函数替换存储过程方面有很大的改变。

As an added note: http://docs.mongodb.org/manual/reference/command/eval/#dbcmd.eval the warning box there should keep you away from trying this. 作为补充说明: http//docs.mongodb.org/manual/reference/command/eval/#dbcmd.eval那里的警告框应该让你远离尝试这个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM