-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Add internal _primary_term doc values field, fix _seq_no indexing #21637
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
Conversation
|
Because I'm curious, I'm also going to do some measurements about the impact this has on indexing performance for some before and after numbers using Rally, I will post the results here when that is complete. |
|
With Without |
|
retest this please |
30eca01 to
26f2a38
Compare
|
retest this please |
jasontedor
left a comment
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've read through all the production code. I think it looks right, I left some comments on some small things that I noticed.
I have not read the tests yet.
I will give the production code a final super-careful read tomorrow, and I will read all the tests then too. I just want to get the small comments that I have in front you sooner rather than later.
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.
Nit: if we are going to be abbreviate here, can we be consistent with elsewhere: loadSeqNo?
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.
Nit: seqnum -> seq_no
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.
Can we please not use Tuple here? I'm fine with a wrapper class, anything but Tuple (plus, with a wrapper class, no boxing). 😄
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.
As long as I can make it not an inner class :D
I'll update this to use an actual class
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.
Nit: seqNum -> seqNo
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.
Should this method be named to seqID or something like that (and throughout this class)?
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.
seqNo -> seqID?
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.
seqNo -> seqID?
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.
If I'm reading this correctly, the context variable is never used so can we just assign to leaf directly (one less thing to think about).
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.
seqno -> _seq_no
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.
Same thing, I don't think this variable is necessary.
|
Thanks for taking a look @jasontedor, I pushed some commits for the small comments. |
jasontedor
left a comment
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 think we can remove Engine#getSequenceID.
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.
Sorry for not noticing this sooner (I was blinded by the Tuple), but I don't think that we need this method. Most of the time we do not need the primary term (it's only used to resolve conflicts in the sequence number, and we can just load both separately then) so I think that we can safely drop this (and thus drop the wrapper class).
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.
That's part of the reason I used a Tuple in the first place, I expect this method to go away in the future, though maybe not necessarily in this PR (see my comment on the PR)
Sure, that's only in there to show how to get this for the next person down the line. It's actually used for the unit test. However, if we remove that, then we could also remove the |
|
@jasontedor I pushed two commits that I believe addresses your concerns while still keeping what I wanted around. |
jasontedor
left a comment
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.
The change looks good, I left a comment, two nits, and a request. We are basically there though.
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.
Nit: primary term -> _primary_term
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.
Why not primary.getPrimaryTerm()? I don't think it matters since we are going to drop this on the floor and there isn't an assigned sequence number here, but we can set the primary term to the correct value, so why not?
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.
Sure, I'll use primary.getPrimaryTerm instead
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 see this was already like this, but this can go on a single line.
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.
Can you leave a comment why this is needed?
|
@jasontedor thanks again, I pushed another two commits addressing your comments. |
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.
random drive by question - why is the primary term part of the index result? it's already part of index and index result is supposed to capture the dynamic things that the engine has assigned.
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.
That's fair, I poked around the code and I do not think it's needed on the result at all. Can you confirm @dakrone?
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 included it because the sequence number is included in the result. Also, it's used when constructing a new Index op from an Engine.IndexResult:
public Index(Engine.Index index, Engine.IndexResult indexResult) {
this.id = index.id();
this.type = index.type();
this.source = index.source();
this.routing = index.routing();
this.parent = index.parent();
this.seqNo = indexResult.getSeqNo(); // <-- here
this.primaryTerm = indexResult.getPrimaryTerm(); // <-- and here
this.version = indexResult.getVersion();
this.versionType = index.versionType();
this.autoGeneratedIdTimestamp = index.getAutoGeneratedIdTimestamp();
}(Also used when creating a new Delete op from a DeleteResult)
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 see. The seqNo and the term do not necessarily always go together. the seqNo is the location of the operation and the term is the authority to put it there. I like the fact that the result object only contains the things that the internal engine creates / changes. Seq# are owned by the engine (on a primary). Terms are owned by the shard. I would prefer to remove the term. At least in the example you gave (Translog.Index#Index(Index, IndexResult) it's readily available from the index operation.
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.
Okay, I'll remove it then!
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.
another drive by question - should we do it here, or separate this into two, more explicit, flows - one we when we create an Index operation on a replica (where we set the seq no number based on incoming request) and one here when we operate as a primary? If you guys feel the current version is more intuitive, I'm good but I wanted to get confirmation this was considered.
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 prefer having exactly one place where this is updated, as it's less likely to get out of sync than if it were separated. It's also easier to find when it's only in a single place.
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'm totally open to suggestions otherwise though, @jasontedor you're about to use this PR, do you have a preference?
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 prefer it the way that you have it.
jasontedor
left a comment
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.
LGTM.
This adds the `_primary_term` field internally to the mappings. This field is populated with the current shard's primary term. It is intended to be used for collision resolution when two document copies have the same sequence id, therefore, doc_values for the field are stored but the filed itself is not indexed. This also fixes the `_seq_no` field so that doc_values are retrievable (they were previously stored but irretrievable) and changes the `stats` implementation to more efficiently use the points API to retrieve the min/max instead of iterating on each doc_value value. Additionally, even though we intend to be able to search on the field, it was previously not searchable. This commit makes it searchable. There is no user-visible `_primary_term` field. Instead, the fields are updated by calling: ```java index.parsedDoc().updateSeqID(seqNum, primaryTerm); ``` This includes example methods in `Versions` and `Engine` for retrieving the sequence id values from the index (see `Engine.getSequenceID`) that are only used in unit tests. These will be extended/replaced by actual implementations once we make use of sequence numbers as a conflict resolution measure. Relates to elastic#10708 Supercedes elastic#21480 P.S. As a side effect of this commit, `SlowCompositeReaderWrapper` cannot be used for documents that contain `_seq_no` because it is a Point value and SCRW cannot wrap documents with points, so the tests have been updated to loop through the `LeafReaderContext`s now instead.
2275850 to
ee22a47
Compare
|
Thanks @jasontedor and @bleskes |
This adds the
_primary_termfield internally to the mappings. This field ispopulated with the current shard's primary term.
It is intended to be used for collision resolution when two document copies have
the same sequence id, therefore, doc_values for the field are stored but the
filed itself is not indexed.
This also fixes the
_seq_nofield so that doc_values are retrievable (theywere previously stored but irretrievable) and changes the
statsimplementationto more efficiently use the points API to retrieve the min/max instead of
iterating on each doc_value value. Additionally, even though we intend to be
able to search on the field, it was previously not searchable. This commit makes
it searchable.
There is no user-visible
_primary_termfield. Instead, the fields areupdated by calling:
This includes example methods in
VersionsandEnginefor retrieving thesequence id values from the index (see
Engine.getSequenceID) that are onlyused in unit tests. These will be extended/replaced by actual implementations
once we make use of sequence numbers as a conflict resolution measure.
Relates to #10708
Supercedes #21480
P.S. As a side effect of this commit,
SlowCompositeReaderWrappercannot beused for documents that contain
_seq_nobecause it is a Point value and SCRWcannot wrap documents with points, so the tests have been updated to loop
through the
LeafReaderContexts now instead.