Navigation Menu

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

Clean up translog interface #7564

Closed
wants to merge 1 commit into from
Closed

Conversation

dakrone
Copy link
Member

@dakrone dakrone commented Sep 3, 2014

This has two major parts:

  • Simplifying the translog interface

Get rid of readSource() entirely, it sucked, Operations should be able
to provide the source themselves.

No more TranslogStream headers, you are now required to pass an
StreamInput or StreamOutput for all operations, which means no extra
state is needed and no need to construct new versions when detecting the
version.

The interface now exists of 2 main methods, and one helper:

// read
Translog.Operation read(StreamInput in)
// write
void write(StreamOutput out, Translog.Operation op)
// when reading a file, need to be able to read and consume the header
void seekPastHeader(StreamInput in)

  • Read and write translog op sizes in TranslogStreams

Previously we handled these integers outside of the translog stream
itself, which was very unclean because other code had to know about
reading the size, or about writing the correct header sometimes.

There is some additional code in LocalIndexShardGateway to handle the
legacy case for older translogs, because we need to read and discard the
size in order to maintain the compatibility for the streaming
operations (they did not read or write the size for 1.3.x and earlier).

Additionally, we need to handle a case where the header is truncated
when recovering from disk, so added code for that.


I'm hoping this makes working with the translog easier and less error-prone. On top of this (in a separate PR) we can add the size-reading safety to prevent rare OOMEs on corrupted translogs.

throw e;
} catch (IOException e) {
throw new TranslogCorruptedException("translog header corrupted", e);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it true that any I/O exception would mean that the translog is corrupt?

Copy link
Member Author

Choose a reason for hiding this comment

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

If reading the header of the translog causes an IOException, I think it's safer to abort with a corruption exception (the cause will be in the stacktrace too) than to try and continue. Additionally the corrupt index exception that Lucene's CodecUtil throws is an IOException, so I elected to wrap it in our own exception.

@s1monw
Copy link
Contributor

s1monw commented Sep 5, 2014

I like it left one comment

@s1monw s1monw removed the review label Sep 5, 2014
@dakrone
Copy link
Member Author

dakrone commented Sep 8, 2014

@s1monw so I'm kind of concerned about one of the changes I made here, which is that we now serialize the size of the operation when sending translog operations between nodes. If it were just a size it wouldn't be a big deal, but to get the size we create a new byte array for every operation, which seems much slower.

What do you think of keeping read and write and adding readWithoutSize and writeWithoutSize for the Transport case? Is that too messy? We could avoid the byte array entirely if we don't need the size.

@dakrone dakrone added the blocker label Sep 8, 2014
@dakrone
Copy link
Member Author

dakrone commented Sep 8, 2014

Also labeling this as a blocker for 1.4 because delaying it until 1.5 means adding another translog format since this changes it (see my previous comment).

@dakrone dakrone added the review label Sep 8, 2014
@dakrone
Copy link
Member Author

dakrone commented Sep 8, 2014

@s1monw added the NoopStreamOutput that we talked about and addressed your comment.

* A non-threadsafe StreamOutput that doesn't actually write the bytes to any
* stream, it only keeps track of how many bytes have been written
*/
public class NoopStreamOutput extends StreamOutput {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be final?

@s1monw
Copy link
Contributor

s1monw commented Sep 8, 2014

I left some comments but mainly cosmetic

@dakrone
Copy link
Member Author

dakrone commented Sep 8, 2014

Updated with your feedback, except for the "stream private" comment because I don't understand what you mean.

@clintongormley clintongormley changed the title Clean up translog interface Resiliency: Clean up translog interface Sep 8, 2014
@s1monw
Copy link
Contributor

s1monw commented Sep 9, 2014

LGTM

@dakrone dakrone force-pushed the translog-clean-up branch 2 times, most recently from f9d1a6e to c390caa Compare September 9, 2014 13:08
get rid of readSource() entirely, it sucked, Operations should be able
to provide the source themselves.

No more TranslogStream headers, you are now required to pass an
StreamInput or StreamOutput for all operations, which means no extra
state is needed and no need to construct new versions when detecting the
version.

Read and write translog op sizes in TranslogStreams

Previously we handled these integers outside of the translog stream
itself, which was very unclean because other code had to know about
reading the size, or about writing the correct header sometimes.

There is some additional code in LocalIndexShardGateway to handle the
legacy case for older translogs, because we need to read and discard the
size in order to maintain the compatibility for the streaming
operations (they did not read or write the size for 1.3.x and earlier).

Additionally, we need to handle a case where the header is truncated
when recovering from disk

Use a NoopStreamOutput instead of byte arrays

Instead of writing translog operations to a temporary byte array and
then writing that byte array to the stream, we now write the operation
twice, once to a No-op stream to get the size, then again to the real
size.

This trades a little more CPU usage for less memory usage.
@dakrone
Copy link
Member Author

dakrone commented Sep 9, 2014

Merged to 1.x and master.

@dakrone dakrone closed this Sep 9, 2014
@dakrone dakrone deleted the translog-clean-up branch September 9, 2014 13:43
@jpountz jpountz removed the review label Oct 21, 2014
@clintongormley clintongormley changed the title Resiliency: Clean up translog interface Clean up translog interface Jun 7, 2015
@clintongormley clintongormley added :Distributed/Distributed A catch all label for anything in the Distributed Area. If you aren't sure, use this one. :Distributed/Engine Anything around managing Lucene and the Translog in an open shard. and removed :Translog :Distributed/Distributed A catch all label for anything in the Distributed Area. If you aren't sure, use this one. labels Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocker :Distributed/Engine Anything around managing Lucene and the Translog in an open shard. >enhancement resiliency v1.4.0.Beta1 v2.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants