[WIP] Use BigTable Columns as range keys#753
[WIP] Use BigTable Columns as range keys#753gouthamve wants to merge 3 commits intocortexproject:masterfrom
Conversation
See cortexproject#714 for motivation. One thing to notice is that unlike existing schemas, here the structure of the data being stored changed. This caused some backwards incompatible changes as the `StorageClient` interface doesn't have any time information in the `QueryPages` making it impossible to know if we need to range over the row-key or the columns to retrieve the data. For maintaining backwards compat, use `chunk.storage-client=gcpv1`. Signed-off-by: Goutham Veeramachaneni <cs14btech11014@iith.ac.in>
Signed-off-by: Goutham Veeramachaneni <cs14btech11014@iith.ac.in>
|
Thanks Goutham! Will take a look tomorrow. |
|
@gouthamve please give the motivation for this change. |
|
Sorry, explained everything in the commit message but forgot to post here too. Motivation comes from: #714 This would mean accessing lesser number of rows per query. |
pkg/chunk/gcp/fixtures.go
Outdated
| srv *bttest.Server | ||
| name string | ||
|
|
||
| version int |
There was a problem hiding this comment.
I'm generally less of a fan of "version" fields, and more of a fan of feature flags, mainly because feature fields are more self-explanatory.
pkg/chunk/gcp/storage_client.go
Outdated
| // this format, so we need to do a proper migration. | ||
| rowKey := hashValue + separator + string(rangeValue) | ||
| hasher := sha256.New() | ||
| hasher.Write([]byte(hashValue)) |
There was a problem hiding this comment.
SHA256 is pretty slow, and we don't need its cryptographic properties. I'd have probably picked FNV (fast and pretty uniform), and then append the row key to final hashed value to guarantee uniqueness.
pkg/chunk/gcp/storage_client.go
Outdated
| func (s *storageClient) NewWriteBatch() chunk.WriteBatch { | ||
| return bigtableWriteBatch{ | ||
| func (s *storageClientV2) NewWriteBatch() chunk.WriteBatch { | ||
| return bigtableWriteBatchV2{ |
There was a problem hiding this comment.
Do we really need two implementations? Or can we abstract away row and column key generation into a set of functions that switch off the flag?
|
|
||
| if len(query.RangeValuePrefix) > 0 { | ||
| rowRange = bigtable.PrefixRange(query.HashValue + separator + string(query.RangeValuePrefix)) | ||
| rOpts = append(rOpts, bigtable.RowFilter(bigtable.ColumnFilter(string(query.RangeValuePrefix)+".*"))) // TODO: Check again and anchor. |
There was a problem hiding this comment.
Hmm yeah this is not particularly desirable. @mbrukman do you know of a better way?
There was a problem hiding this comment.
I'm a bit confused, this is doing a ColumnFilter with a value prefix?
There was a problem hiding this comment.
Yep. We want to filter by prefix.
There was a problem hiding this comment.
I was just confused because this is setting up a filter on column names, but the RangeValuePrefix implies that the filter should be used for values instead.
There was a problem hiding this comment.
This is just a Cortex-ism; our datamodel at this level is super simple, consisting of three-tuples of (hash value, range value, 'cell' value). We always specify the hash value (mapped to the row key in bigtable), want to do range queries over the range value, and equality filtering on the 'cell' value.
Sorry for the confusion.
There was a problem hiding this comment.
Makes sense, thanks for the explanation!
I'm not sure there's a significantly better way to do this... It's probably worth doing this filtering on the bigtable side but, if the amount of data that would get filtered out by this ColumnFilter is small, consider measuring against doing it all client-side.
There was a problem hiding this comment.
I wonder, would it be valid to apply the same trick @bcotton added to the row ranges; use range query from prefix to prefix+null ?
pkg/chunk/gcp/storage_client.go
Outdated
| }, bigtable.RowFilter(bigtable.FamilyFilter(columnFamily))) | ||
| hasher := sha256.New() | ||
| hasher.Write([]byte(query.HashValue)) | ||
| hashValue := string(hasher.Sum(nil)) |
There was a problem hiding this comment.
Would be good to share this with the code to generate the row key for writes.
pkg/chunk/gcp/storage_client.go
Outdated
|
|
||
| for i := range val { | ||
| val[i].Column = strings.TrimPrefix(val[i].Column, columnFamily+":") | ||
| // TODO: Hacky hacky ^ |
There was a problem hiding this comment.
You could push this into the readbatch.RangeValue function (if you want to).
| Name: c.batch[0].tableName, | ||
| ProvisionedRead: 100000, | ||
| ProvisionedWrite: 100000, | ||
| })) |
There was a problem hiding this comment.
Not a huge fan of using the mock store to get the expected result; I think I'd prefer having the test case spell out explicitly what we expect to return.
There was a problem hiding this comment.
Hmm, it actually increases the test verbosity by a fair share. I'd rather add test-cases to increase the confidence in the in-mem version, but it's your call.
|
Done a first pass; let me know when you've addressed the comments. Also, we should test this out and get some performance results before we merge, its not guaranteed to be an improvement. |
Signed-off-by: Goutham Veeramachaneni <cs14btech11014@iith.ac.in>
|
@tomwilkie PTAL. I've addressed most of the comments. I've made it a single implementation as much as possible, but the Where is this queryFn passed? Do we want to have large fn definitions in the struct initialiser? For the tests, I've done testing using the in-mem/Mock implementation for TSDB where the mock has tests to make sure it works as intended. I can do that, or just test the implementation independently. Your call. |
|
What is the status of this PR? |
|
We're testing it this week.
…On Tue, Apr 3, 2018 at 10:44 AM Bryan Boreham ***@***.***> wrote:
What is the status of this PR?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#753 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbGhdTmZ6Vy2IuiPtRrK-sPIco3K9Nxks5tk0RpgaJpZM4StnrB>
.
|
|
How did the testing go? |
|
Looking through this it appears the change is not backwards compatible right now? Did I miss something, or are there plans to use a -from flag? Also, if you need some more testing done, FreshTracks would be happy to help out! |
|
We dropped the ball on this: We did some testing, and couldn't explain a difference (increase) in size in the bigtables. Its still a WIP. |
|
This is block on pushing the schema switching up a layer (to the chunk store) so we can have a migration path, as discussed on a recent community call. |
@tomwilkie Still have TODOs that I want to tackle in refactorings. Also I used SHA256 to hash, let me know if that's okay.
One curious thing to check is the prefix queries, I haven't found anything other than regex to fix that.
/cc @bboreham
This change is