Migrating from RethinkDB to Postgres – An Experience Report
medium.com
medium.com
I think standard line "use right tool for the job" is still the ultimate answer. Data in most applications is relational, and you need to query it in different ways that weren't anticipated at the beginning, hence the longevity of SQL.
That said, I too often see HN commentators say something like "this data was only 100 GB? Why didn't they just put it in Postgres?" which is not as clever as the writer may think. Try doing text search on a few million SQL rows, or generating product recommendations, or finding trending topics... Elasticsearch and other 'big data' tools will do it much quicker than SQL because its a different category of problem. It's not about the data size, it's about the type of processing required. (Edited my last line here a bit based on replies below.)
What you retain by staying with Postgres rather than going to a more exotic database is priceless. There is a threshold of data size or product need that makes a more specialized database the right choice. It's just well above 100 GB and your application should have some very specific needs to justify it.
As for the other stuff I mentioned (recommendations, etc.) I'm not just basing it on my personal experience--here's a write-up from Pinterest about having to dump all their MySQL data to Hadoop to drive various types of analysis. I doubt they would do it it if just putting the SQL DBs in RAM was adequate! https://medium.com/@Pinterest_Engineering/tracker-ingesting-...
Full text with Postgres is pretty fantastic and configurable. Not putting the data somewhere else keeps you from having to maintain a second system, keep things in sync, etc.
People jump to putting data in a search tool because it's a search tool waaaaay too quickly IMHO. If the use case justifies it, go for it...but don't add uneccessary complexity unless you have to.
To be fair there is some amount of "keeping things in sync" one has to do with postgres, even if it's just setting up the right triggers to update the FTS index on updates.
Right now I'm working on an app that works with tweets. I want to find all tweets that link to iTunes.
When I was using:
> select * from `tweets` where `url` not like '%twitter.com%' and `url` like '%itunes.apple.com%'
I could scale my server up to 16 CPUs, it would still take several minutes to search a few million tweets.
Yesterday I added another field to the database, `is_audio_url` where I pre-compute whether the URL is an itunes link (by string matching in the app code) when I insert the record into the database. So I can do:
> select * from `tweets` where `is_audio_url` = 1
And now it's blazing fast. It is just my most recent of many experiences that MySQL really struggles with text matching.
> It is just my most recent of many experiences that MySQL
1) You're using MySQL not Postgres; given that this is a discussion about whether Postgres can compete with Elasticsearch, that's not super relevant. :)
> select * from `tweets` where `url` not like '%twitter.com%' and `url` like '%itunes.apple.com%'
2) That's not how you query a full text index; that's going to be glacially slow.
You need a FULLTEXT index and to use a MATCH...AGAINST query. Check out the docs[1].
[1]: https://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html
You can use trgm module to index this kind of queries.
- Full text index - Extract the domain name to another column index it - Change mysql defaults - Change engine types. Maybe go in memory - Create lookup table of domains
And it works better than ElasticSearch, just due to the lower additional overhead.
What is the size of your database on disk?
The size of the database is a few dozen gigabytes by now, but that isn’t relevant with tsvector, only the row count has an effect on search speed.
I was asking because ranking can be slow in PostgreSQL. PostgreSQL can use a GIN or GiST index for filtering, but not for ranking, because the index doesn't contain the positional information needed for ranking.
This is not an issue when your query is highly selective and returns a low number of matching rows. But when the query returns a large number of matching rows, PostgreSQL has to fetch the ts_vector from heap for each matching row, and this can be really slow.
People are working on this but it's not in PostgreSQL core yet: https://github.com/postgrespro/rum.
This is why I'm a bit surprised by the numbers you shared: fulltext search on 270 million rows in below 65ms on commodity hardware (sub 8€/mo).
A few questions, if I may:
- What is the average number of rows returned by your queries? Is there a LIMIT?
- Is the ts_vector stored in the table?
- Do you use a GIN or GiST index on the ts_vector?
Cheers.
What storage solutions would you use for product recommendations or trending topics?
It comes out of the box with a way to find "More Like This" https://www.elastic.co/guide/en/elasticsearch/reference/curr...
For trending topics I believe I used something related to this: https://www.elastic.co/guide/en/elasticsearch/reference/curr...
An interesting article on using ES: https://auth0.engineering/from-slow-queries-to-over-the-top-...
Relational is well understood. The modeling problem is well understood so you don't have to guess too much about how your data should be structured. By default I start projects with a rdbms and then carve out the portions that truly are hierarchy-only.
That said, I'm starting to investigate graph databases more closely and what I like about them is what I like about relational: queryability. It's so easy to write a short query and extract your data. I like the model quite a bit too because graphs are a pain to shoehorn into a relational db. I'm still not entirely sold but I would love to find more good resources on graph dbs.
Order / OrderLine
In a document db we store it as a single document because an order is the root aggregate and the order line cannot exist without an order.
It relates to other objects in the database in the sense that it may relate back to a User...
We hack together our "understood" objects to fit into a relational database.
When I was first building the project, I didn't totally know what schema I would need. I started on Postgres. But having to constantly do database migrations while I was developing was a pain. RethinkDB was great for development while I was figuring out what schema I needed. But now that the website is live https://sagefy.org , the schema started getting stable.
I'm not using perfect third-normal form, but in many cases I have no query needs there so JSONB makes sense. JSONB columns can actually remove much of the need for NoSQL. The biggest gains from moving were: not having to do foreign key validations myself (yay!) and about 2/3 filesize reduction to the database. My database isn't large enough for performance to matter, but I'm sure it would eventually.
If I were to do this again, I would probably start again with a NoSQL database (maybe Redis or ES, or just files even) until I figured out the schema and then move to Postgres before launching. I'm sure there's smarter people out there who can start with SQL and predict easily what the feature set is going to be be before they start, but I don't usually have that foresight. `ALTER TABLE ...` gets old really quickly.
I'm keeping an eye on CockroachDB too... if they can really make something similar to Postgres but easily scales horizontally... that would be amazing.
Much of the "reasoning" I see for people choosing Elasticsearch or InfluxDB or MongoDB seems to come down to, "It showed up a lot on Hackernews".
I would be grateful if you contact me at 8nvyve+wj7zvh7q5e0@sharklasers.com (it's a throwaway email as I avoid posting my private email publicly). Thank you.
> leaning heavily on Haskell in order to fill in some of the gaps quickly.
So it looks like they had to do some work to cover some features from rethinkdb/elasticsearch.
PG doesn't even have a clustering solution out of Citus, how do you scale / HA postgres using the default setup without doing sharding yourself?
https://wiki.postgresql.org/wiki/Clustering
Some commercial.
Maintaining each library has enhanced my appreciation and respect for how the Postgres people do their thing.
Or are you saying that you're only CPU-bottlenecked?
Not quite following - a column store will usually not have more sequential IO than a row-store. Often enough to the contrary, because you have to combine column[-groups], for some queries. What you get is: Higher compression ratios, better IO & cache access patterns for filter-heavy queries, easier to vectorize computations. Especially if you either filter heavily or aggregate only a few rows, you can do a lot less overall IO in total, but the sequential-ness doesn't really improve.
> Or are you saying that you're only CPU-bottlenecked?
Oftentimes, yes. You might be storage space constrained, but storage speeds for individual sequential-IO type queries are usually fast enough. Parallelism helps with that (if you can push down enough work, a lot of it added in 9.6 & 10), plain old code optimizations (better hash-tables, new expression evaluation framework, both in 10), as does JITing parts of the query processing (WIP, patches posted for 11).
Also, it would be really nice if I could do both my transactions and my analytics in the same box. Then ETL is basically just maintaining a materialized view.
See a Quora answer I wrote:
https://www.quora.com/Amazon-redshift-uses-Actians-ParaAccel...
Just wondering, seeing as am not a Postgress user - is Postgress commercially maintained? Or is it pure open source (like I believe RethinkDB is currently)?
There's not really a foundation that manages development - there's one that holds the trademark etc. but that's largely the extent of its activities and there are some geographical associations. The development is just managed by the community - there's a number of committers that technical authority to make decisions, there's the "core team" that resolves conflicts should they otherwise not be resolvable, release team, infrastructure team, ... but these are just people working together.
> ..., but there are a number of well established businesses offering commercial grade support. Some of these companies employ some of the major contributors to PostgreSQL.
Indeed, most of the active PG devs work for one of them.
I do think there are enough companies now that develop PostgreSQL based products (EnterpriseDB, Citus Data, Greenplum, etc) along with the larger PostgreSQL consultancies which would probably raise their hand if they thought one player or another was becoming dominant in some way hostile to the others.
All of this is outside observer speculation, but it's the way I read the tea leaves.
At least some of us have that understanding - and looking at where at least the committers work it's fairly well distributed.
> Having said that, there do seem to be some larger concentrations of them in a few companies. I don't keep up too much with that either, but it seems like EnterpriseDB was in this camp (and logically so).
There is some concentration, but if you look at the list of committers (smaller number, I don't have to look up affiliations), they're fairly well distributed across the the larger players (alphabetically 2ndQuadrant, Crunchy Data, EnterpriseDB) and various other orgs with some.
Whereas RethinkDB was primarily developed by one company, then open-sourced. I hope that the RethinkDB project is successful, but it's reasonable to suggest that the future of Postgres is 'safer' at the current time.
(What you think?)
Seems like a legit answer to me.