Skip to content

Commit

Permalink
Add test & update docs
Browse files Browse the repository at this point in the history
Signed-off-by: Povilas Versockas <p.versockas@gmail.com>
  • Loading branch information
povilasv committed Aug 27, 2019
1 parent 9a8d8ab commit 9a8a2ae
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 40 deletions.
8 changes: 5 additions & 3 deletions docs/components/store.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,16 @@ Flags:

By default Thanos Store Gateway looks at all the data in Object Store and returns it based on query's time range.

Thanos Store `--min-time`, `--max-time` flags allows you to shard Thanos Store based on constant time or time duration relative to current time.
Thanos Store `--min-time`, `--max-time` flags allows you to shard Thanos Store based on constant time or time duration relative to current time.

For example setting: `--min-time=-6w` & `--max-time==-2w` will make Thanos Store Gateway return metrics that fall within `now - 6 weeks` up to `now - 2 weeks` time range.

Constant time needs to be set in RFC3339 format. For example `--min-time=2018-01-01T00:00:00Z`, `--max-time=2019-01-01T23:59:59Z`.

Thanos Store Gateway might not see new blocks immediately, as Time partitioning is partly done in asynchronous block sync job, which is refreshed every 3 minutes by default. Additionally some of the Object Store implementations provide eventual read-after-write consistency, which means that Thanos Store might not immediately see newly created & uploaded blocks anyway.
Thanos Store Gateway might not get new blocks immediately, as Time partitioning is partly done in asynchronous block synchronization job, which is by default done every 3 minutes. Additionally some of the Object Store implementations provide eventual read-after-write consistency, which means that Thanos Store might not immediately get newly created & uploaded blocks anyway.

So we recommend having overlapping time ranges with Thanos Sidecar and other Thanos Store gateways as this will improve your resiliency to failures.
We recommend having overlapping time ranges with Thanos Sidecar and other Thanos Store gateways as this will improve your resiliency to failures.

Thanos Querier deals with overlapping time series by merging them together.

Filtering is done on a Chunk level, so Thanos Store might still return Samples which are outside of `--min-time` & `--max-time`.
65 changes: 28 additions & 37 deletions pkg/store/bucket_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/go-kit/kit/log"
"github.com/oklog/ulid"
"github.com/pkg/errors"
prommodel "github.com/prometheus/common/model"
"github.com/prometheus/prometheus/pkg/timestamp"
"github.com/prometheus/tsdb/labels"
"github.com/thanos-io/thanos/pkg/block"
Expand Down Expand Up @@ -456,85 +455,77 @@ func TestBucketStore_ManyParts_e2e(t *testing.T) {
}

