Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Downsampling writer that drop a percentage of spans #1353

Merged
merged 20 commits into from
Mar 12, 2019
Merged

Add a Downsampling writer that drop a percentage of spans #1353

merged 20 commits into from
Mar 12, 2019

Conversation

guanw
Copy link
Contributor

@guanw guanw commented Feb 15, 2019

Accidentally removed my forked jaeger project so have to create this new pull request..

Which problem is this PR solving?

Short description of the changes

  • Instead of doing ratelimiting based on the volume, simply adding DownSamplingWriter to wrap other writers so user could specify a float ratio number between 0 ~ 1.0 to drop certain percentage of spans.

Ratio parameter is specified by passing DOWN_SAMPLING_RATIO as env variable.

plugin/storage/factory.go Show resolved Hide resolved
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/utils.go Outdated Show resolved Hide resolved
storage/spanstore/utils.go Outdated Show resolved Hide resolved
@guanw guanw changed the title Judew auto drop index Adding a DownSampling writer that automatic drop spans Feb 15, 2019
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_test.go Outdated Show resolved Hide resolved
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
storage/spanstore/utils.go Outdated Show resolved Hide resolved
storage/spanstore/utils.go Outdated Show resolved Hide resolved
storage/spanstore/utils.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_test.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_test.go Outdated Show resolved Hide resolved
Copy link
Contributor Author

@guanw guanw left a comment

Choose a reason for hiding this comment

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

@yurishkuro I tried running some benchmark against sync.Pool, something like the following two.
image
image

Against another version where I just use mutex for locking, it seems the simple mutex beats sync.Pool in both scenarios. I think using sync.Pool here is not necessary since we don't need to do fnv.New64a() everytime hashing: Just need to do fnv.reset() to reset it which doesn't involve memory allocation thus sync.Pool won't help here?(But I might be wrong) So i prefer we just use mutex here.

Ran a benchmark against both mutex and sync.Pool versions that spawns 50000 goroutines where each goroutine WriteSpan 10000 times
(writeSpan is mutex version and writeSpan2 is sync.Pool version)
image

image

plugin/storage/factory.go Show resolved Hide resolved
Copy link
Contributor

@black-adder black-adder left a comment

Choose a reason for hiding this comment

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

mutex looks good.

storage/spanstore/utils.go Outdated Show resolved Hide resolved
@yurishkuro
Copy link
Member

You should use reset() even with the pool. The point of the pool is to avoid memory allocations.

But in any case, we have an issue with the overall design where we run many go-routines working independently on saving spans, but we have these synchronization points like your mutex that block all writers for little reason. Unfortunately, fixing this requires significant re-design where we create writers per goroutine.

Given that both the explicit mutex and sync.Pool introduce a critical section, the main benefit of the pool should be in avoiding memory allocations while unblocking other goroutines invoking the hash. If you're not getting the benefits of the sync pool with your benchmark, I suspect the benchmark.

@black-adder
Copy link
Contributor

@guanw can you add your benchmarks so we can see? In your benchmark you maybe creating threads but not actually waiting for them to run before the benchmark resolves.

@yurishkuro You _should_ use reset() why?

@black-adder
Copy link
Contributor

If it's some crap about how one day aliens will invade and the underlying implementation will in the future require you to call reset before every call so we should prepare for it now...

@yurishkuro
Copy link
Member

@yurishkuro You _should_ use reset() why?

as alternative to allocating a new buffer

@black-adder
Copy link
Contributor

@yurishkuro You _should_ use reset() why?

as alternative to allocating a new buffer

The underlying implementation of the hash is:

func (s *sum64a) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash ^= sum64a(c)
		hash *= prime64
	}
	*s = hash
	return len(data), nil
}

where

type (
	sum64a  uint64
)

The underlying hash function doesn't use a buffer for representation. All reset does is:

func (s *sum64a) Reset()  { *s = 14695981039346656037 }

@guanw
Copy link
Contributor Author

guanw commented Feb 20, 2019

I tried moving the fnv hash logic directly to our code and get rid of the sync.pool. It reduces the benchmark runtime 5x, I think we could just go with that?

@guanw
Copy link
Contributor Author

guanw commented Feb 20, 2019

actually ignore my last comment. I'm still going with sync.Pool.

Copy link
Contributor

@black-adder black-adder left a comment

Choose a reason for hiding this comment

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

do we have 100 code coverage?

plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory_test.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_benchmark_test.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_benchmark_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@black-adder black-adder left a comment

Choose a reason for hiding this comment

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

nearly there

storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
return math.MaxUint64
}
return h.Sum64()
//Currently fnv.Write() doesn't throw any error so metrics is not necessary here.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: space between // and Currently

Copy link
Contributor

Choose a reason for hiding this comment

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

also, linter might complain that we are swallowing the error.

storage/spanstore/downsampling_writer_benchmark_test.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Show resolved Hide resolved
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
plugin/storage/factory_config.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
}

var instance *poolSingleton
var once sync.Once
Copy link
Member

Choose a reason for hiding this comment

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

Pools should be fields of the factory, not globals. Pointers are not needed.

Copy link
Contributor Author

@guanw guanw Feb 25, 2019

Choose a reason for hiding this comment

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

Not sure I got the first part. Here instance is lowercase so it won't be exposed to other files. In factory.go the default is to disable DownsamplingWriter entirely so doesn't make sense to create pool there if we are not using downsamplingWriter as default?

I will get rid of the pointer though.

storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_benchmark_test.go Outdated Show resolved Hide resolved
plugin/storage/factory_test.go Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
return ds.spanWriter.WriteSpan(span)
}

//hashBytes returns the uint64 hash value of bytes slice.
Copy link
Contributor

Choose a reason for hiding this comment

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

ping

storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_benchmark_test.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_benchmark_test.go Outdated Show resolved Hide resolved
@guanw
Copy link
Contributor Author

guanw commented Feb 27, 2019

@yurishkuro @black-adder @vprithvi Any more comments on this one?

@guanw
Copy link
Contributor Author

guanw commented Mar 4, 2019

@yurishkuro any more comments on this?

plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
@guanw
Copy link
Contributor Author

guanw commented Mar 7, 2019

@yurishkuro updated.

@guanw
Copy link
Contributor Author

guanw commented Mar 8, 2019

@yurishkuro Please let me know if you have any more comments.

storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
plugin/storage/factory.go Show resolved Hide resolved
plugin/storage/factory_test.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer.go Outdated Show resolved Hide resolved
storage/spanstore/downsampling_writer_test.go Show resolved Hide resolved
storage/spanstore/downsampling_writer_test.go Show resolved Hide resolved
@yurishkuro yurishkuro changed the title Adding a DownSampling writer that automatic drop spans Add a Downsampling writer that drop a percentage of spans Mar 11, 2019
Jude Wang added 20 commits March 11, 2019 17:11
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
Signed-off-by: Jude Wang <[email protected]>
@yurishkuro yurishkuro merged commit 19b6807 into jaegertracing:master Mar 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a rate limiter to jaeger-ingester
4 participants