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

add is-write-index flag to aliases #30942

Merged
merged 29 commits into from Jun 15, 2018
Merged

Conversation

talevy
Copy link
Contributor

@talevy talevy commented May 29, 2018

This commit adds the is-write-index flag for aliases.
It allows requests to set the flag, and responses to display the flag.
It does not validate and/or affect any indexing/getting/updating behavior
of Elasticsearch -- this will be done in a follow-up PR.

This is a follow-up to: #30703
It made more sense to split the above PR into two PRs. One for introducing the is_write_index
flag, and another to use it for validation and index resolution.

@talevy talevy added >enhancement review :Data Management/Indices APIs APIs to create and manage indices and templates labels May 29, 2018
@talevy talevy requested a review from bleskes May 29, 2018 21:56
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@talevy talevy force-pushed the is-write-index-setting branch 3 times, most recently from a47b7d7 to 54d952a Compare May 30, 2018 02:21
Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

Thanks @talevy , much smaller :) left some comments.

@@ -27,9 +27,9 @@ setup:
indices.get_alias:
name: alias

- match: {test_index1.aliases.alias: {}}
- match: {test_index1.aliases.alias: { is_write_index: false }}
Copy link
Contributor

Choose a reason for hiding this comment

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

why are these false? this is the only index in this alias so it should be true?

@@ -60,6 +62,8 @@
@Nullable
private String searchRouting;

private boolean writeIndex;
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 we specify "default"? don't we want a Boolean here?

