Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

Chunk cache #417

Merged
merged 59 commits into from
Jan 4, 2017
Merged

Chunk cache #417

merged 59 commits into from
Jan 4, 2017

Conversation

replay
Copy link
Contributor

@replay replay commented Dec 7, 2016

Replaces PR #416

@replay replay changed the title Chunk cache [WIP] Chunk cache Dec 7, 2016
func (ig *IterGen) Get() (*Iter, error) {
it, err := tsz.NewIterator(ig.b)
if err != nil {
log.Error(3, "failed to unpack cassandra payload. %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging should be left up to the caller. inside lowlevel structures such as IterGen we can't assume any particular logging approach

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I'll just return the error I got from tsz.NewIterator.

type IterGen struct {
b []byte
ts uint32
len uint64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of having a len attribute and expecting callers of NewGen to provide it, can't we simply have the Length() method return len(ig.b) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally, i'm annoyed I didn't see that.

@@ -7,12 +7,10 @@ import (
// Iter is a simple wrapper around a tsz.Iter to make debug logging easier
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment is no longer true. the purpose is now simply to abstract away go-tsz

itergen iter.IterGen
}

type MetricCache struct {
Copy link
Contributor

@Dieterbe Dieterbe Dec 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this name is a bit confusing. we need a more specific name, perhaps ByMetric (can't come up with anything better for now). or maybe we call this one ChunkCache and what's now ChunkCache could be GlobalChunkCache, or something

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I'm just not sure what to rename it to. I think the name ChunkCache for the most outer scoped struct still makes sense, because it is theoretically possible to have more than one of them (I wouldn't know why).
How about I rename MetricCache to ChunkCacheMetric? I know you don't like long names, but I think it's kind of logical because that makes it clear that this is a more specifically scoped piece that belongs to ChunkCache. To make the names shorter I could also just rename ChunkCache -> CCache & ChunkCacheMetric -> CCacheMetric.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or like we have Aggmetric and Aggmetrics we could do ChunkCache and ChunkCaches

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So how about this:

  • CCache for the whole cache struct
  • CCacheMetric for each of the metrics inside the CCache
  • CCacheChunk for each of the chunks inside a CCacheMetric

That seems quite consistent, not too long, easy to type, easy to understand. Do you think so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

// this assumes we have a lock
func (cc CacheChunk) SetNext(next uint32) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lowercase the method, e.g. setNext, this way it can't be called by code in other packages

@replay
Copy link
Contributor Author

replay commented Dec 8, 2016

I don't want to force push because I don't like changing the past, so I'll just change everything we discussed in the comments and push the changes as a new commit. Once we both agree that this is ready to merge I'll squash them into one.

@replay replay force-pushed the chunk-cache branch 3 times, most recently from 2a9fc82 to 02b8447 Compare December 8, 2016 05:05
return iters, err
}
iters = append(iters, iter.New(it, true))
itergens = append(itergens, iter.NewGen(b[1:], uint32(ts)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should pass the chunks as-is to the itergens. e.g. don't remove the first byte which holds the chunk format. and I think we should leave it up to Iter to inspect the format and call into go-tsz when the format is chunk.FormatStandardGoTsz

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sure. that would probably mean that it makes more sense to move the error definition for errUnknownChunkFormat into iter/itergen.go as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not iter.go?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, they are both the same name space. but the reason why i would put it into itergen.go is because that's where the check happens whether the format is ok or not, right?
The check should be in itergen.go in the initializer NewGen because that's where the iterator also gets instantiated which the gets passed to iter.Iter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i personally would put all tsz and chunk format things in iter.go but if you feel differently about it, then do it your way it doesn't matter much

c.Unlock()
}

c.RLock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c is already rlocked here.

if _, ok := c.metricCache[metric]; !ok {
c.RUnlock()

c.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this a race condition? in between the RUnlock and the Lock another thread could have added the CCacheMetric and perhaps even added chunks to it.
Probably better to just do the ok check and the adding to the map in 1 critical section

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're totally right. I should make these locks less granular

@replay replay force-pushed the chunk-cache branch 7 times, most recently from 415e538 to 67fc9dc Compare December 14, 2016 09:32
@Dieterbe Dieterbe self-assigned this Dec 15, 2016
@Dieterbe Dieterbe added this to the hosted-metrics-alpha milestone Dec 15, 2016
@replay replay force-pushed the chunk-cache branch 5 times, most recently from ea2a343 to 3752791 Compare December 19, 2016 07:13
@@ -384,6 +385,8 @@ func main() {
/***********************************
Initialize our MetricIdx
***********************************/
cache := cache.NewCCache()
metrics = mdata.NewAggMetrics(store, chunkSpan, numChunks, chunkMaxStale, metricMaxStale, ttl, gcInterval, finalSettings)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right. why is the diff adding a NewAggMetrics() line but not removing one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, i think i messed up a rebase there. fixing

if err != nil {
log.Error(3, "failed to unpack cassandra payload. %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we not log the error we get back anymore?

@Dieterbe
Copy link
Contributor

Dieterbe commented Jan 4, 2017

in 4cb3845 you re-introduced a bug that you had fixed, we now add to cache again before the check that a chunk is not corrupt

replay and others added 21 commits January 5, 2017 00:08
also fixes a bug that has been found by the new test added in this
commit
adds a new target to the make file which calles build.sh and
build_tools.sh with -race. this makes them use the race flag.
this is a bit more clear that "endTs" is really the ts that is the
beginning of the next chunk.
If we used continuous math (and/or if everyone thought of our timestamps
as continuous) then we could have used the same name.

However since our timestamps are discrete and at second resolution,
it's more clear this way. (the end of a chunk is one second prior to the
t0 of the next)
- improves the getSeries test to go through various combinations of
  datasources
- moves cache and cache accounting into interfaces
- adds an EndTs() method to chunk.IterGen
- adds Stop() method to accounting and cache to stop their go routines
if an itergen that has been returned by the store is invalid, then do
not add it to the cache
@Dieterbe Dieterbe merged commit a2679fd into master Jan 4, 2017
@Dieterbe Dieterbe deleted the chunk-cache branch December 15, 2017 22:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants