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

added redis storage option #96

Merged
merged 2 commits into from
Mar 15, 2018
Merged

added redis storage option #96

merged 2 commits into from
Mar 15, 2018

Conversation

heltonmarx
Copy link
Contributor

Inserted as a storage option the use of Redis, passing through Builder the redis client.

Please, any suggestions will always be welcome.

@db7
Copy link
Collaborator

db7 commented Mar 2, 2018

Really nice contribution! Thanks for taking the time.

I have a couple of comments:

  • I think it would be better to create a subpackage storage/redis and put this code there, otherwise the Redis client will become a default dependency.
  • the keys stored in Redis need to be made disjoint from other possible applications writing to the same Redis instance. I'd suggest prefixing keys with something like namespace:table:partition:.
    • namespace should distinguish applications that write to the same keys
    • table should distinguish multiple tables in the same application that write to the same keys
    • partition should guarantee that partitions don't overwrite each other. Actually that is already the case due to the hasher that splits the key space in partitions, but all partitions have at least one key in common called __offset_key, which stores the latest offset of the partition for recovery. If this gets overwritten, partitions will be recovered incorrectly.
    • You can pass these options in the builder.

And I saw that you have added a retention to the entries in Redis. What is the intention of expiring the entries? Is this to be used in combination with a retention in Kafka too? I think one should have the option of setting no retention (it seems to be mandatory now).

func RedisBuilder(client *redis.Client, namespace string) storage.Builder {
return func(topic string, partition int32) (storage.Storage, error) {
if namespace == "" {
namespace = strconv.FormatInt(time.Now().UnixNano(), 10)
Copy link
Contributor

@SamiHiltunen SamiHiltunen Mar 7, 2018

Choose a reason for hiding this comment

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

It would be better to return an error here and make the namespace a required parameter. Using the time as the namespace would mean that the application has to recover on every launch and leave a lot of obsolete data from previous runs in Redis.

}

// NewRedis creates a new Storage backed by Redis.
func NewRedis(client *redis.Client, hash string) (storage.Storage, error) {
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 remove the Redis suffixes and prefixes from the types and methods as the package path and name implies this is a Redis storage for Goka. I think it would be cleaner to have redis.New.


// Close removes all data present current hash(`namespace:table:partition`)
// instead closing the redis client.
func (s *redisStorage) Close() error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Close should close the client and leave the data in Redis. Deleting the data on close would force the applications to recover their state on every launch and this is not in line with the other storage implementations. Functionality for cleaning the state from Redis would definitely be a convenient addition but I would move it to a separate method.

Copy link
Collaborator

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 it is deleting the data, but I don't think that Close should actually close the client too. The caller should care about closing the client since the Redis client is passed to the storage builder and all partitions share the same client.

Copy link
Contributor

Choose a reason for hiding this comment

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

I completely overlooked that part. Even if it wasn't shared with other builders, it would be better to leave it to caller who built the client.

Copy link
Contributor Author

@heltonmarx heltonmarx Mar 7, 2018

Choose a reason for hiding this comment

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

I put this delete here, 'cause I thought that when you close a partition, you would not use it anymore by this consumer. But probably I thought on the wrong direction.

Copy link
Collaborator

@db7 db7 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!

@db7 db7 merged commit 2c9e0f5 into lovoo:master Mar 15, 2018
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.

3 participants