How far can you go with MySQL or MariaDB?
jfg-mysql.blogspot.com
jfg-mysql.blogspot.com
My personal experience is that InnoDB performance drops off a cliff as tables grow and parts of tables stop fitting in RAM. TokuDB just keeps on going.
TokuDB also compresses your data really well.
My own stats: https://williamedwardscoder.tumblr.com/post/160628887798/com...
This doesn't take away from TokuDB though - which is pretty awesome in any case.
Yes but at least in my experience as things fit in RAM, InnoDB is still the correct choice.
TokuDB is great once you run out of RAM-related solutions but given the price point RAM is at these days, we are talking 100GB+ tables which probably shouldn't be one a single machine anyway.
If your dataset fits in ram, and when it doesn't you have to buy more boxes with more ram rather than just buying more disk, then I think you are making a very uneconomical trade off.
> If your dataset fits in ram, and when it doesn't you have to buy more boxes with more ram rather than just buying more disk, then I think you are making a very uneconomical trade off.
It is all in what lower latency is worth to the bottom line and how well you scale horizontally.
(Src: have run each, and stuff like shard-query to parallelise queries and scale them out)
The machine isn't even that beefy, 128 GB of RAM, dual mid range Xeons, and prosumer SSDs in RAID 10. I would rather spend money in PCI-E SSDs, 300+ GB of RAM, and high end CPUs if it meant I didn't have to implement sharding at an application level.
You can comfortably handle multi-tera tables on single machines these days. Adding more machines isn't "scaling", its admitting "we can't scale in software so make it a hardware problem"
I think we are ultimately going to switch to PostgresSQL as it has better tooling and features that we need (json, jsonb, postgis) and performance is also good when properly tuned.
Backup isn't that bad either as this run on ZFS that support blazing fast atomic snapshots of all related filesystems like pg_xlog and tablespaces.
For tablespaces the recordsize can be anything from 8k to dynamic / 128k. They all have pro/cons. Greater record size improve compression and sequential read performance but small random updates becomes a lot more expensive. I feel a recordsize of 16k or 32k with lz4 compression is a safe setting for optimal performance with good compression.
Other useful topics related to performance are: Use multi-column/functional/partial indexes, as this will help you design a database where most of your 'hot' indexes can fit in RAM. If you have too many indexes, you will do index scan on disk, which is painfully slow. I many cases a full table scan (sequential read) would be faster instead.
BRIN indexes are great for large tables that can be sorted on for example on timestamp.
Common Table Expressions, for recursive queries.
The query planner sometimes needs help as it will start doing full table scan on a table when it could just have used an index. This is related to table statistics which you need to alter. You can read more about this here: https://www.postgresql.org/docs/9.5/static/planner-stats.htm...
Adjusting the seq_page_cost and random_page_cost can also help the query plannner.
There is probably a lot more, but you learn as you go :)
I have a theory that a lot of people who are dismissive of modern relational databases for 'big data' simply never took the time to learn to tune them properly as the data sets grew in size. It's a painful process, and there is an intimidating number of switches and knobs, some of them in the filesystem and kernel.
In particular, running large databases on virtualized hardware like AWS really brings the pain.
> running large databases on virtualized hardware like AWS really brings the pain.
The pain, I've found, mostly stems from the fact that it is a VM, and the performance costs associated with that. When you assume that your disk is local, and it's actually a network volume with shared network bandwidth, you'll get kicked right in the assumption. Or you assume that you have a static amount of memory, but the balloon drivers punt you into swap, or that you will get reliable interrupts from the OS...
It's gotten better over the years, but it's still a mess.
Oh, and I've said it before, so I'll say it again. If you're running MySQL in RDS, go in and turn up the 'innodb_log_file_size' setting to a bare minimum of 2GB, 15GB if you have the disk space. Go, do it now!
Not who you're responding to, but this is a good overview.
The practical effect of changing this value: a 2xlarge RDS host goes from 85% CPU utilization to 10%, with faster response times, for a moderate write load.
The downside, and why it's not the default for RDS, is that it eats your RDS storage by 2x the value set.
The OS needs about 2GB of memory to do its thing sanely; if your instance only has 4GB of memory, don't assign 3 (closer to 3.5 with the constant memory costs) of it to the DB.
FWIW, if you either do only relatively large transactions, or you're ok with a small loss window, you're often ok - usually the issue is latency not bandwidth. With postgres you can e.g. set synchronous_commit = off, which'll allow COMMIT's to return without an fsync, instead grouping them together.
A lot of disk reads with working set >> memory are still a problem, and a good reason to use local storage. But that obviously complicates the durability story a good deal.
I had a former coworker who would routinely put an index on every column in a table when creating the table.
Of course some DBs are better in some use cases, and price is a factor. As is ease of replication, sharding, etc.
Many of the no-SQL databases are very task specific and, as such, don't have this problem. Probably one of the reasons for their popularity. Learning which no-SQL database is best for each task tends to be easier than learning how to tweak relation DBs for each task. I think part of the reason that relation DBs are coming back a bit is that this communication/documentation issue is starting to be addressed.
It's about scale, it's about failover, it's about active active active multi DC Masterless HA. All of these things you can build around MySQL, but you end up reinventing something that looks a lot like Cassandra.
If you're FB/YouTube, you write that tooling, because it extends your existing investment in MySQL
Everyone else needing to scale to multipetabyte, millions of ops per second, always online scale is better off using Cassandra
The answer lies in the "Billion Tables Project" :) https://www.pgcon.org/2013/schedule/events/595.en.html
- HA
- How to recover some subset of 37TB of data without restoring all of it
- What happens when your write throughout needs to exceed the capacity of a single disk
Nobody gives up features like joins in favor of a distributed shared nothing DB because they feel like they need more space, they do it for HA, more cores, more spindles, fault tolerance and isolation.
[1] https://code.facebook.com/posts/190251048047090/myrocks-a-sp...
So, still impressive to me. That custom storage engine is just for the "user database" tier. Given their user count, that doesn't seem unreasonable.
The context being that InnoDB got FB pretty far, and that UDB appeared to be the first area where any pain was notable enough to need something else.
This comparison is a bit apples to oranges anyway, with respect to the original article :) JFG's post was talking about extreme cases within a single MySQL instance, whereas Facebook is extremely heavily sharded.
Was just trying to reinforce the point that MySQL gets you pretty far.
(Using "big data" to mean sacrificing low latency joins and full transaction support, with the caveats that many "big data" systems are making progress at getting those things to work.)
Of course you can shard, but there is a significant maintenance cost to that as well, and requires your data model can be easily sharded.
Sharding, or splitting out into "big data" databases has its own cost, a cost which is frequently greater than the $20k worth of hardware.
Maybe that's a system that could have been better served by something like Cassandra? (Depending, of course, on access patterns, complexity of queries, etc. etc.)