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

Ability to use multiple storage types #880

Merged
merged 8 commits into from
Jun 29, 2018

Conversation

davit-y
Copy link
Contributor

@davit-y davit-y commented Jun 22, 2018

Which problem is this PR solving?

Short description of the changes

  • Adding ability to specify multiple storage types
  • All listed storage types are used for writing
  • In the case of multiple storage types, the first is used for Reading and by the ArchiveSpanWriter

@davit-y davit-y changed the title Multi storage Ability to Use Multiple Storage Types Jun 22, 2018
@davit-y davit-y changed the title Ability to Use Multiple Storage Types Ability to use multiple storage types Jun 22, 2018
@codecov
Copy link

codecov bot commented Jun 22, 2018

Codecov Report

Merging #880 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #880   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files         126    126           
  Lines        6053   6068   +15     
=====================================
+ Hits         6053   6068   +15
Impacted Files Coverage Δ
plugin/storage/factory.go 100% <100%> (ø) ⬆️
plugin/storage/factory_config.go 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3884950...71434f4. Read the comment docs.

@@ -151,9 +162,13 @@ func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) {

// CreateArchiveSpanWriter implements storage.ArchiveFactory
func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) {
factory, ok := f.factories[f.SpanStorageType]
if len(f.SpanWriterTypes) > 1 {
fmt.Fprintf(f.log, "WARNING: Since there are multiple span storage types,"+
Copy link
Member

Choose a reason for hiding this comment

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

factory should have access to logger. Don't use printf.

SpanStorageTypeEnvVar = "SPAN_STORAGE_TYPE"

// SpanReaderTypeEnvVar is the optional env var that defines the type of backend used for span reading in the case of multi-storage.
SpanReaderTypeEnvVar = "SPAN_READER_TYPE"
Copy link
Member

Choose a reason for hiding this comment

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

have you tried without introducing this new config? What's not working without it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we can't have a CompositeReader, in the case of multiple storage types we must decide on 1 storage to read from. At the moment, the first listed storage type is used and a warning is emitted, but the extra flag allows users to specify the storage so that they don't have to be concerned with the order of their inputted storage types.

Copy link
Member

Choose a reason for hiding this comment

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

but the extra flag allows users to specify the storage so that they don't have to be concerned with the order of their inputted storage types.

I suggest removing this optional behavior - the same can be achieved by reordering items in the main storage type var without additional code.

Copy link
Contributor

Choose a reason for hiding this comment

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

the same can be achieved by reordering items in the main storage type var without additional code.

I'm not a fan of this non user friendly behavior where the user has to know the ordering of the flags, the new variable makes it explicit.

Copy link
Member

Choose a reason for hiding this comment

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

I can argue it's simpler to reorder values in one env vars then pass two env vars. The flag description can explain it. Not to mention that this whole scenario is only applicable to all-in-one, which nobody should be running with real storage anyway. So I am 👎 on adding extra complication to the code for this marginal use case (the diff size would probably be 1/2 of what it's now without this).

Copy link
Contributor

Choose a reason for hiding this comment

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

gonna be a pedant and not forward this conversation in anyway; the ingester will read from kafka and write to kafka/cassandra, this won't be just a marginal use case. As a user, I'd prefer a second explicit flag.

Copy link
Member

Choose a reason for hiding this comment

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

fair point. What about topic names in this case? It sounds like we'd need separate configuration for reader / writer. In theory this always could've been the case even with other storages (write to one cluster/keyspace, read from another), but in case of Kafka this is more obvious.

So if you want to go with extra variable, then it should be symmetric, reader AND writer. Same for dependencies. It sounds like we need a whole overhaul of the storage configurations.

DependenciesStorageType string
log io.Writer
Copy link
Member

Choose a reason for hiding this comment

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

?

we use *zap.Logger for logging.

token,
SpanStorageTypeEnvVar,
)
logger.Warn("found deprecated command line option " + token +
Copy link
Member

Choose a reason for hiding this comment

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

sorry, I didn't realize we already use this io.Writer. Let's continue using it instead of creating redundant logger in all mains.

fmt.Fprintf(log, "WARNING: Since multiple storage types have been listed,"+
"the first span storage type listed (%s) will be used for reading and archiving.", spanWriterTypes[0])
}
depStorageType := os.Getenv(DependencyStorageTypeEnvVar)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this come from viper?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All the main.go files initialize viper after setting up this initial factory.

Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, but sounds odd... @yurishkuro, @black-adder, is there a reason why both the main storage and the strategy storage factories are initialized before viper? They are consumed only way after...

Copy link
Contributor

Choose a reason for hiding this comment

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

If the factories can be created within the Cobra's command, it can also receive a zap.Logger, avoiding the usage of fmt.Fprintf

Copy link
Member

Choose a reason for hiding this comment

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

The reason is to avoid each storage type adding it's flags to cli

Copy link
Contributor

Choose a reason for hiding this comment

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

That affects only the contents of --help, right?

Copy link
Member

Choose a reason for hiding this comment

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

yes

depStoreType = spanStorageType
spanWriterTypes := strings.Split(spanStorageType, ",")
if len(spanWriterTypes) > 1 {
fmt.Fprintf(log, "WARNING: Since multiple storage types have been listed,"+
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like this warning could be easily missed.
Is it difficult to require the user to explicitly specify a read and archive storage type when multiple storage types are specified?

Copy link
Member

Choose a reason for hiding this comment

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

we discussed this offline and decided to defer this to later changes when the ingester is implemented. We would like to merge this s that we can publish a new release with Kafka writer support (just to allow people to do data mining).

}
return factory.CreateSpanWriter()
return spanstore.NewCompositeWriter(writers...), nil
Copy link
Member

Choose a reason for hiding this comment

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

do we want to short-circuit here for len(writers)==1 by returning the one underlying writer? Composite writer adds perf and cognitive overhead when it's not needed.

depStoreType = spanStorageType
spanWriterTypes := strings.Split(spanStorageType, ",")
if len(spanWriterTypes) > 1 {
fmt.Fprintf(log, "WARNING: Since multiple storage types have been listed,"+
Copy link
Member

Choose a reason for hiding this comment

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

we discussed this offline and decided to defer this to later changes when the ingester is implemented. We would like to merge this s that we can publish a new release with Kafka writer support (just to allow people to do data mining).

fmt.Fprintf(log, "WARNING: Since multiple storage types have been listed,"+
"the first span storage type listed (%s) will be used for reading and archiving.", spanWriterTypes[0])
}
depStorageType := os.Getenv(DependencyStorageTypeEnvVar)
Copy link
Member

Choose a reason for hiding this comment

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

yes

SpanStorageType: spanStorageType,
DependenciesStorageType: depStoreType,
SpanWriterTypes: spanWriterTypes,
SpanReaderType: spanWriterTypes[0],
Copy link
Member

Choose a reason for hiding this comment

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

add // TODO support explicit configuration for readers - maybe book an issue & describe our offline discussions so far.

black-adder and others added 7 commits June 28, 2018 17:22
Signed-off-by: Won Jun Jang <wjang@uber.com>
Signed-off-by: Won Jun Jang <wjang@uber.com>
Signed-off-by: Davit Yeghshatyan <davo@uber.com>
Signed-off-by: Davit Yeghshatyan <davo@uber.com>
This reverts commit 57dd2a4

Signed-off-by: Davit Yeghshatyan <davo@uber.com>
Signed-off-by: Davit Yeghshatyan <davo@uber.com>
Signed-off-by: Davit Yeghshatyan <davo@uber.com>
Signed-off-by: Davit Yeghshatyan <davo@uber.com>
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.

None yet

5 participants