@@ -516,7 +516,7 @@ public ClusterState execute(ClusterState currentState) throws Exception {
}
for (Alias alias : request.aliases()) {
AliasMetaData aliasMetaData = AliasMetaData.builder(alias.name()).filter(alias.filter())
.indexRouting(alias.indexRouting()).searchRouting(alias.searchRouting()).build();
.indexRouting(alias.indexRouting()).searchRouting(alias.searchRouting()).writeIndex(alias.isWriteIndex()).build();
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to resolve the is write index here (for when it's not specified).

@@ -112,7 +121,8 @@ boolean removeIndex() {
boolean apply(NewAliasValidator aliasValidator, MetaData.Builder metadata, IndexMetaData index) {
aliasValidator.validate(alias, indexRouting, filter);
AliasMetaData newAliasMd = AliasMetaData.newAliasMetaDataBuilder(alias).filter(filter).indexRouting(indexRouting)
.searchRouting(searchRouting).build();
.searchRouting(searchRouting).writeIndex(writeIndex).build();
Copy link
Contributor

Choose a reason for hiding this comment

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

what happens if writeIndex is null?

==== Write Index

It is possible to associate the index pointed to by an alias as the write index.
When specified, all index and update requests against an alias that point to multiple

This comment was marked as resolved.

This commit adds the is-write-index flag for aliases.
It allows requests to set the flag, and responses to display the flag.
It does not validate and/or affect any indexing/getting/updating behavior
of Elasticsearch -- this will be done in a follow-up PR.
@talevy
Copy link
Contributor Author

talevy commented Jun 1, 2018

@bleskes thanks for the initial review. As I mentioned outside of Github, I believe we were misaligned in terms of how to break apart the original PR that both added the flag, and leveraged it to resolve index name expressions.

I've updated this PR to re-add validation and auto-upgrading of the is_write_index. This means that alias-index configurations with is_write_index=null in both alias-add-actions and index-creations will be set to true when there is no existing write index for that alias. In both cases that a promotion to true is not possible, false will be set.

Although AliasMetaData stores this value as a Boolean, any cluster-state changes that occur via index-creation or alias-updates will resolve this value to either true or false. AliasMetaData#writeIndex must stay a Boolean because of its use in templates. Templates need not define this field explicitly, and no smart unboxing should occur.

I've also added some unit tests that should account for these scenarios. (still iterating to catch all the CI tests that need updating).

- match: {foo.aliases.alias: {}}
- match: {test_index1.aliases.alias: { is_write_index: true }}
- match: {test_index2.aliases.alias: { is_write_index: false }}
- match: {foo.aliases.alias: { is_write_index: false }}

---
"put alias in * index":

This comment was marked as resolved.

@talevy
Copy link
Contributor Author

talevy commented Jun 5, 2018

@bleskes I've updated to reflect the changes we mentioned offline

  • move all validation logic to run at the time that MetaData is built
  • default is_write_index (null) to true if-and-only-if there are no other aliases, false otherwise

I believe I am still missing some test coverage, but I think it should be good enough to review.
I do not feel comfortable with how complex MetaData#build is, but I decided to push back on opening at can of worms for this PR.

Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

Thx @talevy . I left some suggestions.

// CONSOLE
// TEST[s/^/PUT test\nPUT test2\n/]

It is important to note that the order of these actions is important. The original write index
Copy link
Contributor

Choose a reason for hiding this comment

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

This is tricky - with our new model the order is not important but it is that you remove an explicit flag. I wonder if we should add a section over the "default" behavior and illustrate some examples.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh, woops. I thought I went through this. will update since it is left-over and currently wrong

@@ -308,6 +337,8 @@ public static void toXContent(AliasMetaData aliasMetaData, XContentBuilder build
builder.field("search_routing", aliasMetaData.searchRouting());
}

builder.field("is_write_index", Boolean.TRUE.equals(aliasMetaData.writeIndex()));
Copy link
Contributor

@bleskes bleskes Jun 8, 2018

Choose a reason for hiding this comment

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

I think we want just aliasMetaData.writeIndex() here?

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 aspect of Clint's original proposal that I liked was that we would always show this field and make it clear to the user which value we defaulted to. Having it be null feels confusing.

Copy link
Contributor

Choose a reason for hiding this comment

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

make it clear to the user which value we defaulted to

That's my point - we don't know in this point. I agree that outputting null will be confusing hence my suggestion which will completely omit the field if not set.

@@ -134,8 +149,11 @@ public AliasMetaData getFirstAliasMetaData() {
return referenceIndexMetaDatas.get(0).getAliases().get(aliasName);
}

void addIndex(IndexMetaData indexMetaData) {
void addIndex(IndexMetaData indexMetaData, @Nullable Boolean isWriteIndex) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of doing this like this maybe only do it at the end? add a method called "computeAndValidateWriteIndex" and let that one do two things:

  • scan the all index metadata and extracts the writeIndex, if any
  • validate we have no two indices which are marked with the index_write flags.

you can use org.apache.lucene.util.SetOnce to store the writeIndex reference. Then you can assert that once computeAndValidateWriteIndex is called you can't call addIndex anymore.

* @param aliasAndIndexLookup The current state of aliases and indices in the cluster state
* @throws IllegalStateException if any alias has more than one write index
*/
public static void validateAliasWriteOnly(Map<String, AliasOrIndex> aliasAndIndexLookup) {
Copy link
Contributor

Choose a reason for hiding this comment

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

see my other comment.

@@ -701,7 +702,8 @@ private static IndexNotFoundException indexNotFoundException(String expression)
if (context.getOptions().ignoreAliases()) {
return metaData.getAliasAndIndexLookup().entrySet().stream()
.filter(e -> e.getValue().isAlias() == false)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(v1, v2) -> {throw new IllegalStateException("no duplicate indices should exist");}, TreeMap::new));
Copy link
Contributor

Choose a reason for hiding this comment

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

out of curiosity - why did you add this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh woops. this was not meant to stay. I added this to debug where the ordering of indices was being lost. will revert

* @param alias the alias to search for a write-index with
* @return the write-index {@link Index} for <code>alias</code>, null if no write-index is configured
*/
public Index getWriteIndex(String alias) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is usage? I think we should remove it and use it in the follow up PRs we're planning?

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 will double check, but I believe it will be used by the index-name resolver when used for indexing. It is not used yet since we haven't implemented that yet

AliasValidator.validateAliasWriteOnly(aliasAndIndexLookup);

// set any `is_write_index == null` to their appropriate boolean values
for (AliasOrIndex aliasOrIndex : aliasAndIndexLookup.values()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

see other comment - this should all be done in buildAliasAndIndexLookup



// build all concrete indices arrays:
// TODO: I think we can remove these arrays. it isn't worth the effort, for operations on all indices.
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this is about memory allocation - I think we can discuss this but in a different issue.

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 didn't write this

@talevy
Copy link
Contributor Author

talevy commented Jun 12, 2018

hey @bleskes, I've updated the build logic to behave more like a one-pass build of the aliasAndIndexLookup + manipulating the IndexMetaData of the cluster, itself.

one thing I am debugging is how this behavior is affecting snapshot restoration. Since one can restore and rename index names, the aliasmetadata now has multiple copies of is_write_index: true. So restoration is failing

writeIndex = in.readOptionalBoolean();
} else {
writeIndex = null;
}
}

public static Diff<AliasMetaData> readDiffFrom(StreamInput in) throws IOException {

This comment was marked as resolved.

This comment was marked as resolved.

@talevy
Copy link
Contributor Author

talevy commented Jun 14, 2018

I've updated to add more tests and removed unused imports, ready for another review @bleskes. thanks!

Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

LGTM. looks great @talevy

@talevy
Copy link
Contributor Author

talevy commented Jun 15, 2018

thanks! I will probably finalize the back-porting dance early next week in the hopes of not breaking a CI run on a Friday

@talevy talevy merged commit 3b70e94 into elastic:master Jun 15, 2018
@talevy talevy deleted the is-write-index-setting branch June 15, 2018 15:45
@albertzaharovits
Copy link
Contributor

albertzaharovits commented Jun 17, 2018

@talevy I have pushed 5b94afd
It fixes a minor test fault that manifests reproducible with:

 ./gradlew :server:test -Dtests.seed=22BB040A257F9A41 -Dtests.class=org.elasticsearch.cluster.metadata.ToAndFromJsonMetaDataTests -Dtests.method="testSimpleJsonFromAndTo" -Dtests.security.manager=true -Dtests.locale=pl-PL -Dtests.timezone=PRT
ERROR   0.33s | ToAndFromJsonMetaDataTests.testSimpleJsonFromAndTo <<< FAILURES!
   > Throwable #1: java.lang.IllegalStateException: alias [alias2] has more than one write index [test11,test12]
   >    at __randomizedtesting.SeedInfo.seed([22BB040A257F9A41:FE049499C585A170]:0)
   >    at org.elasticsearch.cluster.metadata.AliasOrIndex$Alias.computeAndValidateWriteIndex(AliasOrIndex.java:168)
   >    at org.elasticsearch.cluster.metadata.MetaData$Builder.lambda$buildAliasAndIndexLookup$1(MetaData.java:1078)
   >    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)

which I have stumbled upon on my PR CI https://elasticsearch-ci.elastic.co/job/elastic+elasticsearch+pull-request/11893/console .

@talevy
Copy link
Contributor Author

talevy commented Jun 17, 2018

thanks @albertzaharovits! sorry for the noise

@talevy talevy added v7.0.0 and removed review labels Jun 18, 2018
dnhatn added a commit that referenced this pull request Jun 19, 2018
* master:
  Add get stored script and delete stored script to high level REST API - post backport fix
  Add get stored script and delete stored script to high level REST API (#31355)
  Core: Combine Action and GenericAction (#31405)
  Fix reference to XContentBuilder.string() (#31337)
  Avoid sending duplicate remote failed shard requests (#31313)
  Fix defaults in GeoShapeFieldMapper output (#31302)
  RestAPI: Reject forcemerge requests with a body (#30792)
  Packaging: Remove windows bin files from the tar distribution (#30596)
  Docs: Use the default distribution to test docs (#31251)
  [DOCS] Adds testing for security APIs (#31345)
  Clarify that IP range data can be specified in CIDR notation. (#31374)
  Use system context for cluster state update tasks (#31241)
  Percentile/Ranks should return null instead of NaN when empty (#30460)
  REST high-level client: add validate query API (#31077)
  Move language analyzers from server to analysis-common module. (#31300)
  [Test] Fix :example-plugins:rest-handler on Windows
  Expose lucene's RemoveDuplicatesTokenFilter (#31275)
  Reload secure settings for plugins (#31383)
  Remove some cases in FieldTypeLookupTests that are no longer relevant. (#31381)
  Ensure we don't use a remote profile if cluster name matches (#31331)
  [TEST] Double write alias fault (#30942)
  [DOCS] Fix version in SQL JDBC Maven template
  [DOCS] Improve install and setup section for SQL JDBC
  SQL: Fix rest endpoint names in node stats (#31371)
  Support for remote path in reindex api - post backport fix Closes #22913
  [ML] Put ML filter API response should contain the filter (#31362)
  Support for remote path in reindex api (#31290)
  Add byte array pooling to nio http transport (#31349)
  Remove trial status info from start trial doc (#31365)
  [DOCS] Adds links to release notes and highlights
  add is-write-index flag to aliases (#30942)
  Add rollover-creation-date setting to rolled over index (#31144)
  [ML] Hold ML filter items in sorted set (#31338)
  [Tests] Fix edge case in ScriptedMetricAggregatorTests (#31357)
talevy added a commit to talevy/elasticsearch that referenced this pull request Jun 19, 2018
This commit adds the is-write-index flag for aliases.
It allows requests to set the flag, and responses to display the flag.
It does not validate and/or affect any indexing/getting/updating behavior
of Elasticsearch -- this will be done in a follow-up PR.
talevy pushed a commit to talevy/elasticsearch that referenced this pull request Jun 19, 2018
talevy added a commit that referenced this pull request Jun 20, 2018
* add is-write-index flag to aliases (#30942)

This commit adds the is-write-index flag for aliases.
It allows requests to set the flag, and responses to display the flag.
It does not validate and/or affect any indexing/getting/updating behavior
of Elasticsearch -- this will be done in a follow-up PR.

* [TEST] Double write alias fault (#30942)
dnhatn added a commit that referenced this pull request Jun 20, 2018
* 6.x:
  [DOCS] Omit shard failures assertion for incompatible responses  (#31430)
  [DOCS] Move licensing APIs to docs (#31445)
  backport of: add is-write-index flag to aliases (#30942) (#31412)
  backport of: Add rollover-creation-date setting to rolled over index (#31144) (#31413)
  [Docs] Extend Homebrew installation instructions (#28902)
  [Docs] Mention ip_range datatypes on ip type page (#31416)
  Multiplexing token filter (#31208)
  Fix use of time zone in date_histogram rewrite (#31407)
  Revert "Mute DefaultShardsIT#testDefaultShards test"
  [DOCS] Fixes code snippet testing for machine learning (#31189)
  Security: fix joining cluster with production license (#31341)
  [DOCS] Updated version in Info API example
  [DOCS] Moves the info API to docs (#31121)
  Revert "Increasing skip version for failing test on 6.x"
  Preserve response headers on cluster update task (#31421)
  [DOCS] Add code snippet testing for more ML APIs (#31404)
  Docs: Advice for reindexing many indices (#31279)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Data Management/Indices APIs APIs to create and manage indices and templates >enhancement v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants