Stop asking the filesystem the same question three times per append - #145
Merged
Conversation
An append stats the log to check nothing else has touched it, stats it again to learn the offset it is about to write at, writes, then stats it a third time for the new length. The append lock is held across all three -- taken before the first, released after the last -- so nothing can change the file in between and the second answer is already known. The second stat is gone: the check hands its answer to the append. The third is now an fstat on the handle just written, which is cheaper and a better question -- it reports the length of the file this record went into, rather than of whatever the name refers to afterwards. Measured here: a stat by path costs 2.47 us and an fstat on an open handle 1.67, against a 77 us asynchronous append. The saving is those two figures, not an end-to-end number: the machine was too busy to measure the whole append fairly, and a difference of a few microseconds is not something to claim from a run taken under load. Deliberately not done: holding the file handle open between appends. It would save the open and the close -- 5.9 us, of which about 4.3 survives once an identity check replaces them -- but a handle held across another process's reclaim, which replaces the log by rename, would write into a file nobody will read again. That is not a trade worth 5% of an asynchronous append.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An append stats the log to check nothing else has touched it, stats it again to learn the offset it is about to write at, writes, then stats it a third time for the new length.
The append lock is held across all three — taken before the first, released after the last — so nothing can change the file in between, and the second answer is one the caller already has.
fstaton the handle just written — cheaper, and a better question: it reports the length of the file this record went into, rather than of whatever the name refers to afterwardsThe numbers, and what I am not claiming
The saving is those component figures — one stat removed, one downgraded to an fstat. I am not quoting an end-to-end delta. One run suggested 77 us → 49 us, which is far more than removing ~3 us of syscalls can explain; the machine had a different load between the two, and a few microseconds is not something to claim from runs taken under a load average that swung between 2 and 20 during this work.
What I chose not to do
Holding the file handle open between appends. It would save the open and the close, 5.93 us, of which about 4.3 us survives once an identity check replaces them — an fstat, since another process can reclaim the log and reclaim replaces it by
rename. A handle held across that would be writing into a file nobody will ever read again.About 5% of an asynchronous append, and nothing at all on a durable one where the fsync dominates, is not worth a failure mode that loses data silently. Recorded here so the next person does not have to re-measure it to reach the same conclusion.
Testing
Library suite: 1020 passed, 9 failed. Four names differ from the
maincomparison run and all four were isolated clean earlier today —manifest_fold_reload_reconstructs_catalog_with_band_manifest_deleted,topology_check_stays_off_the_request_path,http_raft_transport_sends_append_vote_and_snapshot_over_tcp,distributed_raft_chunks_large_sequence_add_under_default_entry_limit.