func TestBucketStore_TimePartitioning_e2e(t *testing.T) {
bkt := inmem.NewBucket()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
bkt := inmem.NewBucket()

dir, err := ioutil.TempDir("", "test_bucket_time_part_e2e")
testutil.Ok(t, err)
defer func() { testutil.Ok(t, os.RemoveAll(dir)) }()

series := []labels.Labels{
labels.FromStrings("a", "1", "b", "1"),
labels.FromStrings("a", "1", "b", "1"),
labels.FromStrings("a", "1", "b", "1"),
labels.FromStrings("a", "1", "b", "1"),
labels.FromStrings("a", "1", "b", "2"),
labels.FromStrings("a", "2", "b", "1"),
labels.FromStrings("a", "2", "b", "2"),
labels.FromStrings("a", "1", "c", "1"),
labels.FromStrings("a", "1", "c", "2"),
labels.FromStrings("a", "2", "c", "1"),
labels.FromStrings("a", "2", "c", "2"),
labels.FromStrings("a", "1", "b", "2"),
labels.FromStrings("a", "1", "b", "2"),
labels.FromStrings("a", "1", "b", "2"),
}
extLset := labels.FromStrings("ext1", "value1")

_, minTime, maxTime := prepareTestBlocks(t, time.Now(), 3, dir, bkt, series, extLset)
_, minTime, _ := prepareTestBlocks(t, time.Now(), 3, dir, bkt, series, extLset)

hourAfterDur := prommodel.Duration(1 * time.Hour)
hourAfter := model.TimeOrDurationValue{Dur: &hourAfterDur}
hourAfter := time.Now().Add(1 * time.Hour)
filterMaxTime := model.TimeOrDurationValue{Time: &hourAfter}

store, err := NewBucketStore(nil, nil, inmem.NewBucket(), dir, noopCache{}, 0, 0, 20, false, 20,
store, err := NewBucketStore(nil, nil, bkt, dir, noopCache{}, 0, 0, 20, false, 20,
&FilterConfig{
MinTime: minTimeDuration,
MaxTime: hourAfter,
MaxTime: filterMaxTime,
})
testutil.Ok(t, err)

err = store.InitialSync(ctx)
err = store.SyncBlocks(ctx)
testutil.Ok(t, err)

mint, maxt := store.TimeRange()
testutil.Equals(t, minTime, mint)
testutil.Equals(t, maxTime, maxt)

vals, err := store.LabelValues(ctx, &storepb.LabelValuesRequest{Label: "a"})
testutil.Ok(t, err)
testutil.Equals(t, []string{"1", "2"}, vals.Values)
testutil.Equals(t, filterMaxTime.PrometheusTimestamp(), maxt)

for i, tcase := range []struct {
req *storepb.SeriesRequest
expected [][]storepb.Label
req *storepb.SeriesRequest
expectedLabels [][]storepb.Label
expectedChunks int
}{
{
req: &storepb.SeriesRequest{
Matchers: []storepb.LabelMatcher{
{Type: storepb.LabelMatcher_RE, Name: "a", Value: "1|2"},
{Type: storepb.LabelMatcher_EQ, Name: "a", Value: "1"},
},
MinTime: mint,
MaxTime: maxt,
MaxTime: timestamp.FromTime(time.Now().AddDate(0, 0, 1)),
},
expected: [][]storepb.Label{
expectedLabels: [][]storepb.Label{
{{Name: "a", Value: "1"}, {Name: "b", Value: "1"}, {Name: "ext1", Value: "value1"}},
{{Name: "a", Value: "1"}, {Name: "b", Value: "2"}, {Name: "ext1", Value: "value1"}},
{{Name: "a", Value: "1"}, {Name: "c", Value: "1"}, {Name: "ext2", Value: "value2"}},
{{Name: "a", Value: "1"}, {Name: "c", Value: "2"}, {Name: "ext2", Value: "value2"}},
{{Name: "a", Value: "2"}, {Name: "b", Value: "1"}, {Name: "ext1", Value: "value1"}},
{{Name: "a", Value: "2"}, {Name: "b", Value: "2"}, {Name: "ext1", Value: "value1"}},
{{Name: "a", Value: "2"}, {Name: "c", Value: "1"}, {Name: "ext2", Value: "value2"}},
{{Name: "a", Value: "2"}, {Name: "c", Value: "2"}, {Name: "ext2", Value: "value2"}},
{{Name: "a", Value: "1"}, {Name: "b", Value: "2"}, {Name: "ext2", Value: "value2"}},
},
// prepareTestBlocks makes 3 chunks containing 2 hour data,
// we should only get 1, as we are filtering.
expectedChunks: 1,
},
} {
t.Log("Run ", i)
t.Log("Run", i)

srv := newStoreSeriesServer(ctx)

testutil.Ok(t, store.Series(tcase.req, srv))
testutil.Equals(t, len(tcase.expected), len(srv.SeriesSet))
testutil.Equals(t, len(tcase.expectedLabels), len(srv.SeriesSet))

for i, s := range srv.SeriesSet {
testutil.Equals(t, tcase.expected[i], s.Labels)
testutil.Equals(t, 3, len(s.Chunks))
testutil.Equals(t, tcase.expectedLabels[i], s.Labels)
testutil.Equals(t, tcase.expectedChunks, len(s.Chunks))
}

}
}

0 comments on commit 9a8a2ae

Please sign in to comment.