arborint wrote:
pytrin wrote:Simple for writing, but how would you know how to fetch the information if you are not getting it by the primary key?
Usually sharding is done by splitting the database into separate servers. There's also partioning which allows splitting the tables themselves. Both require that the application knows how to retrieve the data once it's no longer on the same server.
You do get it by primary key. It's just that primary keys 1,5,9.. are on one server and 2,6,10.. are on a second and 3,7,11.. are on another. You set the step to be however many servers there are. You can either have the application code determine the server, or with replication you can read back from any server. There are many ways to do sharding. This was just a something I tried that was really easy and worked well.
The problem with that is it's limited to a set number of servers. My two cents on those whole project is scaling small-medium sites is not that difficult.
(These are examples)
Step #1
Master/Master - ( Just two servers, keep them at around 50% load each that way either master can take over if something goes wrong )
Step #2 (you grow)
Master/Master with slaves. You read from slaves, you write to masters, simple.
Step #3
As you grow more and more reads you can start doing things like have slave-masters that other slaves will replicate off it's slave. So lets say the master writes to 10 slaves, then those 10 slaves write to 10 slaves each, you can scale reads forever almost.
Step #4
Okay so you're starting to have write issues. There is tons of ways to solve this problem as specified in posts before. Horizontal Sharding ( e.g. Splitting table data across multiple servers. For instance you might have 1,000,000 users on server A while the other 500,000 is on server B. ) Vertical Sharding ( e.g. Splitting up table(s) across multiple databases. You can do something like putting the entire users table on a separate database server, or before you have that big of a users table you can put multiple tables on the same database server. Basically instead of having one huge database server, you cut the tables into groups.)
Now the problem with this comes into relationships. You have to start denormalizing your data. JOINS are not your friend as you scale. For instance, Facebook doesn't have a single JOIN in production. To solve issues like this sites like Flickr, Facebook, Digg, etc start replicating their data across their servers. For instance User ID 51789 might be on Server #482 and they'll not only store that users information, but any comments, picture entries, etc on that server also. If two users needs to have the same data joined, they'll replicate the data. For instance an entry in the database links to two different users, then each of the user's servers will have that data. Sure, denormalization makes things much harder as your application logic needs to start adding in the fact that you duplicate data and need to update both, etc. But no one said this would be easy.
Also, to fix the issue with not being able to have primary keys, a lot of big sites have index servers. These index servers contain information tow here all the data is at. For instance I'll connect to my users index and ask them where user 45 is. It will return what cluster / server that user is located and then I'll connect to that.
Scaling isn't just the database, you can reduce A LOT of load on your database servers by caching. For instance, Memcache. Facebook has a 99% cache hit ratio. That means that 99% of the time they can pull data off their cache instead of having to get data from their database. That helps a lot. Even simple things like fragment caching can be amazing, on your main page for instance you can set data to expire after 4 hours. Or you can make it not expire at all and in the backend whatever is updating that info, also updates the cache. It's really simple.
For scaling static content, you can use a 3rd party service like Amazon S3, etc. Or if you want to host it on your own, it's not that difficult just make sure you use something other than Apache as said above it's not really the best for static content serving. You can use other software to help like for instance if you have a large data set where people need to filter out results, you can use something like SphinxSearch. It's not just made for Search, you can use it to help find data by adding filters on it's huge index without even specifying a search query. Lets say I want to find all the users from the ages 18-24, I want them to be male, and they need to be in the zipcode xxxxx, it will return the results instantly.
Anyways I wrote way too much. Hopefully the posts helps someone. Like someone stated above highscalability.com is a good resource. Cal Henderson wrote a great book called "Building Scalable Web Sites". He basically built Flickr. Although it's mainly PHP/MySQL based the solutions can be used on other languages / databases with a bit of common sense.