Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Does running server-side JavaScript have performance issues in MongoDB? Does V8 solve said performance issues?

Why does the MongoDB documentation recommended not using server-side functions?

like image 757
user2564821 Avatar asked Jul 09 '13 14:07

user2564821


2 Answers

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. 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:

The eval command

eval has the drawback that it only runs on one node. 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).

The answer by Sammaye also explains some serious security concerns.

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

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.

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. It's another test- and administration tool you shouldn't use in regular operation.

Find with the $where-operator

The $where operator in a find-command allows to pass a javascript function which is used to filter values. 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.

MapReduce

MapReduce uses two javascript functions to create aggregated data. 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.

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.

But MapReduce can at least run distributed and it can be parallelized.

tl;dr:

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. When possible, do what you want to do with the specialized tools you have available or implement your logic on the application layer.

like image 63
Philipp Avatar answered Oct 31 '22 13:10

Philipp


It is recommended within the documentation not to use stored JavaScript procedures within MongoDB.

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.

Anyway, by default JavaScript functions take global lock, which can be mitigated with nolock and V8 (default since 2.4) can multithread; 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 does not work with sharded collections still
  • eval must have full admin access to run at all with auth enabled (this means using an admin user in your application)
  • eval runs in a self contained JavaScript environment which when run with admin acess has full access to your database. 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.

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.

like image 25
Sammaye Avatar answered Oct 31 '22 13:10

Sammaye