 I'm Mike. I work for Tengen. Tengen is a startup company in New York, and we sponsor the development of MongoDB. So for those of you who aren't familiar with MongoDB, what MongoDB is is an open source, high-performance, schema-free, document-oriented database. And what's really great about that is that I get to get all of my buzzwords out of the way on the first slide. But hopefully, by the end of the talk, I'll have given you guys an idea of why these traits combine to make something that should be interesting to you guys. So can you guys in the back here? Okay. Okay, good. So what I do at Tengen is I work primarily on the Ruby and Python client libraries for MongoDB, so that's a little background about myself. And the plan for this talk is really going to be to introduce MongoDB sort of by way of comparing it to some other things in the data storage space that you might be familiar with already. And then we'll sort of get right into code examples, sort of how does MongoDB work? How does the API look from Ruby? How do you interact with it? What types of queries can you perform? And if there's time, we'll get a little bit into the auto-sharding and how that works, because people tend to have a lot of questions about that and be interested in that. One note before we go on is that if you guys have any questions throughout the presentation, feel free to throw your hand in the air and I'll try to get to those rather than just drag right through to the end. So to sort of introduce what the goal is with MongoDB, we'd like to show this chart. So you can see on the x-axis here, we have depth of functionality and on the y-axis, we have scalability and performance. So all the way in the upper left-hand corner, we have things like memcachedd, which are incredibly fast and incredibly scalable, but they might not have the functionality that you'd expect from a general-purpose data storage. So with memcachedd, for example, you basically have put and get on a single key and data can get evicted without you knowing it. So in terms of a general-purpose data storage, we might expect some more functionality. So key value stores are another sort of hot area right now, and those tend to provide a little bit more functionality than something like memcachedd. So there, a lot of times you can expect persistence. And also some of them have some more interesting query capabilities than just put and get on a single key. So with some of those, you can do things like range queries and that sort of stuff. All the way in the bottom right-hand corner, we have the rdbms. So the rdbms supports everything about the kitchen sink, tons of functionality, but they're not that scalable. And I'll talk a little bit more about that in a minute. And for some cases, they're not as performant as some of these other things. So with memcachedd, really what we're trying to do is sort of take the scalability and performance of a key value store and then just sort of push out to the right as far as we can here. So basically any functionality that we can add without degrading performance below or too far below what you get from a key value store, we're going to add. So we're really trying to sort of bridge the gap between the traditional relational database and what you get with a key value store. So I think as we go through some of the query examples, you'll see how the APIs and the types of queries you can perform aren't that different from what you're able to do with a relational database. So again, by way of introduction, I think there's a talk tomorrow titled Death to Sequel or something along those lines. And that's not something that we're advocating. So I think that the relational database has been around for the paper that introduced the relational data model was written 40 years ago in April or something. So this is well-studied technology and it's great for a lot of different applications. So we're not advocating that this be thrown out and not used for anything. We just think that there are some cases where you can get gains by moving away from relational models. So I think that what we'll see over the next couple of years is less of a one-size-fits-all approach to storing data and more of evaluating your problems and picking a data store that matches an individual solution to those problems. So some of the shortcomings that you see with the relational database are in scalability. So with the relational database, it's really easy to scale out vertically. So you can throw more power at a single node and scale that way. But that quickly gets expensive. And so one thing that a lot of these solutions are trying to do is allow you to scale out horizontally easily. So with the relational database to do that, you sort of have to develop your own sharding scheme. Things like distributed joins are really tricky to do properly. So that's one reason why we don't see these massively scalable relational databases. Also complex transactions across nodes is another really difficult problem. So with a lot of these non-relational systems, you're giving up some of those abilities to do things like joins and complex transactions. And the reason is that so you can gain some scalability. And there's also some gains, I think, in terms of flexibility for developers. So again, I'll get to in a couple of slides how something like MongoDB could give you a little bit more flexibility than you used to when working with a relational database. So to continue introducing what MongoDB is, I'm going to sort of talk about some of the features that sort of define it. And in some sort of separate it from some of the other things out there. So the first really important thing that's sort of essential to understanding MongoDB are these JSON style documents. So basically everything you store in MongoDB is a JSON style document. And that's also the way the query API works. So they're really essential to using it. And I say JSON style because we don't actually use JSON. So the stuff that we're writing to disk is actually a binary serialized version of JSON that we call bson. And that's extended slightly to add things like date-time support and regular expressions and some other things that are important if you're writing a database which aren't supported in JSON. So that's called bson. And that's actually a useful thing to look at, even if you're not enthusiastic about the whole MongoDB thing, the bson encoding and decoding would be applicable to a wide range of projects. It's sort of an open format and we've implemented it in a bunch of different languages for all the different drivers. So that's definitely worth a look independently. So yeah, another cool thing about using these JSON style documents is that we can have nested documents as well. So you can have sort of arbitrary hierarchies of documents. So by doing that, it's possible that you can eliminate some places where you would normally need to do a join just by embedding documents directly into a parent document. And I'll show an example of that later on. But that's one of the ways where you can really see some extreme performance improvements over using a relational system and doing a join across tables by embedding documents directly inside of a parent document. MongoDB is schema free. So there's no defining a table and saying this column is an integer and this column is a varchar or whatever. Basically, you can insert any document of any type or any shape into a collection. So this is more of what I was talking about when I said that there's some gains to be made in terms of flexibility versus a relational database. And we found that this schema free approach is a really nice sort of mental match to dynamically type languages like Ruby. Programmers who are used to developing Ruby are sort of already used to this schema free mindset. So making this leap is not nearly as much of a mental jump as for somebody coming from Java or something like that. And one really nice thing about this is not only does it make for sort of quick development cycles because you can, in your code as you're developing, change your schema on the fly without having to worry about doing a migration or rebuilding a table or whatever. It also makes for doing migrations on a production system. Maybe like 90% of migrations in some systems that we've run for a couple of years now have turned out to just be sort of small changes adding a new field to a table or whatever. And by doing schema free approach, you can basically do that on the fly. So no migration and it's totally trivial. You sort of handle the case and your application logic. And I'll show another example of that later on too, but that's really nice. Dynamic queries. So those of you who are coming from an RDVMS background are probably sort of used to dynamic queries with SQL. So this might not seem like too big of a deal, but some of these other systems use various other approaches of querying. So with MongoDB, it's a little bit more traditional. So we have traditional dynamic queries with, you know, you can manually specify indexes and we have a query optimizer. And this turns out to be really nice. So in terms of just administration being able to run queries on the fly and inspect the data in your database. And also it's sort of familiar to all of us. So this is the way we do development now and it's not this huge jump. So this is sort of one thing that separates MongoDB from CouchDB because that's a question that a lot of people end up asking. So with CouchDB, you define these, it's actually a really cool mechanism. You define these basically custom MapReduce functions that are basically custom index building. And then you do queries on that. So it's sort of static and predefined what your queries are to generate these custom indexes as you insert data. And with MongoDB, again, it's totally dynamic. It's a little bit more like what you're used to with SQL or whatever. And if you define your indexes appropriately, it's basically equivalent what's going on in the back end. So one thing about MongoDB is that we've really focused on performance from the very beginning. So there's a lot of decisions that have been made, which you'll see as you sort of go through docs or whatever, that have been made specifically for performance reasons. So single node performance is definitely a target of MongoDB. So things like we don't use a REST protocol for talking to the database by default. We have a binary socket protocol that speaks Bson, which is this binary JSON format that I talked about earlier. So there's a bunch of decisions that have been made for that. And what's sort of cool about it is that if you have really great single node performance, it sort of opens up opportunities to use a database in places where we might normally consider a database to be too heavyweight. So things like logging, writing logging directly to the database or session management or all sorts of stuff like that where normally you might not think that the database is applicable. Here you could consider writing directly to the database. So replication MongoDB supports replication out of the box. Master slave replication, any number of slaves. You can have a slave be a master to other nodes. So sort of daisy chaining. We also support this mode called replica pairs, which is a little bit cool. Basically you can set, right now the limit is two nodes, but we're playing on extending that in the future. But basically you can set two nodes such that they're master and slave to each other. So at any one time one of them is master and the driver's talking to that. And if the master fails, the slave automatically promotes itself and the driver knows how to talk to that. So basically you get automatic failover. And so that's really cool. Auto sharding is sort of our path to infinite scalability and hopefully we'll have time and I'll talk a little bit more in depth about how that works in MongoDB later on because that's something people tend to be pretty curious about. So the last sort of defining feature is that it's well supported across various different platforms and languages. So you can run the server on OSX, Linux, Windows, FreeBSD, Solaris, all of these 32 or 64 bit. And there are drivers written for Ruby obviously, Python, C, C++, Java, Erlang, PHP, Perl, you name it. So you can use it from a lot of different places. So to sort of summarize what we've talked about so far, what are some things that I think MongoDB is good at? I think it's good at the web. So this was actually originally developed as sort of part of a full stack cloud computing platform and we sort of ripped the database out and made it its own standalone product. So basically it was developed to be the backing data store for web applications. And again, this is something that sort of shows throughout a lot of the decisions that have been made. So that's something that it's very good at. It's good at caching. So a lot of people have found that there isn't a need for putting something like memcache in front of MongoDB. So it uses memory map files and it tends to be really performant in that regard. But also you can use it as a caching layer in front of some other processes generating data. So you can sort of have your caching layer be able to do some of these complex queries that I'll talk about in a bit. And there are people using it for that sort of thing as well. So it's good for high volume data, things like logging, things like analytics. That sort of stuff it tends to be really good at because of the way that inserts and updates work. And it's good for scalability and that comes back to that sharding thing which I'll talk about at the end. Things that MongoDB is less good at. So if you have a highly transactional system where you really need complex multi-row transactions, MongoDB is probably not an option. So basically there are no transactions in MongoDB. There's no rollbacks and there's atomicity but only on a single document at a time. So doing sort of these multi-document transactions is really not possible. I haven't found that there's been too much of a need for that with most of the people that are using this now but if that is something that you have a need for this probably isn't a good solution. Ad hoc BI. You could certainly use this for BI but it's not a target of the system. So like I said, we've really focused on sort of as a web backend and we haven't, you know, there are specialized solutions for BI so if that's what you want to use then I would probably recommend looking at one of those. And finally if your problem requires SQL so if you're using some tool that's generating SQL queries or something like that MongoDB isn't an option. So now we'll talk a little bit about some basics of working. This is going to be more at sort of the API level. So the first thing I already mentioned is the unit of storage is a document. It's stored in this BSON format which stands for binary JSON and from Ruby basically you can just think of it as a hash. So the Ruby driver takes hashes and encodes them to BSON and then takes BSON and decodes them back to regular hashes. So that's really all you have to think about. And a collection. So a collection is sort of like the schema-free equivalent of a table. So a single database in MongoDB can have any number of collections and basically they're logical groupings of documents. So since it's schema-free you might be thinking well I have no need for different tables then because I can put, no matter what my documents look like I can put them all in the same collection and that'll be fine. And that's true, you could sort of do things that way but by grouping things logically it gives you better performance on disk but also things like indexes are defined per collection. So even though it's totally schema-free you're generally going to have an idea of say a user's collection and all of your users might not be identical but you have some sort of underlying schema there. So that's sort of where our collections come in. And this is sort of a little bit of a side note but I think that in my example code this underscore ID thing pops up so I just wanted to explain it beforehand. So underscore ID is this special key that's present in all documents in MongoDB. It's unique across collections. You can either use your own underscore ID so if you have some unique key you can use it as underscore ID or the driver will insert one for you. So to sort of go over how queries look and how the API looks we're going to do a simple sort of blog back end. So I'm just going to show you how you could represent posts and how you might do some queries that you would use to implement a blog. So here's a simple post. You can see it's just a hash and we can take advantage of some, you know, Ruby data types like a time instance and that will automatically be converted to a BSON date. We can put arrays there. We can embed documents even which we don't do in this example. And here's a comment. So the comment is again very similar just an author, date and text. So to create a new post basically what we do is we take this post hash and we just save it in the post collection. So this DB post thing is the post collection and when we save this it's going to automatically insert it and add that underscore ID thing so this is a little bit more of a complex example. So here what we're going to do is we're going to take our comment and we're going to embed it directly into that post document. So this is what I talked about way at the beginning. Now we can avoid doing any joins by getting our post and getting all the comments with it. So in a relational database you'd probably have a separate comments table and a separate post table in this example. And so one way to do this would be we could go get our post from the database. We could insert the comment into our comments array and then we could save the post back and that would work fine but one cool thing about MongoDB is that there's a bunch of these sort of atomic update operators. So here what we're going to do instead of doing that sort of two round trips we're going to just send an update message and we're going to update the document where underscore ID is the underscore ID of that post we just inserted. So that first hash is sort of selecting which documents we want to update and then the second hash tells us what the update is going to look like. So the update is going to be a push of this comment C into the comments array and that will automatically append the comment to the array or insert or create a new array if it doesn't already exist. Collection identifier. The question is post to collection identifier. Yes, so this post thing is the name of the collection. So then we can do some queries on that. So here we're going to find all the posts where the author is Mike. So basically the way the queries work in Mongo is that you give it a hash that shows you sort of what you want your resulting documents to look like. So this is pretty similar to how queries work in SQL, say. So here we're just going to do a find where author is Mike. We can also do some more advanced queries. So here we're going to do a sort ordered by date descending and limit it to 10 results. So this is an easy way to get the last 10 posts. And since you can have indexes and stuff, you can make queries like this efficient, range queries like this efficient. So here is another example of sort of a more complex query. So just like we had this dollar sign push operator for doing updates, we also have some dollar sign operators for doing queries. So here we're going to do a query to find where posts where the date is greater than this date that I constructed for last week. So we use this dollar sign GT operator to say greater than. There's a couple other operators, too, which I'll show a partial list of in a bit, but if you want to know what all the possible operators are, you should probably just hit the docks online. We can also do regular expression queries. So if we just say we're text and we give text as a regular expression, that will automatically get encoded to BSON and sent across in the database knows how to understand it. So here we're going to find the post to end in Ruby. If we were doing a prefixed regular expression, it would actually use an index, too. So that's sort of cool. I mean, it's not general purpose, but for some types of regular expressions, we can use an index. So here we're going to find tag, a post with a specific tag. And if you remember that tags feel was an array. So here was MongoDB in Ruby and if we just search for where tags is MongoDB, that's going to reach inside that array and look at every element in the array and find the posts that contain MongoDB in that tags array. And sort of a cool feature is that if we create an index on tags, it's actually going to index that document on each element in the array. So we call this multi keys. And basically it lets you do, obviously it's perfect for tagging, but you can sort of fake a little bit of full text search stuff by doing this multi keys thing. And that's how some like blogs that are running on MongoDB now, that's how they do their searches using this multi keys feature. So there's counts. You can count all the posts in a collection in the first line. You can also count posts that match a certain query. Here's basic paging. So we have limit and skip. So you can visualize and skip over end pages of results. So here's an interesting example. This is what I was talking about, how migrations become trivial. So here if we decide, you know, we've got this blog running for a couple weeks. We've got a ton of posts in it. And we realize, hey, it would be nice if we had like a title for all these posts in here. So we decide to add a title field to our post documents. And basically it's as trivial as just starting to add new posts with a title field. So your old posts, when you get them from the database, won't have that title field. And you handle that case in your application code. And your new posts do. And so the nice thing about that is that let's say you roll out this new version of your application that starts adding titles. And you realize something's broken and you need to roll back. So not only was the migration, forward migration trivial, but you can also, if your application code is implemented you can also roll back your application code and continue to use these new documents that were inserted and just ignore the title key. And your old code will still work perfectly fine without doing any sort of schema migration or anything like that. So again, it's not fully general-purpose migration proof. If you need to do some, you know, complex transformations and things like that you can get yourself in a situation where you need to run some form of migration. But in the general case we found that you can avoid a lot of that stuff because it's schema free. So this is just a list of some of the more advanced query operators. So we have all sorts of different inequality operators, greater than, less than, greater than or equal to, not equal to. We also have some that operate on lists so you can say, I want only an array that contains all of the elements in this array that I'm giving you. In and not in are sort of cool too. That's basically a way that you can fake or. So if you have two authors and you want to get all the posts by either author, you can pass an array of authors and say in this array. So you could say give me all the posts where author is in Mike or Elliott, for example. Where? So this is another sort of interesting thing about MongoDB is that it's got sort of tight integration with JavaScript. So there's a JavaScript interpreter embedded in the database and you can run arbitrary JavaScript expressions as queries. So here we're going to do a where clause and we give it this JavaScript string and basically this is going to get evaluated against each document and only return the documents where it's true. So the downside of where is that you can't take advantage of indexes because basically the database has no way of knowing what your random JavaScript function is going to be doing. But it can be very useful if you're able to sort of use some of these normal filters and then sort of tack on a where in addition. So you could use post where author is Mike and that will take advantage of an index on author and then you can use a where clause in addition to sort of filter that down at a more fine-grained level. And so that's very cool and there's also JavaScript appears in several other places. So we have this eval thing where you can basically run arbitrary JavaScript that's not even a query on the database and we also have a JavaScript shell which I'll talk a little bit about later but that's very cool for doing sort of administrative stuff and just playing around with the database on your machine. So in the Ruby world there's some more interesting things to look at which is a variety of sort of higher level projects that have been implemented on top of this driver that I've been talking about to give you things like validations and models and that sort of stuff that you might be used to. So three of the projects that might be worth a look are Mongo Mapper, Mongoid and Mongo Record. So this is an example of Mongo Mapper and you can see that you have things like validations and associations and models and that sort of stuff. So I would actually recommend that if you guys are playing with this for your own applications start out using the Ruby driver directly. A lot of people have found that once you get used to that API it might not be totally familiar to you coming from Active Record or Datamapper or whatever else but once you get used to that API it can be pretty nice and lightweight and if you decide that you need validations and you need this stuff that these are providing then you'll only be a leg ahead because you'll know what they're doing underneath and you'll be able to sort of jump down to that lower level if you need to. So that's my recommendation but these are cool projects too. Other cool stuff to look at if you're playing with MongoDB are aggregations. So there's sort of some built in aggregation basically sort of like a group by and also MapReduce. So in the most sort of most recent development versions we have MapReduce support. This is different from the MapReduce that you might expect that you hear about with CouchDB. So with CouchDB again MapReduce is sort of treated as custom index building. Here it's more like a little bit more traditional MapReduce and it's basically used for things like aggregation. So the nice thing about MapReduce is that it also works in sharded setups. So you can do some complex aggregation that way. Cap collection. So cap collections are a really cool feature. Basically you can create a new collection and say I want to limit it to 50 gigs or to 50,000 documents and what will happen is that as you insert data once you hit that limit it will just wrap around and start overwriting the first data that you inserted. So this is really cool for implementing things like logs that have an integer and we use it actually internally for replication. We store operations in an op log. That's a cap collection. But that's a cool feature for a lot of use cases. Unique indexes. So the index on underscore ID that I told you about is unique but you can also create general unique indexes if you know that this is a constraint that you want to apply when you're creating an index. If you try to insert a duplicate key the Mongo shell like I talked about is this JavaScript shell that comes with the distribution and it's really nice to be able to sort of programmatically interact with the database and it's real quick to start up go through the tutorial using that but also later on to do administrative stuff. So like I said I do a lot of work on driver development and there's a lot of time throughout the day that I fire up the shell to do some quick queries see what's in the database writing a script to do the same thing. In GridFest GridFest is another cool thing that's sort of worth a look. Basically what it is is a specification for storing large binary data within MongoDB. So what we do is we sort of the Bison thing supports storing binary data but documents are limited to a size of about four megabytes total. So with GridFest basically we chunk up your binary data into several documents using a spec that we've come up with and the nice thing about doing it that way is that then there's a whole host of drivers and tools that know how to interact with this data stored in this spec. And cool things about GridFest are that if you store files in GridFest and you've already got replication setup for your database or sharding setup for your database you can sort of leverage that for your file storage as well. So that's worth a look as well. So if people don't have questions now we've got a couple minutes left so I can dive in a little bit on sharding and tell you a little bit about how that works. So sharding is sort of our path to infinite scalability and basically what it does is split up your data across several different nodes. So replication we treat as a path to failover so there you're replicating the same exact data across nodes whereas sharding you're storing the same data on different nodes in order to scale out. And so before we get too deep into it I'll introduce some terminology that we use and it can be a little bit confusing when you read a bunch of papers about this stuff because people use these terms in a lot of different ways and we're just as guilty of that as everybody else but this is how I'm using them for the rest of this talk. So a shard key is basically a single key in your document that you're going to split up chunks by. So in the example of the blog post maybe we'll split up our documents by date so we would set our shard key as date and so then all of the documents in that collection are going to be split up into ranges based on their date and those ranges are called chunks so you can think of a chunk basically as just a range of the value space for a single key in a collection. So a chunk could be represented by a tuple that looks like collection name shard key minimum value and maximum value for that chunk so basically every chunk your entire collection is going to get split up into these chunks. If it's a small collection maybe to start with you only have a single chunk and what auto-sharding does is take care of splitting up those chunks of data and distribute them to different shards. So a shard is a single node or several nodes here it says replica pair but the model going forward is that you're going to be able to have sort of n nodes per shard but basically every node in a shard is going to be responsible for a set of these chunks of data. So given some value it's going to live in a single chunk some value for a key in your collection it's going to live in a single chunk and that chunk is going to live in a single shard which could be multiple machines and probably should be multiple machines for failure or sake. So to sort of diagram this out because that doesn't help too much this is the way it looks in terms of like a process diagram. So we have a single client and it's talking to this process called Mongo S. The S stands for shard and Mongo S is basically a lightweight database router it's pretty stateless and it basically gives you the same API that you're used to working with when you're talking to a single node or to a replica pair or whatever. So the client code doesn't have to really change it all to use sharding. And what Mongo S does is it handles when it gets a query it knows which shards might contain that query and it handles routing out your query to all the different shards that might have results for you and basically it's sort of like a merge sort engine as well. So if you're doing a range query Mongo S can send out the query and then merge back in the results. And so this is where it becomes important what your choice of shard key is. So if you choose your shard key as the date and then you do a query on date that's going to be really fast because Mongo S knows where that chunk lives and it can route your query to a single shard get the result and give it back to you. If you choose your shard key as date and you do a query on author without including date at all Mongo S has no idea where the documents with matching authors might be. So it's going to have to route that query to every single shard and merge back in the results. And you can imagine there's all sorts of different combinations of how many, depending on your query how many shards might have to be involved. So the key when you're when you're setting up sharding is choosing a shard key that's appropriate to the types of queries that you're doing. Such that Mongo S doesn't have to distribute your query across you know tons of nodes just to return your result. And for, you know, smaller setups, four or five shards it might be fine to do a couple of these distributed queries. But for larger setups thousands of nodes obviously that's going to be a huge performance bottleneck. Yeah. Let's say two, three sets of referee clubs that has different shard keys and Mongo S can decide which shard key to use. The question was could you have different replicas that are sharded on different keys and let Mongo S decide which shard key to use. So that's a good point. So basically you can think of the sharding as like a distributed index. Just like you have indexes on each of these individual nodes, you have sort of this distributed index in Mongo S nodes where that data might live. The answer is that I don't think we're planning to do anything like that currently. I mean there's no reason you couldn't do it yourself in your application code. You could have multiple collections each of which is sharded on a different key and insert into both of those collections manually, which is pretty much what this would have to do at least the way the setup works right now. So yeah, so again, Mongo S can talk to any of these different shards, each of which could be multiple nodes so that you have failover on that level. But the cool thing is that, like I said, Mongo S is pretty much completely stateless. So it's not like this single point of failure down here. You can have multiple Mongo S's as well. So you can talk to any of these Mongo S's and any of them know how to route your results or how to route your queries appropriately. So there's really no problem if one of those Mongo S's failed. You can just go talk to another one. And another cool thing about that is that there's lots of ways you could actually set this up in terms of physical hardware. So one setup that we think is interesting and that we definitely want to experiment with is having a Mongo S per app server basically. So if Mongo S lives on the same machine as your application code, then all that communication is going over local hosts and it's only these remote hops that are actually going out on the wider network. So the question now is if all these Mongo S's are completely stateless, where is sort of this configuration information stored? And that's where these config servers come in. So these are basically like a special separate set of Mongo D instances that store configuration information and that information is basically a mapping from those chunks that I talked about to shards that own those chunks. So you can think of the data in these config servers as just a list of chunks with a shard identifier saying which shard has them. And the thing about these is that all of the basically metadata changes that go on here are done using two phase commit. So this is actually like synchronous replication just for this config server part, whereas a lot of the rest of the stuff that goes on in MongoDB is all asynchronous replication. And so sort of to give you an idea of how failover works here. So like I said, any of these Mongo S's can fail and you can just talk to another one and that's fine. Shards any single one of those Mongo D's can fail in this setup because we have a replica pair and then we can just talk to the other one and that's fine. If all of the nodes representing a shard fail then we lose access to those chunks that that was responsible for until we bring one of those back up. And config servers are sort of special because we need those to know where things live. And so the way it works is that if a config server is down we can't do any metadata changes until we get that config server back up. So we can continue to do queries, we can continue to insert data, but we just can't change where a chunk lives. So what happens is that as a chunk fills up there are two operations we perform. We perform a split which basically divides the chunk into two chunks and we perform a migrate which can move the chunk to a new shard. And that's how we achieve load balancing basically. And so if a config server is down we won't perform either splits or migrates. And that's so that we make sure that we have a consistent view of what lives where across the whole system. And that's not actually too big of a problem because if you imagine a production system that's been up for a while the chunks in these shards are going to be pretty well balanced already. So going a couple hours without doing any of these sort of rebalancing operations is not too big of a deal. And so yeah, so MongoAS basically just caches that information that lives in the config servers. Okay, so what I would like for all of you guys to do who are in the audience if you haven't done it already is download MongoDB. It's really easy to install. It takes like two minutes to download. We have binaries for all these different platforms so nothing stopping you there and try it out. So try it out from the shell install the Ruby driver it's on, gem cutter play with that and let us know what you think. So write a blog post put something on Twitter, email us whatever. We really just want to sort of continue to build a strong community. There's already a pretty strong community, especially in Ruby but that's sort of the goal so please do that. And the website is MongoDB.org. We're on IRC all the time. We have a Google group. This is what we use for basically most of the interaction in terms of within the developers but also what users happens on that list. We're on Twitter. I'm on Twitter if you want to ping me directly. That's my personal email if you want to ping me directly as well and this slideshow will be up there at some point. It's not up there right now but next couple of days. Questions? You mentioned using this for sessions. Is that something that you've actually implemented? Yeah, so I've used it for sessions in one small app that I've written that isn't really deployed anywhere but people are using this for sessions and there are some there are some nice wrappers that people have written around other session libraries that will basically persist the data in MongoDB. I can't remember at the moment if there have been any of those written for Ruby sort of hard to keep track of all these third party packages that are going on but that's definitely a great use case for it. Yeah. Is there any way to query embedded documents? Yeah, so the question is is there any way to query against embedded documents and I probably should have had a slide on that but yeah, there is. Not only can you query against them but you can also build indexes on embedded documents. So the cool thing about this BSON format is that the database knows basically completely understands the format so the database is sort of able to reach into your documents and get at sub documents and all that sort of stuff. Posts.comments or comments.author in that example and then we have an index on the authors within those comments and you can do the same thing with queries. You could query on comments.author or comments.date. Yeah. And the scalability is one of those selling points. How big? Okay, so the question is how big are the current deployments? So we maintain a list of production deployments that we know about and that's on the website. If you go to modernity.org and you do a quick search for production deployments in terms of absolute size so this sharding thing is actually under really active development right now so I don't know of anybody using this on a large site in production right now the sharding layer. Everything else, the replication, the core server all the querying, all the index building that's all very stable. That's been used in production for like two years now. So one of the bigger sites that's using this right now is Sourceforge. I think their setup is that they have not too much data on the order of say two terabytes of data and they've got it in a replicated setup so they've got a single master and maybe six or seven read-only slaves so they do all writes to the master it's like most web applications it's very read heavy they do all writes to the master and all reads distributed across these slaves and I think the way they're using it is they store basically a document for each project on Sourceforge and so when you hit a project page on Sourceforge it's pulling a document out of MongoDB, again no memcache or anything like that and basically all the information for that project is in those documents so I think about 90% of Sourceforge traffic hits MongoDB now at some point. Yeah, in the back. I was interested is replication always like a pull replication or can you support parity and that sort of thing? So the question was is replication always pull or do we support parity and that sort of stuff so right now replication is basically completely asynchronous pull only this is something that we're actually actively thinking about especially in terms of the way sharding works is possible different setups but right now the thing that's production ready and really the only thing that's in active development is pull only. So it uses basically an adaptive mechanism so when you do a pull the master keeps a log of operations that is performed in a cap collection and the slave every couple of seconds to start with does a pull and gets all the operations that have been performed since its last pull and applies those but then the way it works now is we use sort of an adaptive timing so if the slave pulls and a ton of operations have been performed it will stop pulling a little more frequently and if the slave pulls and nothing has been performed it will stop pulling so frequently so it's sort of adaptive but yeah it's totally asynchronous Yeah Does it cache any parts of the database in memory or does it keep it all on disk or how does that work? The question was does it cache any parts of the database in memory does it keep it all on disk, how does it work? The answer is that basically all of the files so we sort of let the OS handle it everything in the database lives in memory map files indexes all the data and the OS is responsible for when that gets paged out so this is why we can maintain the performance of close to things like memcached because if all of your data is resident in memory then basically what you're doing is memcached with some nice query mechanisms on top of it so one thing that we're working on right now which I think might be in the latest latest tip is an operation to perform a guaranteed full f-sync and then lock the database so this is very useful for things like Amazon EBS you could do a full f-sync, lock the database, take an EBS snapshot and then come right back up within the matter of half a second or something like that so that's something we're working about on disk durability there hasn't been too much of a focus in terms of traditional acid durability and the reason why is because that we're really treating replication as our path to failover so the idea is get it on a replica somewhere and if you get it on enough replicas it'll get to disk yeah the question was why not use something like a distributed hash table to store configuration information for the sharding it's something again this is something we're thinking about doing so the sharding layer is really an active development right now we're hoping to have a beta out for sharding by the end of the year so again the production stuff, the really stable stuff is the non-sharded stuff but things like zookeeper other distributed hash table type things are definitely an interesting approach to storing that configuration information so it's something we're thinking about to own our own stuff for that Is there any plans to have a hotspot to be able to tell his peers when we have to take the shard off the question is basically how does load balance work in the sharding setup the answer is it has to be the only sane way to do it is to use some combination of data size as well as load in terms of queries per second or whatever so that's how it's going to work in terms of rebalancing if one shard is getting totally hammered that's a huge signal that we need to rebalance some of that data the exact mechanics of how we decide when and what to rebalance is still a little bit up in the air the model that's implemented now is pretty simplistic anything else I have some longer to be stickers if people want some of those come grab me also if you have more questions you want to ask me in person please pull me aside thanks