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

docs: add the design document of Warehouse #114

Merged
merged 2 commits into from
Nov 23, 2021
Merged

docs: add the design document of Warehouse #114

merged 2 commits into from
Nov 23, 2021

Conversation

huachaohuang
Copy link
Contributor

@huachaohuang huachaohuang commented Nov 17, 2021

The semantics of Warehouse is useful to build some analytical databases like Snowflake and DeltaLake.

Warehouse

@huachaohuang huachaohuang added this to the Version 0.2 milestone Nov 17, 2021
@huachaohuang huachaohuang marked this pull request as draft November 17, 2021 13:09
@huachaohuang huachaohuang marked this pull request as ready for review November 18, 2021 09:09
When a client connects to Warehouse, it gets the last version from Warehouse as its base version and then subscribes to delta versions.
When a delta version arrives, the client applies it to the base version to catch up with Warehouse.
The client can maintain a list of live versions for ongoing queries and release a version once it is no longer required.
Warehouse guarantees that objects recorded in all client versions remain valid until the corresponding versions are released.
Copy link
Contributor

Choose a reason for hiding this comment

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

how do warehouses know "all client candidates"~? maybe the client can be temp leave or be network partition, it seems not simple to know "all live client released the version" :)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the implementation will be similar to a distributed lock or leases in etcd. Clients need to communicate with Warehouse to keep their versions alive.

It maintains multiple versions of metadata. Each version represents a snapshot of metadata at a specific time.
Each metadata transaction (add or remove objects) creates a delta version that transforms the last version into a new one.
When a client connects to Warehouse, it gets the last version from Warehouse as its base version and then subscribes to delta versions.
When a delta version arrives, the client applies it to the base version to catch up with Warehouse.
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO, reverse synced version info just used to let client can release version? how about query & modification arrival client during "un-catch up" time period? I guess they should not take care about those reverse synced version? (if so maybe read stale data and inconsistent between different warehouse client component)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think I understand the questions. Specifically, what does "reverse synced version" mean?

Copy link
Contributor

@tisonkun tisonkun 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 submitting this PR! Comments inline.

Also \n in markdown without a blank line won't start a new line, you can check the rendered version and I think it's the primarily used version that we should take care of. I don't insert a line break without a blank line :P

Warehouse stores object data in Storage and stores object metadata in Manifest.

To add objects to Warehouse, a client uploads objects to Storage first and then commits the uploaded objects to Warehouse.
To delete objects from Warehouse, a client commits the to be deleted objects to Warehouse and relies on Warehouse to delete those objects.
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
To delete objects from Warehouse, a client commits the to be deleted objects to Warehouse and relies on Warehouse to delete those objects.
To delete objects from Warehouse, a client commits the to-be-deleted objects to Warehouse and relies on Warehouse to delete those objects.

Comment on lines +17 to +18
To add objects to Warehouse, a client uploads objects to Storage first and then commits the uploaded objects to Warehouse.
To delete objects from Warehouse, a client commits the to be deleted objects to Warehouse and relies on Warehouse to delete those objects.
Copy link
Contributor

Choose a reason for hiding this comment

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

In this way, a client should talk to both Storage and Warehouse. So a user should keep in mind these usages. It seems a bit awkward. I'll imagine with the Warehouse facade, a user can talk to the Warehouse only.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Make senses. We can hide Storage from the abstraction.

Copy link
Contributor

Choose a reason for hiding this comment

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

With #140 and #143, a client (engine) is still holding all of:

  • Kernel (Warehouse here)
  • Stream
  • Journal
#[derive(Clone)]
pub struct Engine<K: Kernel> {
    kernel: K,
    stream: K::Stream,
    bucket: K::Bucket,
    // ...
}

To add objects to Warehouse, a client uploads objects to Storage first and then commits the uploaded objects to Warehouse.
To delete objects from Warehouse, a client commits the to be deleted objects to Warehouse and relies on Warehouse to delete those objects.
It is possible that a client fails to upload an object or fails to commit the uploaded objects. In this case, the corresponding objects become obsolete.
Warehouse relies on garbage collection to purge obsoleted or to be deleted objects in the end.
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
Warehouse relies on garbage collection to purge obsoleted or to be deleted objects in the end.
Warehouse relies on garbage collection to purge obsoleted or to-be-deleted objects eventually.

Comment on lines +25 to +26
When a client connects to Warehouse, it gets the last version from Warehouse as its base version and then subscribes to delta versions.
When a delta version arrives, the client applies it to the base version to catch up with Warehouse.
Copy link
Contributor

Choose a reason for hiding this comment

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

So the client will hold a connection to subscribe updates per object or per Warehouse? It seems like something that can help in implementing materialize view. We can think more in this direction.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it should be bucket-level. And maybe we should only support bucket-level transactions too.

Copy link

Choose a reason for hiding this comment

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

i think bucket level is too large, warehouse can also import database concept like hive? it seems more complicated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did consider using database concepts here. But it seems that Warehouse is more like an object management abstraction. So it may be easier to understand if we refer to the bucket/object concepts from Storage.

Copy link

Choose a reason for hiding this comment

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

Bucket concepts may cause many clients to fetch many recent metadata updates that it does not need

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I think most applications will map one database to one bucket. I need to make it clear that the bucket concept may not actually map to a bucket in the cloud storage. It is ok for Warehouse to map multiple buckets to a single bucket in Storage. Does it sound confused? Maybe I should consider use "database" instead of "bucket" here 🤔

Copy link

@SGZW SGZW Nov 22, 2021

Choose a reason for hiding this comment

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

Yes, it's will be more clearly, s3's bucket is more familiar with me, thanks for feedback


## Architecture

![Architecture](images/warehouse-architecture.drawio.svg)
Copy link
Contributor

Choose a reason for hiding this comment

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

From the graph, it seems the client talks to Warehouse directly. Will Warehouse becomes a new kind of unit? I'd like to confirm whether it's at the same level of Storage or a component inside Compute.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question. Warehouse is between Storage and Compute. I am considering running Warehouse and Manifest in the same unit. There are still some designs to be done in the overall architecture and microunit.


Warehouse stores object data in Storage and stores object metadata in Manifest.

To add objects to Warehouse, a client uploads objects to Storage first and then commits the uploaded objects to Warehouse.
Copy link

Choose a reason for hiding this comment

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

How to resolve concurrent upload conflicts? Warehouse unit maintains txn manager?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The assumption is that clients will not upload the same object concurrently. This can be achieved by assigning a unique name to each object (for example, a UUID or a sequence number issued by Warehouse).

Comment on lines +25 to +26
When a client connects to Warehouse, it gets the last version from Warehouse as its base version and then subscribes to delta versions.
When a delta version arrives, the client applies it to the base version to catch up with Warehouse.
Copy link

Choose a reason for hiding this comment

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

i think bucket level is too large, warehouse can also import database concept like hive? it seems more complicated

@huachaohuang
Copy link
Contributor Author

Thanks for everyone's feedback. While the design is far from perfect, I think it's still better to have it landed and move the design forward. So I am going to merge it now, some wording can be improved later.

@huachaohuang huachaohuang merged commit 80a05fd into engula:main Nov 23, 2021
@huachaohuang huachaohuang deleted the docs branch November 23, 2021 09:15
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

4 participants