Tidis - Redis protocol on top of TiKV
github.com
github.com
Questions to fellow HNers: - If you need to deploy such software for your business, was it because optimizing GCP/AWS is not cost-effective or the same level of performance is not possible on public cloud?
TiDB was build to operate at a scale for OLTP (scale writes horizontally just by adding more nodes) that doesn't exist on Amazon's MySQL. You would have to you DynamoDB and downgrade from SQL transactions to eventual consistency.
In terms of customization, TiDB is offering something AWS does not: the ability to store ever more of your data in one distributed data store (TiKV) and to leverage that in different ways (query it with TiSpark, and perhaps more projects like this in the future).
[1]: https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-au...
[2]: https://aws.amazon.com/about-aws/whats-new/2017/11/sign-up-f...
I don't expect multi-master to increase write performance much. It will scale out network connections and maybe query processing, but not actual writing of data.
It will replicate all data to all nodes, and the replication will be synchronous to any node it can automatically fail over to. So a client will be able to connect to any master, but that master will have to synchronously write to at minimum all other masters, if not all other nodes, before the server can acknowledge the write back to the client. Every node will need the write performance to write every write. That isn't scaling out writes.
> Workloads that require even higher write throughput will benefit from horizontally scaling out their writes with additional master instances.
[1]: https://aws.amazon.com/about-aws/whats-new/2017/11/sign-up-f...
In Aurora [1], data is partitioned into 10GB chunks ('protection groups'), with copies stored in 6 'storage nodes' spread across 3 Availability Zones. When the 'server' (database node) handles a write, the data is sent in parallel to all 6 storage nodes, and the write is accepted as soon as a quorum of storage nodes (4) writes the data to its redo log and responds. The storage nodes also continuously back up the data to S3 for extra durability.
These 6 parallel storage-node operations are performed for every write, even in a single-master Aurora setup. Multi-master simply scales out the number of 'database nodes' (compute) for handling queries, while keeping the number of storage nodes (and the total write-amplification) constant. In the rare case when conflicting write-transactions occur that can't be resolved locally at either the database or storage layer (e.g., when data changed at both multiple database nodes AND multiple storage nodes), a hierarchical conflict-resolution mechanism is invoked to decide which transaction succeeds and which gets rolled back [2]. This reportedly provides 'near-linear performance scaling when there is no or low levels of conflicts', even when dealing with multiple masters spread across multiple regions [3].
[1]: https://aws.amazon.com/blogs/database/introducing-the-aurora...
[2]: https://www.slideshare.net/AmazonWebServices/deep-dive-on-th...
[3]: https://www.slideshare.net/AmazonWebServices/deep-dive-on-th...
When they do that it will be called horizontal scaling.
Aurora horizontally scales storage capacity and read throughput (and with multi-master currently in preview, write throughput) without requiring the application to handle any implementation details of 'sharding'. This is a feature, not a bug.
And looks like the compute layer can't pushdown processing to storage servers.
You do a "select coun(*) from t where a=1" and "a is not indexed" on 600 storage servers and 1 compute server. Does the count happen in parallel on 600 storage-nodes and 1 accumulate on the compute server ? Or rows transfer to compute for counting ?
Yes, 6 storage servers (10GB chunk) automatically scale up to 6000+ (64TB) [1].
> And looks like the compute layer can't pushdown processing to storage servers.
'Parallel query' for Aurora became available for preview in February [2]. The compute layer does pushdown processing to storage servers [3]. If you do a "select count(*) from t where a=1" and "a is not indexed" on 600 storage servers and 1 compute server, the count should happen in parallel on 600 storage nodes and 1 accumulate on the compute server.
[1]: https://aws.amazon.com/rds/aurora/faqs/#hardware-and-scaling
[2]: https://aws.amazon.com/about-aws/whats-new/2018/02/amazon-au...
[3]: https://www.slideshare.net/AmazonWebServices/deep-dive-on-th...
Perhaps the biggest reason though is that software is easier than ever to operate now with the rise of containers and Kubernetes. In fact, you can use Kubernetes as the single managed service to get that taken care of by the cloud, and then do the rest yourself for a great balance of cost, performance, flexibility and reliability.
At least move many things in coprocessors in tikv layer.
Cool project though.
Isn't that what a database is?
Is there anything fundamentally better about Redis than say, a single connection to Postgres?
Except with Postgres you would be allowed many concurrent connections and greater throughput, while having the same external behavior thanks to transaction serializability. It's as if the operations got applied by a single thread in a defined order, but in reality can be parallelized. Redis cannot do that intelligently.
I use Redis occasionally because it's a very simple system and it's easy, and has been micro-optimized very well. I don't think it necessarily contains any good computer science ideas. Am I wrong here?
Tidis is more evidence that Redis's single threaded design leaves a ton on the table.
A sorted set is a index in Postgres, stored as a B-Tree.
Postgres has hash indexes, basically the same as a hash table.
And you can run Postgres in memory if you want via tmpfs.
Bitmaps and hyperloglogs are basically math functions running in the database, and Postgres supports user-defined math functions. It seems disingenuous to point out individual math functions when both databases support arbitrary user defined math functions.
Think of Redis a a shared, in-memory, well-tested implementation of basic data structure primitives that takes care of a lot of the fiddly nonsense around them without you having to do the work. Postgres is awesome, but it's targeted at a different use case and has different characteristics; it's overkill for something like a shared key-value store, for example.
For us, redis takes the place of IPC and “persistence” by not sharing lifetimes with its consumers, ie while redis May go down and our microservices restart all the time, the two have separate lifetimes and redis being around between the two bridges the temporal gap.
Using redis to store structured data is ineffective once you need something even remotely structured, requiring too many commands to perform what should be an atomic operation.
Strong persistence or consistency isn't something that is very popular in Redis (or at least I haven't seen it done). In most cases you are right - if you are willing to trade latency for persistence or consistency there are other tools available.
I wouldn't read that much into tidis - it seems like a hobby project for now. Another interesting redis project is pedis (https://github.com/fastio/pedis). It takes advantage of multiple cores by, at a high level, sharding the keyspace per core.
But Redis is designed for a different use-case It's far simpler to install and operate, and much faster to run by being completely in-memory. It has optional persistence when you need it, easy replication, and a simple single-threaded architecture with primitive access to data structures. So yes, you won't get the flexibility of a relational database, but you get performance and simplicity and there are a great many uses for that.
If you can't think of a reason to use it, then that's a good sign that you just don't have a need for it.