 All right, it's getting to be about that time, so I guess we'll start. My name is Josiah Carlson, and today I'll be presenting on Redis. With a talk I call Redis for Everyone. This is sort of derived from a previous talk that I did in the past for a Python meet-up down in Santa Monica, but you'll get a bunch of new content, just a few small things that are similar. So if you've already seen one of my talks on Redis on YouTube, well, it'll be like that only different. So yeah, so my name is Josiah Carlson. If you like what I say or you're interested in seeing what I have to say in the future, feel free to follow me on Twitter at Dr. Josiah, or check out my blog, Dr. Josiah at blogspot.com. And if you really decide you like what I'm saying about Redis, you can buy my book. We'll get to it via the big B-link, Redis in action. And by the way, chapter, up to chapter seven is available now, and if you wait until the beginning of next month, you can buy up to chapter nine. Just got edits back on that, and it will definitely be available beginning of next month. So Redis for Everyone. Today some topics that I'm going to cover include who I am, sorry, followed by what is Redis, and then some examples of Redis being used in production, then move on to some very good use cases for Redis, things that are quintessential Redis applications, followed by some perhaps not so good use cases for Redis, of which there are many, but I'll only describe a few. Followed by some benefits to your organization, if you are on the business side of things. Speaking of which, how many of you are on the business side? Raise your hands. Okay. Engineering? All right. Engineering. That's it. Business is important. It's hugely important, and I've got a section just for you to convince your organization to use Redis. All right. So moving on. So who am I? Well, I've been a contributor to some open source software for about nine plus years. Start out with some of my own projects, then for three or four years, I participated heavily in Python Dev, which is the development of the Python language. I spent a lot of time bike shedding, and if you posted to the Python Dev mailing list for one of those three or four years, I probably replied to you at some point. I was, yeah, kind of a tyrant in there. I've since grown up and care much less about things. Anyways, so I've also worked at some high tech firms, Networks in Motion, then Google YouTube, and a little company called Adley. Now I'm at a company called Chownow. We do online takeout and delivery ordering. But a lot of, at least my start with Redis started at a company called Adley where we built a variety of things, which I'll actually talk a little bit about today. I'm also a very heavy user of Redis. In particular, I built an ad targeting network based just on Redis. I built a Twitter analytics platform, search engines, various caches, queues, and whatnot. And part of those experiences went to source material for my book, Redis in Action, which is being published by Manning Publications, who is also a sponsor of this conference. If you are looking for solutions to problems that you have or problems that maybe you didn't know you have or ways to improve your existing systems, you owe it to yourself to at least read the table of contents, which is available for free, and even maybe even give the first free chat for a shot. If you feel like the book is too expensive, let me know, follow me, and say, hey, the book is too expensive at 25 bucks, and I'll find a deal. So yeah, let's continue on. What is Redis? Well, Redis is an in-memory key structured database. And what I mean by that is that rather than mapping to a single type of value, which is the case for a variety of databases, Redis actually maps to one of five different types of data structures. And it also has support for a system known as publish, subscribe. The particular structures include strings, lists, sets, hashes, and sorted sets, which are also known as these sets. These structures are really what makes Redis unique in the NoSQL world. So far, I've not seen anything even come close. You can kind of sort of get something similar if you think about it in the wrong way with MongoDB, but it's completely different. So yeah, Redis also supports server-side scripting, sort of like stored procedure with Lua and Redis 2.6. 2.6 is in a release candidate six and is getting better every day, which is to say, they've established that there are no big bugs that would stop its release. Occasionally, you get new features coming in. And actually, I need to add more content to my book because new features have been added since I started writing it and the chapter where I even talk about some commands. So Redis has persistence via snapshotting or a pend-only file. So when you restart your Redis instance, you can actually get data back. This is far cry from, say, Memcache D, where you restart your Memcache and you lose everything because it's a cache as opposed to a database or data store. Redis also supports replication via master-slave replication, which means that you can, and because a slave can also be a master, you can set up slave chains or slave trees, and you can do multi-data center replication with it. There is a sort of clustering that is full on master-master clustering with failover and make sure to write out to two, three, four replicas, whatever that is in progress. It is not done yet. It's been somewhat delayed because certain components have not been finished yet, among which include a high availability and automated failure, failover daemon, which is actually being released independently of Redis 2.6 and Redis Cluster. And right now, this Redis Sentinel is actually available today. And it's in somewhat beta form. But even today, it is the best failover and health check of systems available. There are other systems that offer sort of monitoring to see what kind of commands you're running, but those tend to slow down your Redis, because they actually monitor every command coming in. And yeah, most languages can't keep up with Redis. Turns out that if you're actually using it. So let's get into some of the structures and what they're supporting. So we start out with strings. Strings are actually not just plain character strings. And you can certainly use character strings. But strings also can represent long integers, your platform long integers. So you get 32-bit on 32-bit platforms and 64-bit on 64-bit platforms. These are signed integers. And if you try to increment over the maximum integer, positive integer, or decrement below the negative integer limit, it will actually give you a warning. And it will say, hey, sorry, we're not going to do this because this would go over. So you don't get any of that overflow or underflow issue. It also has support for atriplea 764 floating point doubles on platforms that support it. It also offers things like incrementing by one or incrementing by whatever you want. And on the floating point side of things, you can increment by arbitrary values as well. There's also lists. Now lists are actually doubly linked lists of character strings. Now internally, it turns out that if your character string is actually a base 10 integer, it will actually store them more concisely. And if you have short lists, it will actually store them in a packed format, so you don't have to spend all that extra overhead for all of the links in a linked list structure. Those are nice convenient optimizations to reduce memory use. RITUS also has sets. And by sets, I mean they're really hash tables without values. And they're generally a character string or long ant members. Within sets, you get support for all the nice set math operations, intersections, unions, and differences. For short sets where they're all long ant members, then you can actually store them as an array as opposed to a hash, which gives you better memory use and similar performance characteristics. Speaking of hashes, RITUS also has support for hashes, which are generally hashes of character string to character string, long ant, or double values. In a lot of ways, you can see them as kind of a smaller namespace version of the higher level RITUS, although RITUS does not support any sort of recursive structures. And that's probably for the sake of, shall we say, command set limitations. Right now RITUS has somewhere over 100 commands. And if you started adding support for nested structures, that would totally go even more. Although you can, if you want, you can twist your head around and you can build a sort of nested structure with namespaces with the keys. RITUS also has supports for things called sorted sets, which are really a combination of a hash and a skip list that maps to character members and double scores. And Z sets are actually ordered by score. So you can reference things by their member name, or you can access them by the order of the member score sorted by scores. Now, if you're looking to build a sort of sorted index, this is what you would use. And with a combination of these structures and combined with sorted sets, you can actually build somewhere on the order of 75% to 90% of the functionality of relational databases and indexing and even joins if you twist your head around it enough, although I wouldn't do that last step. There are certain types of mental twists that you have to do which are just a bad idea. And maybe I'll get into that if I have time. So, oh, did I miss something? Oh, and RITUS also has support for publish and subscribe. Publish and subscribe, if you're familiar or not familiar with it, is this concept where people who want to receive or listen to events subscribe to a channel. RITUS has support for basic stream channels, you can subscribe to multiples, or you can subscribe to wildcard channels. And anyone who publishes on any one of those channels sends a message to everyone who is subscribing on those channels. So in a lot of ways it's like a radio station. You tune yourself to a radio station or a dozen radio stations or thousands, and anyone who sends a message out will be transmitted. If you're not connected at that particular point in time, then you don't receive it. So there's no store in forward. If you're there, you get it. If you're not there, sorry, you missed it. RITUS also has support for a sort of optimistic locking and transactions. What I mean by that is you can watch certain data for modifications. You can fetch data that you've watched or even data that you've not watched. And then you can start to write data with a command called multi, and you send a bunch of commands. But those commands are not executed until you send the exec command. Now once you execute the exec command, if any of the data that you were watching has changed at all, the entire transaction is aborted and you receive an error. Now you can keep retrying this until you succeed, or you can just say, well, no, I don't want to do it anymore. It's your choice. You can actually abort at just about any time with unwatch and discard between the watch multi and multi exec steps. Now this is not like a real transaction like you're used to in perhaps SQL in that there is no real concurrent write. You can't be updating the same rows. You can't say row with ID 7 with column, the value column, we want to increment it by 1. You can't do this at the same time in RITUS. There isn't that sort of protection. But if you are using the append-only file persistence and your operation will be executed, RITUS appends the entire transaction to disk. So you see everywhere from the watch to the exec, you get to disk. And so if it has to replay that because, say, your server crashed, it will execute to completion. RITUS has server-side scripting with Lua. It's via three commands. Eval evaluates a string that represents a Lua script. Eval SHA executes the SHA. So when you execute a script, it is SHA1 hashed on the server and is stored and cached. You can execute that directly with the val SHA where you can load a script without executing it with script load. And this is primarily just to reduce transfer back and forth and maybe to save the server from having to perform a SHA1 hash on every script that has passed. Generally, it supports just about all of the full RITUS functionality. The exception being when cluster comes out, you won't be able to write two keys that are not on the particular instance that your script is running. And in many ways, it can simplify your problems. One of the chapters in my book, I spend about 15 pages building a proper and correct lock with timeouts and a few other features. And I try to be very rigorous and prove that, hey, this is totally correct. With scripting with Lua, that turns into about a five-line Lua script and it's pretty obvious that it's correct. You don't need to spend a lot of time proving it. So this can completely change it. And it has been available in some form. There was a scripting branch of RITUS 2.4 that is available. Although that was unsupported, 2.6 will support completely. RITUS also has support for client-side sharding, which is to say, clients need to support it. The server doesn't really care about it, although with clustering, there will be server-side notifications of, hey, long shard. There's writing data that should not exist on this shard. So RITUS in production. Now, let me explain a little bit about this particular section. I'm going to go through a few problems. And the basic idea about these problems are these are things that I ran into personally and had either an existing solution or needed to create a solution for it. And we ended up choosing RITUS for this. And so these are some of the results that we received after the fact. After we implemented it, ran it in production. So this first example, we had 100,000 user profiles. These were user profiles about Twitter users and their followers and the demographics of their followers and a variety of things like that. And we needed to filter in a search over 10 attributes. And we also needed a full text search. At the time, we were using Postgres and we were using Postgres 8.1, and it was a great database, but didn't have access to full text search at the time. And we didn't want to go and add Lucene. And we had just heard about this platform called RITUS. And at the time, we had been building a SQL query composed via ORM, and we looked at the SQL queries and they were all pretty reasonable. We had many of the right indexes, but just from the data volume, and I think we were running it on an instance that was too small or wasn't big enough, or maybe we didn't have all the right indexes, but basically we were getting three to six seconds per query. And that was without a full text search. And it was primarily because we were looking for, you know, kind of a half full text search with like in the wild cards and, you know, you got to do table scan on that, and that's going to be awful. Well, after we learned about RITUS, and after I was told, hey, you know, give it a shot, maybe you can do it, you know, you've got experience with search, maybe you can apply this to RITUS. Well, it turns out that RITUS has all the structures necessary to build a search engine. And so it was my first RITUS project. It took two to three weeks to pull public rule out, and we reduced the query times to 50 milliseconds. This is a full search engine over 100,000 user profiles. Now, it's not very much. We later scaled it to over a million and didn't see an appreciable increase in the search times. We also updated our index via ORM post commit hooks, so our data was always up to date in real time. We added locking around it to make sure that we weren't trying to update the same items at the same time, and we were very, very happy with it. We're so happy with it. In fact, that system is still running even after I left the company, which is a great testament to the quality of the software. I don't know. Personally, I've seen a lot of my projects mothballed after I leave. I don't know if it's just me. I hope it's not just me. Later, we refactored this entire system into a general index search, and we built this across our entire database, which offered search for addresses, customers, clients of all different shapes sizes, and all of that is still being used. Our second problem, we needed to create a content targeted ad network. That network needed to be location sensitive. At the time, we were showing in Twitter clients and Facebook clients and MySpace clients, and it was supposed to be AdSense for the stream. Again, because we had such great experience, we continued moving on. This is actually my second major project in Redis. We got about one month to proof of concept, and by proof of concept, I mean we supported learning, second-price auctions, adjustment of prices over time, automatic rescheduling for budget refreshes, all that stuff. Anything that you would expect of an ad network, we built it in about a month, or I built it in about a month. I'm a decent developer. I am not top 1%, at least I don't believe so. At least I hope not, because I would say a lot about the top 1%. But in one month, we built a proof of concept, and I took a two-week vacation, came back and productionized it in another two weeks, and we spent time continuously tweaking because it's an ad network. It was serving ads, returning content, location, and even categorized targeting for in about, well, we had a deadline of under 200 milliseconds, and we were consistently doing better than 100 milliseconds. That included everything from parsing the tweets, performing the query, targeting the ads, doing all the learning stuff that we were supposed to do, and we always beat 200 milliseconds. For a while, it was being used inside of a Twitter client called Uber Twitter on Blackberry, and a few other Twitter clients whose names that I forgot. Ultimately, it was shut down because they couldn't make a business reason to keep it up. Turns out that running an ad network is difficult. Difficult to find money and difficult to find people to show the ads. That's what happens in business. So, problem three. We needed to build a Twitter analytics engine. We needed to track things like follower count over time, gender and demographics information for followers, and a calculation known as follower overlap. The follower overlap calculation we ended up pulling out because we could do it about a thousand times faster than we could do in Redis. I've actually got a blog post about it if you want to read it. So, using Redis to build this and to build a spider over Twitter, we got a basic engine up in two weeks. This basic engine up in two weeks actually replaced $4,000 a month cost that we had been spending on a third party to give us the same data and actually significantly less data. We built in more functionality every week. We had things like gender and location information for 85% of all users on Twitter with 90 to 95% precision. We had a sample set of about 50,000 and we did double blind testing. That was kind of awful to do. Thank you, Amazon Mechanical Turk. We also had full follower less for everyone with over 1,000 followers, which was over 100,000 as of August last year. Inside Redis we did cues, aggregates, and we performed a variety of memory optimizations, of which my most recent chapter, chapter nine, which will be available next month, is all about memory optimization. So if you feel like, hey, I totally want to use Redis, I built it the naive way, and my memory is huge. How can I fix that? Read my chapter. We're asking a question on the mailing list. I answered as many questions as I possibly can there, and that's actually how I got my book deal. So, some good use cases for Redis. There are many of them. I will try to go through these kind of sort of fast, but I'll pause on a few of them, because a few of them need some explanation. Firstly, analytics. Now, if you're used to analytics in other engines, maybe you're just spewing your logs to disk, and maybe you perform a map reuse after the fact. That's great. With Redis, you do it in real time. I can know the number of unique visitors on the website in real time. I don't have to wait a minute or two minutes or whatever the Google Analytics gives me. I can find it out today, right now, within a second. And there's no reason why you can't either. You can write roughly 100,000 to 400,000 objects per second to Redis. One Redis on one Core 2 Duo 2.6 gigahertz can do that. If you run two, you just double-deer performance. If you run one on every single one of your boxes, you can now perform any kind of analytics you want and roll them up to a central server. It's very fast, and there's no reason why you can't have all of the analytics you want right now, today. Task queues. With lists, lists can block and pop, which means you've now got your task clients not polling. They're just waiting on stuff. You can do scheduled things with Z-Sets, and I've actually got a package that I've written called RPQ, which is available in Python, which lets you perform all these task queue operations in Redis. There are about a dozen other libraries that also use Redis for task queues. You can use it for distributed locks, and what do I mean by distributed locks? I mean that you can have 100 machines acquiring a lock so that they're not writing over the same data. Redis works as well as any other system, but because it's all in memory and not on disk, you're not waiting for somebody to log a file on disk. You're not waiting for an operating system level mutex. You're not worrying about those perhaps more expensive options. Redis is also great for caching. You can set max memory limits. You can set expiration times. You can have your cache invalidate based on just the volatile stuff or all of your keys. It's great. It's also more or less as fast as memcache D, depending on how you're measuring it. If you're using UDP on memcache D, I think you can get a little bit better, but for all intents and purposes it's functionally the same. There's only so fast you can go with async sockets and network communications. Redis is also great for data that expires. You can give a specific expiration time and it won't be available after that time. Redis is great for cookie storage. Let me explain that. I'm going to go a little bit more in depth. Most situations where you have cookies on the web, you've got one of two different kinds of cookies. Either you've got some sort of opaque token that leads to data on your servers, or you are encrypting or assigning your data that you store on the client. If you're encrypting or assigning data on the client, it's broken. You're probably not a cryptographer. I'm not a cryptographer, but I can prove that the stuff that I do is correct because of my education. I'm a doctor, I removed that from the talk because I didn't want to seem pretentious. I'm a theoretical computer scientist and I can prove my stuff, but I don't do it on the client because I also make mistakes. If you're relying on a library to store your encrypted or your signed cookies on the client, I can just about guarantee that they're not cryptographers either. You can avoid all of this crap by just storing a random string on the client that maps the data on your server. By storing all of your data on the server, you can control things like cookie expiration. You can store things like first-time visit, last-time visit. When they visited every single time, you can do durations for every single time they visited. You can store this in a data store that has no problems supporting hundreds of thousands of users every second. In fact, with Redis, you can basically support cookies if you've got a big enough instance for a site like Amazon.com without significant difficulty on a single machine with a single instance. That's just my assumption. My assumption is that they're seeing less than 100,000 views every single second, or at least less than 100,000 cookie updates a second. I could be wrong, but other sites are not seeing more than that. So, yeah. So, stop doing cryptography, please. Redis is also great for search engines. I've built them. I've got an entire chapter on them. It's perhaps not going to scale to the point of Solar or Lucene or some more directed search applications. But if you just need to search over your database entities, you can. And I've built search engines that have searched over 100 million items. And 100 million items search index over tweets. And perform great. We can do full-text search. We can do all that fun stuff that you would expect of a full-text search engine. You can also do ad targeting. I mentioned it earlier. In that chapter on search I just mentioned, I actually build about 75% of what you need to actually have an ad targeted, an ad targeting engine inside of Redis. And so, that's free money for you. You can download that. You can buy the book. And you can make money. If you make a lot of money, maybe buy a few books. Throw a little bit back my way. You can also build forums. Generally speaking, most forums do not use a lot of memory. If you are Reddit, don't use Redis for your forums. Probably not hosting Reddit. If you've got your corporate forums, your internal forums, maybe even you have Twitter. Or some internal social networking site. Speaking of which, chapter 8 is building a social networking site like Twitter inside of Redis. But you can build forums. You can sort in a variety of different ways whether you store your tweet data in Redis or maybe you store all of your indexes in Redis and you store your tweet data or your forum posts data somewhere else. Either way, forums are a great use case. You can also use messaging. Either point to point messaging, single recipient, either with public subscribe or you can use lists for kind of a mailbox type scenario. Inside the Twitter chapter, you could actually use Twitter-style messaging for broadcasting out like that. And I've also got a section in a chapter talking about how you can create little group conversations and let people come in and out and make sure that everyone receives the message and store them. Redis is also great for high IO workloads. As I mentioned, anywhere from 100 to 400,000 writes a second on a four-year-old box. Redis is great for small data. If you're just storing a few hundred mags, maybe in a few gigabytes, Redis is great. It will sync to disk in about five to six seconds if you want to do snapshot-style things or if you are using append only files and you sync every second. Unless you're writing very large keys, you're sending huge volumes of data. If you've got a lot of very small writes, Redis will be very fast for that. I've personally not experienced any sort of slowdown and if we have time, I'll actually run the Redis benchmark for you to show you the performance and that machine is running on a four-year-old hardware. It's got a 80-gig spinning disk in it, 2.6 gigahertz Core 2, not a big machine by any stretch of the imagination and it performs great. Also, it's great for bigger data. I don't want to say big data with a different perception of what big data is. Some people have the feeling that, hey, if you're storing 10 gigabytes in memory, that's big data. It's a subjective thing. I know some people who are storing hundreds of terabytes of memory, hundreds of terabytes of data in memory. So, relatively speaking, it's not. But if you are looking for a box with a bunch of memory, I know where a little gigabyte RAM box for $2,000 a month. It's also got 64 cores. So, if you're looking for something to store big databases, whether it's Redis or anything else, and you need a bunch of cores, let me know and I can connect you to the right people. It's a great box and this particular service has no downtime guarantees, no excuses, which is far cry from just about their service provider up there. Redis is also great for geosearchs in much the same way that you can use Redis as a search engine. You can also add geosearching into it either via geohashing or a more naive range type things. I personally prefer just straight up sharding by single degree by single degree boxes that works for 99% of the cases. And if you're really careful, you can basically do your geosearching in two Redis round trips and have exactly the amount of data you need no more, no less. Redis is also great for configuration management. Some of you may be already using Zookeeper or Puppet or Chef or any one of the other configuration management softwares. Well, why not Redis? Really should have a Zoidberg picture up there, but I didn't think about that in time. So yeah, you can use Redis for configuration management. I actually use Redis to configure Redis. I've got one box that stores my configuration information with a slave somewhere else. It syncs over. If I need to change configuration, I write it to one Redis. It syncs off to the other Redis. And then all of my clients always know that, hey, I can check one of these two Redis instances, checks configuration data, updates itself, connects to all the right services. You can use it for database configuration management. You can use it for who to connect to. You can use it for other Redis instance configuration management. Or you can do something crazy like content distribution. What I mean by that is if you are... So Facebook uses BitTorrent to distribute their binaries out to less gigabyte binaries to run the Facebook platform. And they've got thousands of machines. How are you going to distribute four gigabytes to thousands of machines? BitTorrent. But I would hope that most of us are not looking at four gigabyte binaries and many thousands of machines. If you've got less than four gigabyte binaries and you have less than thousands of machines, you can store your binaries up in Redis and you can fetch them using the same sort of configuration management stuff. And everything will work. I've not done this yet. Although I've contemplated it. I haven't gotten around to it primarily and I don't mind sitting in a console and doing a push by hand. So, what are some not quite so good use cases for Redis? Well, if you've got more data that can fit in RAM you're going to have a bad time. There's an old system called VM which didn't work quite as intended. It worked in that you could see your data, but it wasn't very fast. And it was sort of in violation of the concept of what Redis should be. There's a system called DiskStore that stored all the data into an on-disk B-tree structure. DiskStore was never stable. There are some people who have used it and are still using it. Again, it was decided not to be, you know, it decided it was deprecated primarily because, you know, hey, why should we be waiting on disk? This is supposed to be a fast memory thing. If you want to revive that stuff, feel free. There may be some later opportunities to do these kinds of things when Redis Cluster comes out. At least that was the rumor back when DiskStore was kind of going away. If your data fits well within a relational model, you have relations and or you need joins. I mentioned that you can sort of do joins. Can sort of, basically you're exploiting a sort of method that involves sorting data and fetching data. And it's kind of nasty and it's so nasty I don't even mention it in my book. But it's possible. I would still recommend not doing it. If your data is relational, obviously don't use Redis and probably don't use other non-relational stores. You know what you need. If you need acid-compliant transactions, don't use Redis. Watch Multi and Exec come close. So does Lewis Scripting, but it's not an acid transaction, but you're going to know a sequel conference. Hope you don't expect acid transactions. If you need multi-master scaling and failover, Redis is probably not the solution for you yet. When Redis cluster comes out, there will be automatic distribution. If a slave is up to date, when the master goes down, the slave will automatically take over. Everybody will be happy. At least that's the hope. Of course everybody has different feature requests and you can never make everyone happy. If every byte is precious to you, Redis may not be what you're looking for. What I mean by that is that Redis, by default, kind of has some stuff that's only in memory at some point in time. There's an exception to this and that is if you Redis has an option to use an append-only file and either sync once per second or with every write. If you're syncing with every write to Redis, obviously you're going to be running into the limit of your disk. A spinning disk that's 100, 200 IOs a second and if you are running with an SSD, maybe you can get 10, 20, 100,000 IOs a second. Maybe. If you spent a lot of money on your SSD. There are workarounds that let you slave off to another client and make sure that it's on both disks before you continue on with the append-only, with the syncing every second. That basically introduces the second latency for every write that you perform. I wouldn't suggest it, it's possible. Also, if your management needs a support contract, Redis is probably not going to help you there. There are some companies that offer hosted Redis solutions, including VMware with their Cloud Foundry stuff, as well as Heroku. There is some add-on where you can use I think it's Redis2go that lets you do hosted Redis. Generally speaking, Redis can't really get a support contract. Let me quick move through these last few chat sections. When is Redis the right tool to use if you're not afraid of non-relational databases? If you're here, I hope you're not afraid of non-relational databases. If you like the features and functionality offered, which includes the structures, the replication and the sharding, awesome. If you're not afraid of asking questions, if you're having problems, there's not a lot of huge documentation. There's a command listing documentation, and there is some blog posts out there, but a lot of the documentation that you will find is going to be in people's heads. And a lot of the people who know about Redis are hanging out on the Redis mailing list. So if you've got questions, ask. We don't know if you've got problems. And while there are some like, hey, this is how you can solve problem X online, they're probably not going to be able to help you if you say, oh, you know, my CPU usage went up because of XYZ. Can you guys help me with this? Bloggers probably won't. Mailing this can. Also, if you like the idea of building complex functionality in a matter of hours as opposed to days, awesome. So, some benefits to organizations. I've got to move quick. No schemas means no schema migrations. Again, 100,000 to 400,000 simple ops per second, with more complex operations being slower and faster. And if you've got a single fast server, well, obviously you're going to need fewer servers. Redis's unique data model is a variety of problems that perhaps don't fit at all with other data stores. I know that 95% of the time when I'm sitting down, I'm saying, okay, where should I store this? Should I store this in the database? Or should I store it in my relational database? Or should I store this in Redis? I really have to think a lot of the times because it's like, well, you know, it should be in the database, but it doesn't really fit that table and row schema. Also, Redis has very high quality client libraries available in every major language and has C-accelerator libraries in Ruby, in Python, and in a couple other languages. Also, Redis has a very active developer community. So why Redis? Well, you can replace a few one-trick pony servers. You can replace your one configuration management software, your one caching server, your one anyone that does in different things, and you can place it with Redis or a collection of Redis servers. And fewer services and servers that you're maintaining, better support from operations. Also, documentation exists to explain just about everything that you would ever want to do with Redis on a day or tomorrow, whether that's on blog posts or my book, which actually offers about 20 different problems right now, and 20 different ways of solving your problems with Redis. And that's it. Any questions? You mentioned one of these cases that would be test queues. Are people, do you see using this like in places, something like JMS or MSNQ? Yeah, so a lot of the queuing that I see out there in my little startup and a lot of the other startup places is people will be using RabbitMQ or ActiveMQ, sometimes ZeroMQ, and they're even there's one called Beanstalk and some other things, not the Amazon Beanstalk, but the Q Beanstalk. There's a variety of these different kinds of libraries that all seek to offer test queues. And GitHub actually uses Redis as a queue, and they've got their own I forgot the name of it, I should remember it, but they've got their own queuing library that they use via Ruby and Redis, and that's been released open source. And there's Celery on the Python side of things that has a back-end support for Redis. So are you interested in queuing a first class object in there or is it just a list that you're writing stuff to? It's just a list that you're writing stuff to. Can you query 25,000 things in a list and see the different types of... So you can get the length easily and you can pick out individual items, but because it's a linked list, obviously it's going to take more time to get something in the middle than at either end. Can you query to see what the different types of... You would have to index that in some other way. I just wanted to comment that in the queueing library you were trying to remember the name of, it's called Rescue. Yes, Rescue. Thank you. Thank you. Okay. It depends on your needs. If you want, we can talk later. Generally, I wouldn't use it for that because usually write through cache implies that your data is important. And if you remember I've got that every byte is sacred. So I probably wouldn't if you were willing to... If there are some things that you're willing to sacrifice, like if you're willing to sacrifice a bit of performance or if you are willing to run two or three redis machines just to make sure that your data gets on disk somewhere, then you could totally do it. And that would be not a bad use case. Okay. So MongoDB is the document store, right? You store these BSON objects and you get, you know, you can have your nested objects, you can index arbitrary attributes inside anything and you can even have a sort of multi-column index if you define it in Behance and all that other stuff. Redis doesn't store documents. Redis stores structures. Right? And so conceptually they are significantly different in a variety of ways. Now with MongoDB you can have lists of things and you can index entire lists of things which is great from a conceptual perspective and it was totally borrowed from Google App Engine's data store semantics. And if you really want to find out why MongoDB does the things it does, just look at Google's App Engine data store and you will find a lot of similarities. Not saying that they... I mean, conceptually it's a great model. I've built a similar thing myself. But it's not... It doesn't have lists in the sense that you can push and pop things off of both ends atomically. You know, Redis is all about single operations being atomic. And MongoDB, good luck popping one item off of a list in a document. And I wish you that luck honestly and earnestly just because you're going to have to read somehow, acquire a log, do all that other stuff. I wouldn't. But maybe my knowledge about MongoDB is old. There is a pop command? Oh. Good. Okay, great, great. Never mind. Okay, so there exists that stuff. It's a lot better than what I remember in MongoDB. All right. Any other questions? All right. Well, thank you very much. Not a question. I just wanted to let you know if you want to hear more about Redis, the talk is going to be right after this one. And I'm covering Redis in my talk. It's not actually on the schedule because I hadn't changed the topic because we changed the speaker. Anyway, if you want to learn more about Redis and see some example use cases like what he was talking about, come on downstairs and see what I'm talking about. Is your role talk about Redis or is there something else? It's a different tack. We talk about how we use Redis in our startup to basically facilitate fixing a lot of problems similar to his talk but less technical. A little bit more business level. All right. And some live demos. All right. Thank you, everyone.