-
Notifications
You must be signed in to change notification settings - Fork 976
BP-38: Bypass journal ledger #1944
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| --- | ||
| title: "BP-38: bypass journal ledger" | ||
| issue: https://github.com/apache/bookkeeper/issues/1918 | ||
| state: "Under Discussion" | ||
| release: "N/A" | ||
| --- | ||
|
|
||
| ### Motivation | ||
|
|
||
| To guarantee high durability, BK write journal before flush data to persistent device which will cause two write of data. | ||
| But we may not need this level of persistence under [scenarios](https://cwiki.apache.org/confluence/display/BOOKKEEPER/BP-14+Relax+durability) which prefer weak durability guarantee. | ||
| This proposal is aimed at providing bypass journal ledger, this feature includes these parts work: | ||
| - add new write flag `BYPASS_JOURNAL` to existing protocol | ||
| - impl the newly write flag at the client side and server side | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean client visible API change ? or where exactly is this flag?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. What I mean is extending WriteFlags, the user who wants using this feature only needs pass WriteFlags to the WriteHandle. looks like this:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ArvinDevel it would be good if you can put the example code in the BP.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will do that |
||
|
|
||
| The usage will looks like this: | ||
| ```java | ||
| WriteHandle writeHandle = newCreateLedgerOp() | ||
| .withEnsembleSize(3) | ||
| .withWriteQuorumSize(3) | ||
| .withAckQuorumSize(3) | ||
| .withPassword(PASSWORD) | ||
| .withWriteFlags(WriteFlag.BYPASS_JOURNAL) | ||
| .execute().get(); | ||
| // append data as usual, but the lac won't advance | ||
| writeHandle.appendAsync(...); | ||
| // force to advance lac | ||
| writeHandle.force(); | ||
| writeHandle.closeAsync(); | ||
| ``` | ||
| The details of changes are listed in Section “[Proposed Changes](#proposed-changes)”. | ||
|
|
||
| ### Public Interfaces | ||
|
|
||
| This feature will introduce new 'WRITE_FLAG' to enable single write storage impl. | ||
| Like `DEFERRED_SYNC`, when we construct `WriteHandle`, we can pass `BYPASS_JOURNAL`, then every `AddRequest` will carry this flag. | ||
| As for monitoring, we can add metrics to record the main time interval during the io path. | ||
| The detailed compatibility related stuff is in Section “[CDMP](#compatibility-deprecation-and-migration-plan)”. | ||
|
|
||
| ### Proposed Changes | ||
|
|
||
| While the main approach is based on [`WRITE_FLAG` impl](https://github.com/apache/bookkeeper/pull/742), | ||
| the actual implementation is more tricky. In my opinion, there are three different solution: | ||
|
|
||
| 1. Relax LAC protocol(rejected due to violate LAC protocol) | ||
|
|
||
| Modify server side code mostly and don't change legerHandle's LAC advance logic, if the write flag is `BYPASS_JOURNAL`, after write to `LegerStorage`(the data maybe in the memTable, or the buffer of File, or the os cache), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think we should use the DEFERRED_SYNC way of handling LAC, that is that a regular write will not advance LAC, but you need a "force" (like you state below).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The difficult is how to execute "force", leave to app or client lib, and how often to schedule force if WriteHandle is responsible for that. Do you have any ideas?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. force() RPC may carry a flag on the wire which tells that the clients wants to fait for a flush of the memtable for the given ledger. It makes sense only in conjunction with "multiple entry loggers"/"one entry logger per ledger" feature.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, but I'm more worried about that is the synchronized "force" applicable for bypass-journal weak durability. On the "deferred_sync" scenario, the consumer/ReadHandle can tolerant reading after "force" or close. If we still restrict the reader can only read up to the point where writer "force", will this limit the applied scenarios of bypass-journal weak durability?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @eolivelli. For bypass journal use cases, I think applications are usually when a ledger is closed/forced. So the above assumptions would make implementation easier. |
||
| bookie return result to the client directly. | ||
| This impl is like [disable syncData](https://github.com/apache/bookkeeper/issues/753), once all the replica fails, the BK cluster can't recovery from it. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this the above will be obsolete?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The bookie level config |
||
| Note, the user shall know the weak durability for his use case when using this impl. | ||
|
|
||
| 2. Extend `Force` API | ||
|
|
||
| Like `DEFERRED_SYNC`, the normal 'bypass-journal' operation don't advance LAC on the client. | ||
| Only advance LAC using `force` api. To support this new 'bypass-journal' option, we need theses changes: | ||
|
|
||
| - Add force interface to `LedgerDescriptor` and LedgerStorage | ||
|
|
||
| Used to flush the data on memTable to persistent device for specific ledger, and this make senses with "one entry logger per ledger" feature. | ||
| For general SortedLedgerStorage, this "force" operation may has some overhead due to flush data too early. | ||
|
|
||
| - Extend the force request | ||
|
|
||
| If the force request contains bypass journal option, execute force method of `LedgerDescriptor`, which will call LedgerStorage's force interface to flush received entries to persistent device. | ||
|
|
||
| In addition to these changes, we should consider who is responsible for the `force` execution? How often to schedule 'force'? | ||
| To simply the design and give more choices to apps, these choices are up to user. | ||
|
|
||
| 3. Add NonPersistentLAC semantic to existing LAC protocol(rejected due to infeasible and complex) | ||
|
|
||
| To not violate LAC semantics like method 1, we can add `NonPersistentLAC` semantic, this includes these changes: | ||
|
|
||
| - Add persistent callback to LedgerStorage | ||
|
|
||
| Maintain non-persistent entry list and `maxPersistentEntryId` on `LedgerDescriptor`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to have a 'maxPersistentEntryId' while working on DEFERRED_SYNC but actually it was not possible because if you use "LedgerHandleAdv" entries won't get to the bookie with a specific order, so you will have to keep track of holes.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you're right, thanks |
||
|
|
||
| - Wire protocol changes | ||
|
|
||
| Add optional `maxPersistentEntryId` field to `AddResponse`. When the `AddRequest` has 'bypass-journal' option, the server get `maxPersistentEntryId` from `LedgerDescriptor` to construct response. | ||
|
|
||
| - Client side changes | ||
|
|
||
| Add `nonPersistentLAC` to WriteHandle. WriteHandle with 'bypass-journal' option updates the LAC using `maxPersistentEntryId`, and update `nonPersistentLAC` if receives enough ack. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nonPersistentLAC is more like 'pendingAddsSequenceHead' that we introduced for DEFERRED_SYNC
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, and I forgot to state something to complete nonPersistentLAC :
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why persisting an non-persistent value ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I want is relaxing the reader to read up to latest entry as early as possible. |
||
| For normal WriteHandle, the `nonPersistentLAC` is set to null to indicate to keep original LAC advance logic. | ||
|
|
||
| As we only introduce `BYPASS_JOURNAL` write flag to add request, it's better not change existing fencing logic. So fence operation shall falls into journal io path. | ||
|
|
||
| ### Compatibility, Deprecation, and Migration Plan | ||
|
|
||
| As this new feature only add one ledger creating option and corresponding ledger implementation. It has no effect | ||
| on existing users. After this feature is implemented, user can use this function directly on new released version which includes this implementation. | ||
| When user use the latest client which has the `BYPASS_JOURNAL` write flag, but the bookie is old versions which can't do bypass-journal process, | ||
| the bookie will reject this type write. Old client has no chance to use this new write flag, and the new bookie can handle as usual. | ||
|
|
||
| ### Test Plan | ||
|
|
||
| - unit tests for newly introduced write_flag and extended force at client side and server side | ||
| - end-to-end tests for the new Protocol request/response | ||
| - compat tests (client with this new writeflags will not be able to write on old bookies) | ||
|
|
||
| ### Rejected Alternatives | ||
|
|
||
| To avoid two write of data, we can write the data to one log abstraction in the bookie, either by bypassing journal or | ||
| bypassing entryLog. If we choose bypassing entryLog, then we will do lots of work to enable rich read on journal, | ||
| which is more huge work compared with bypassing journal. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume BYPASS_JOURNAL is applicable only in the week durability case. We have that in the protocol, so can't BYPASS_JOURNAL be just a configuration parameter on bookie, which will used only (if enabled) on week durability case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When user create LedgerHandle, he/she can construct it with
WriteFlag.BYPASS_JOURNALThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jvrao I think we cannot have a bookie configuration parameter because the client must be aware of relaxed durability and advance LAC accordingly (like we do with DEFERRED_SYNC)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jvrao If I remember this correctly, we were thinking of adding BYPASS_JOURNAL as a WriteFlag, no? Applications can decide whether to use journal or not.