PostgreSQL, pg_shard, and what we learned from our failures
citusdata.com
citusdata.com
Not sure if that's what they really meant — since their business is sharding, this shouldn't be new to them.
The buckets correspond to hash token ranges. For example, the database takes one row from orders_2013, hashes the customer_id value, and gets a hashed value of 1.5B. It then puts it into the second bucket orders_2013_[1B-2B[.
After the distributed shuffle, you end up with orders_cust_id[1B-2B[ on machine 2. So all orders that belong to a particular / disjoint set of customers live on one machine. You can then push down the count(distinct customer_id) to each node, and then add up the results.
We use hash token ranges in pg_shard. I'll include this clarification to the blog post.
It's Postgres' Extension APIs. They enable you to extend, cooperate with, or override any database submodule's behavior without forking the database: https://goo.gl/rr2EIm
As an example, let's say you leveraged planner hooks to parallelize PostgreSQL queries. When a new feature such as JSONB gets checked into Postgres, it becomes immediately available for parallel querying.
To my knowledge, no other database provides the means to extend the database to such an extent. These APIs became official in PG 9.0, and two example links from the PostgreSQL documentation are:
http://www.postgresql.org/docs/9.4/static/extend.html http://www.postgresql.org/docs/9.4/static/spi.html
It also allows you to present said information from other stores through a well defined interface, such as via stored proceedures that can be locked down via login/identity/application and other features typically in SQL, while being able to act as a gateway for more optimized data stores for specific types of data. Not to mention that JSON data in pgsql has gotten pretty good... I think with plv8 it gets event better. Where I think pg falls is in terms of replica sets, hot failover and automated recovery options which many nosql servers give you in the box. With PG you pretty much have to pay for a decent HA solution.
That said, I honestly really like document stores, and RethinkDB as an example offers some of the relational features of a typical SQL database while being mainly available as a document store.
And personally I have always thought putting business logic in stored procedures is a truly dumb idea. You forever lock yourself to that database and there is always a point that you can exceed its capabilities and need to implement functionality in the application layer anyway.
Generally if you have exposed your db credentials it's because something has gone very wrong i.e. your entire host has been compromised in which case stored procedures aren't going to save you.
Postgres has been building its SQL coverage for over a decade, and compares favorably to others databases: https://news.ycombinator.com/item?id=9018129
Given local join machinery, a join between 2 distributed tables can be achieved by joining the partitions of the tables locally after ensuring that tables are co-partitioned and partitions are co-located. That is, if performing A JOIN B ON (A.X = B.Y), ensure that A is partitioned by X and B is partitioned by Y with the same partitioning scheme such that every partition in A has a corresponding partition in B with which it can be joined. A distributed join can then be performed (in parallel) by joining each pair of partitions and concatenating the results.
Ideally, tables are co-partitioned and partitions are co-located in advance. The article describes scenarios in which the tables need to be repartitioned during the query, which can cause a lot of network traffic. However, the amount of traffic is limited in practice since filters and projections can be applied before shuffling any data.
The great thing about implementing a distributed database on top of PostgreSQL is that the local machinery already exists, and it is very good.
With sharding, the distributed executor can work on the SQL level and translate one SQL query to many SQL queries. In that case your distributed executor can focus on issues such as partitioning and merging data, while the low-level work is still being done by the regular PostgreSQL executor, so you don't have to implement it from scratch.
[1] https://github.com/citusdata/postgres_vectorization_test
> The PostgreSQL Extension APIs ... enable you to extend, cooperate with, or override any database submodule's behavior. We could therefore change our design to use the planner and executor hook APIs, and we found that things followed nicely from there.