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

Support Snappy compression for gRPC #2940

Merged
merged 15 commits into from
Jul 31, 2020

Conversation

Wing924
Copy link
Contributor

@Wing924 Wing924 commented Jul 28, 2020

What this PR does:

Add snappy compression for gRPC.

Which issue(s) this PR fixes:
Fixes #2898

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

Signed-off-by: Wing924 <[email protected]>
Copy link
Contributor

@pstibrany pstibrany left a comment

Choose a reason for hiding this comment

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

Thank you for your work! It looks good. I've left some comments here and there, but nothing major.

func (cfg *Config) Validate(log log.Logger) error {
if cfg.UseGzipCompression {
flagext.DeprecatedFlagsUsed.Inc()
level.Warn(log).Log("msg", "flag *.grpc-use-gzip-compression (or config use_gzip_compression) is deprecated, use *.grpc-use-compression instead.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if it's a good idea, but we could save the prefix in RegisterFlagsWithPrefix, and then report full flag name here.

@bboreham
Copy link
Contributor

bboreham commented Jul 28, 2020

Could you give specific numbers for the benchmarks - looks like a 40% reduction in distributor CPU usage traded for a 150% change in network bandwidth? (comparing gzip and snappy).

@Wing924
Copy link
Contributor Author

Wing924 commented Jul 29, 2020

benchmark result

resource none gzip snappy none -> gzip none -> snappy gzip -> snappy
distributor cpu 23% 40% 25% +74% +8% -38%
ingester cpu 43% 46% 49% +6% +13% +7%
distributor network 74Mbps 8.2Mbps 12Mbps -88% -83% +46%
ingester network 93Mbps 6.5Mbps 12Mbps -93% -87% +84%

@Wing924
Copy link
Contributor Author

Wing924 commented Jul 29, 2020

@pstibrany I've fixed it. Could you review it again?

Copy link
Contributor

@pstibrany pstibrany left a comment

Choose a reason for hiding this comment

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

Thank you very much for addressing my feedback. I have left some more small comments. Can you please take a look?

CHANGELOG.md Outdated
Comment on lines 43 to 49
* [ENHANCEMENT/CHANGE] Added new flags `-*.grpc-compression` to configure compression used by gRPC. Valid values are "gzip", "snappy", "" (no compression, default). Previous flags (`-*.use-gzip-compression`, enumerate) are now deprecated. #2940
* `-bigtable.grpc-compression`
* `-ingester.client.grpc-compression`
* `-querier.frontend-client.grpc-compression`
* Deprecated: `-bigtable.grpc-use-gzip-compression`
* Deprecated: `-ingester.client.grpc-use-gzip-compression`
* Deprecated: `-querier.frontend-client.grpc-use-gzip-compression`
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* [ENHANCEMENT/CHANGE] Added new flags `-*.grpc-compression` to configure compression used by gRPC. Valid values are "gzip", "snappy", "" (no compression, default). Previous flags (`-*.use-gzip-compression`, enumerate) are now deprecated. #2940
* `-bigtable.grpc-compression`
* `-ingester.client.grpc-compression`
* `-querier.frontend-client.grpc-compression`
* Deprecated: `-bigtable.grpc-use-gzip-compression`
* Deprecated: `-ingester.client.grpc-use-gzip-compression`
* Deprecated: `-querier.frontend-client.grpc-use-gzip-compression`
* [ENHANCEMENT] Added new flags `-bigtable.grpc-compression`, `-ingester.client.grpc-compression`, `-querier.frontend-client.grpc-compression` to configure compression used by gRPC. Valid values are `gzip`, `snappy`, or empty string (no compression, default). #2940
* [CHANGE] Flags `-bigtable.grpc-use-gzip-compression`, `-ingester.client.grpc-use-gzip-compression`, `-querier.frontend-client.grpc-use-gzip-compression` are now deprecated. #2940

(Note that they should be moved to their respective sections)

Comment on lines 61 to 62
*compressor
*snappy.Writer
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer to avoid nameless embeds. They expose more methods than intended (writeCloser now has methods like Name and Compress), and may inadvertently implement methods that were not meant to be implemented.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment applies to reader.

func (cfg *Config) Validate(log log.Logger) error {
if cfg.UseGzipCompression {
flagext.DeprecatedFlagsUsed.Inc()
level.Warn(log).Log("msg", fmt.Sprintf("running with DEPRECATED flag -%s.grpc-use-gzip-compression, use -%s.grpc-use-compression instead.", cfg.prefix, cfg.prefix))
Copy link
Contributor

Choose a reason for hiding this comment

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

should be ... use -%s.grpc-compression now.

Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

Amazing job, thanks! I left few comments (other than Peter's ones) but I believe we're on a very good track 👏

@@ -15,11 +20,14 @@ type Config struct {
MaxRecvMsgSize int `yaml:"max_recv_msg_size"`
MaxSendMsgSize int `yaml:"max_send_msg_size"`
UseGzipCompression bool `yaml:"use_gzip_compression"`
Compression string `yaml:"compression"`
Copy link
Contributor

Choose a reason for hiding this comment

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

CLI flags and YAML config option names should match.

Suggested change
Compression string `yaml:"compression"`
Compression string `yaml:"grpc_compression"`

level.Warn(log).Log("msg", fmt.Sprintf("running with DEPRECATED flag -%s.grpc-use-gzip-compression, use -%s.grpc-use-compression instead.", cfg.prefix, cfg.prefix))
}
switch cfg.Compression {
case "gzip", "snappy", "":
Copy link
Contributor

Choose a reason for hiding this comment

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

I would use snappy.Name instead of the hardcoded "snappy" given we have the constant.

Copy link
Contributor

Choose a reason for hiding this comment

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

So this made me go back and look why I didn't use gzip.Name, and it turns out it didn't exist at the time.

Comment on lines 61 to 62
*compressor
*snappy.Writer
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment applies to reader.

@@ -105,6 +105,9 @@ func (cfg *Config) Validate() error {
if err := cfg.CassandraStorageConfig.Validate(); err != nil {
return errors.Wrap(err, "invalid Cassandra Storage config")
}
if err := cfg.GCPStorageConfig.Validate(util.Logger); err != nil {
return errors.Wrap(err, "invalid GCP Storage Storage config")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return errors.Wrap(err, "invalid GCP Storage Storage config")
return errors.Wrap(err, "invalid GCP Storage config")

Wing924 added 5 commits July 30, 2020 09:45
Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
Copy link
Contributor

@pstibrany pstibrany left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my feedback.

func (r *reader) Read(p []byte) (n int, err error) {
n, err = r.Reader.Read(p)
if err == io.EOF {
r.pool.Put(r)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: should we reset snappy.Reader with nil reader before putting back to pool? (same for writer) It would be little more correct to avoid keeping reference to just-read underlying reader, but likely not a big problem as they will be reused all the time.

}

type reader struct {
*snappy.Reader
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: These anonymous embeds now expose snappy.Reader methods. It doesn't even bring anything, as Read is fully reimplemented by reader. In writeCloser it saves reimplementing Write method, although I would still prefer to be explicit. Not a blocker for merging.

Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

Nice job! I have last few comments (+ Peter's nits) and then we're good to go 🚀

# Use compression when sending messages. Supported values are: 'gzip',
# 'snappy' and '' (disable compression)
# CLI flag: -bigtable.grpc-compression
[compression: <string> | default = ""]
Copy link
Contributor

Choose a reason for hiding this comment

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

I would expect this to be grpc_compression. I'm not sure why the CI linter passed. Could you run make doc again, please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as you may know, CI don't run.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I haven't noticed! Can't understand why the CI is not running on this specific PR 👀

if cfg.UseGzipCompression {
opts = append(opts, grpc.UseCompressor("gzip"))
compression = "gzip"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
compression = "gzip"
compression = gzip.Name

@@ -15,6 +21,7 @@ type Config struct {
MaxRecvMsgSize int `yaml:"max_recv_msg_size"`
MaxSendMsgSize int `yaml:"max_send_msg_size"`
UseGzipCompression bool `yaml:"use_gzip_compression"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
UseGzipCompression bool `yaml:"use_gzip_compression"`
UseGzipCompression bool `yaml:"use_gzip_compression"` // TODO: Remove this deprecated option in v1.6.0.

Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

I don't know why, but CI is not running on this PR. I'm falling it as "request changes" because we need to get the CI pass before merging.

Signed-off-by: Wing924 <[email protected]>
@pracucci pracucci force-pushed the support_snappy_grpc branch from 2f15674 to 47d77a0 Compare July 31, 2020 08:44
@pracucci
Copy link
Contributor

I don't know why, but CI is not running on this PR. I'm falling it as "request changes" because we need to get the CI pass before merging.

I've found the issue. Your PR description contained some characters スクリーンショット  which apparently cause the CircleCI webhook to return 400. I've removed them and force pushed to trigger the CI.

FYI, I've rebased the last commit to reword the commit message by 1 character and git push --force it in order to trigger the CI again.

Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

LGTM! One final nit and we should be good to go 😎

@pstibrany
Copy link
Contributor

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] support snappy compressor for gRPC
5 participants