Hi Mike,

this is a great proposal, thanks a lot! I like this general idea, I guess this 
was what Adam was hinting at in the _access draft review ;)

I left one comments inline.

> On 22. Nov 2017, at 14:56, Mike Rhodes <mrho...@linux.vnet.ibm.com> wrote:
> 
> All,
> 
> Just to be clear before starting: this is a proposal from Cloudant not just 
> myself :D
> 
> ## What?
> 
> Introduce a user-specified shard key per document and a way for the user to 
> scope queries to a single shard using this key, thereby reducing query 
> latency by allowing the database to consult only the shard required to answer 
> the user's query. Documents can share a shard key and all documents with a 
> given shard key are written to the same shard. The shard key therefore 
> overrides using the document ID as the key to shard by.
> 
> ## What problem does this proposal address?
> 
> To improve performance and throughput of queries generally, and specifically 
> to significantly decrease the effects of data size on query latency and 
> cluster load leading to better data scaling characteristics of the database.
> 
> CouchDB's current queries -- whether to views, search indexes or mango -- 
> perform badly when the shard count (Q) for a database is high. This is 
> because the coordinator node can't know in advance which shards hold results 
> for the query, so must make a scatter-gather request to all shards, even 
> those that in the end return no results. In turn this generates more load on 
> all servers in the cluster because of many possibly redundant file reads.
> 
> We did some hacky performance testing of this idea by modifying the current 
> view API to allow one to specify a specific view shard in the query. The 
> results were very promising, as they showed that queries started scaling with 
> similar characteristics to lookups, as you'd hope for, in that Q ceased 
> having such a large effect and load on the cluster decreased.
> 
> ## API
> 
> There are a few general considerations which act as constraints on the API. 
> To get these out in the open:
> 
> • The combined <shardkey>:<dockey> must be a valid document id. This enforces 
> uniqueness of shardkey:docid across the database and invariance between 
> document updates.
> • Aside from calculation of shard location, we treat the combined 
> <shardkey>:<dockey> as we do any other document _id.
> • All existing tooling should continue to work as-is (e.g., changes feed 
> doesn't have to change to specify a shardkey:dockey pair and the replicator 
> will "just work").
> • For Cloudant, it's useful to be able to differentiate queries by path for 
> our internal accounting.
> 
> For this we have a documentid becoming a composite thing: 
> `<shardkey>:<documentkey>`
> 
> • shardkey can be any valid characters for a document ID, but must not start 
> with an _ or contain a : or /.
> • documentkey can be any valid characters for a document ID. Further : 
> characters are treated as part of the key; meaningless.
> 
> From this, our proposed API is, which should also help clarify a bit how 
> things work:
> 
> • Enable shard keys using database create: `PUT /db?use_shard_key=true`. 
> Default false.

Since this is the first of “different kind of database”, we should think about 
how to do this more generally, as I expect more of these options to come soon 
as well, _access comes to mind. Would this then be e.g.: `PUT 
/db?use_shard_keys=true&per_doc_access=true`? It might make sense to put a 
little bit of thought into how to name these options and how to enable/disable 
them. This is a total bikeshed (although one CouchDB is famous for), this won’t 
block this overall proposal, there will be a way to enable/disable this, and 
how exactly is TBD.

>       • For databases where this is enabled, every document needs a shard key.
> • Upload a document: `PUT /db/<shardkey>:<dockey>`
>       • In these databases, documents need user-specified document IDs as the 
> shard key needs to be set by the user.
>       • Therefore reject POSTing documents to /db for simplicity (rather than 
> having validation of an _id field).
> • Other things that create documents will need the validation of document ID 
> too:
>       • Copy a document. Same as now but reject when destination document id 
> does not have a shard key.
>       • Calls like `POST /db/_bulk_docs`, `POST 
> /db/_design/mydoc/_update/myupdatefunction` and others that accept documents 
> via POST bodies will need to inspect the body for shard keys.
> • Get a document: `GET /db/<shardkey>:<dockey>`.
> • Special documents:
>       • Design documents and local documents have no shardkey in their docID. 
> This is enforced.
> • Reject documents with IDs of the form `<shardkey>:_design/foo`.
> • Query requests introduce a shardkey into the path, following an explicit 
> `_shardkey` path part:
>       • Mango: `POST /db/_shardkey/<shardkey>/_find`.
>       • Views
>               • `GET 
> /db/_shardkey/<shardkey>/_design/mydoc/_view/myview?include_docs=true`
>               • `POST 
> /db/_shardkey/<shardkey>/_design/mydoc/_view/myview?include_docs=true`
>       • Query results are restricted to documents with the shard key 
> specified. Which makes things harder but leaves the door open for future 
> things like shard-splitting without changing result sets. And it seems like 
> what one would expect!
> • The above is a white list of APIs, so a few notes on some cases I've left 
> out with reasons:
>       • _all_docs (can see uses, but would rather keep API small to start 
> with). Note that Mango depends on the internal _all_docs API.
>       • _changes (use-cases better served by explicit shard API).
> 
> ## What are we NOT addressing here?
> 
> This proposal only provides indirect shard addressing -- it's specifically 
> not covering things discussed previously [1] per-shard changes feeds where 
> one needs to directly address each shard. The shard key only controls the 
> bucketing of documents into shards and doesn't say anything about, for 
> example, whether two shard keys end up on the same shard -- that's an 
> internal detail.
> 
> I'd really appreciate thoughts and comments before Cloudant get started on 
> implementation of this.
> 
> Mike.
> 
> [1]: https://issues.apache.org/jira/browse/COUCHDB-2791
> 

-- 
Professional Support for Apache CouchDB:
https://neighbourhood.ie/couchdb-support/

Reply via email to