19
19
20
20
package org .elasticsearch .gateway ;
21
21
22
- import com .carrotsearch .hppc .cursors .IntObjectCursor ;
23
22
import com .google .common .collect .Lists ;
24
23
import com .google .common .collect .Maps ;
25
24
import org .elasticsearch .ElasticsearchException ;
33
32
import org .elasticsearch .cluster .node .DiscoveryNode ;
34
33
import org .elasticsearch .cluster .routing .*;
35
34
import org .elasticsearch .common .Nullable ;
36
- import org .elasticsearch .common .Preconditions ;
37
35
import org .elasticsearch .common .component .AbstractComponent ;
38
36
import org .elasticsearch .common .inject .Inject ;
39
37
import org .elasticsearch .common .settings .ImmutableSettings ;
46
44
import java .nio .file .DirectoryStream ;
47
45
import java .nio .file .Files ;
48
46
import java .nio .file .Path ;
47
+ import java .util .*;
49
48
50
49
/**
51
50
*
@@ -58,17 +57,19 @@ public class GatewayMetaState extends AbstractComponent implements ClusterStateL
58
57
private final NodeEnvironment nodeEnv ;
59
58
private final MetaStateService metaStateService ;
60
59
private final DanglingIndicesState danglingIndicesState ;
60
+ private final IndexMetaState indexMetaState ;
61
61
62
62
@ Nullable
63
63
private volatile MetaData currentMetaData ;
64
64
65
65
@ Inject
66
66
public GatewayMetaState (Settings settings , NodeEnvironment nodeEnv , MetaStateService metaStateService ,
67
- DanglingIndicesState danglingIndicesState , TransportNodesListGatewayMetaState nodesListGatewayMetaState ) throws Exception {
67
+ DanglingIndicesState danglingIndicesState , IndexMetaState indexMetaState , TransportNodesListGatewayMetaState nodesListGatewayMetaState ) throws Exception {
68
68
super (settings );
69
69
this .nodeEnv = nodeEnv ;
70
70
this .metaStateService = metaStateService ;
71
71
this .danglingIndicesState = danglingIndicesState ;
72
+ this .indexMetaState = indexMetaState ;
72
73
nodesListGatewayMetaState .init (this );
73
74
74
75
@@ -93,6 +94,26 @@ public MetaData loadMetaState() throws Exception {
93
94
return metaStateService .loadFullState ();
94
95
}
95
96
97
+ public static class IndexMetaWriteInfo {
98
+ IndexMetaData newMetaData ;
99
+ String reason ;
100
+ public IndexMetaData previousMetaData ;
101
+
102
+ public IndexMetaWriteInfo (IndexMetaData newMetaData , IndexMetaData previousMetaData , String reason ) {
103
+ this .newMetaData = newMetaData ;
104
+ this .reason = reason ;
105
+ this .previousMetaData = previousMetaData ;
106
+ }
107
+
108
+ public IndexMetaData getNewMetaData () {
109
+ return newMetaData ;
110
+ }
111
+
112
+ public String getReason () {
113
+ return reason ;
114
+ }
115
+ }
116
+
96
117
@ Override
97
118
public void clusterChanged (ClusterChangedEvent event ) {
98
119
final ClusterState state = event .state ();
@@ -117,39 +138,17 @@ public void clusterChanged(ClusterChangedEvent event) {
117
138
}
118
139
}
119
140
120
- // check and write changes in indices
121
- for (IndexMetaData indexMetaData : newMetaData ) {
122
- String writeReason = null ;
123
- IndexMetaData currentIndexMetaData ;
124
- if (currentMetaData == null ) {
125
- // a new event..., check from the state stored
126
- try {
127
- currentIndexMetaData = metaStateService .loadIndexState (indexMetaData .index ());
128
- } catch (IOException ex ) {
129
- throw new ElasticsearchException ("failed to load index state" , ex );
130
- }
131
- } else {
132
- currentIndexMetaData = currentMetaData .index (indexMetaData .index ());
133
- }
134
- boolean shardsAllocatedOnThisNodeInLastClusterState = shardsAllocatedOnLocalNode (event .previousState (), indexMetaData );
135
- boolean shardsAllocatedOnThisNodeInNewClusterState = shardsAllocatedOnLocalNode (event .state (), indexMetaData );
136
- if (isDataOnlyNode (state ) && (shardsAllocatedOnThisNodeInLastClusterState == false ) && (shardsAllocatedOnThisNodeInNewClusterState == true )) {
137
- // shard was newly allocated because it was not allocated in last cluster state but is now
138
- // we removed the index state before so now we have to write it again
139
- writeReason = "shard allocated on data only node" ;
140
- } else if (shouldWriteOnNode (state , shardsAllocatedOnThisNodeInNewClusterState ) && currentIndexMetaData == null ) {
141
- writeReason = "freshly created" ;
142
- } else if (shouldWriteOnNode (state , shardsAllocatedOnThisNodeInNewClusterState ) && currentIndexMetaData .version () != indexMetaData .version ()) {
143
- writeReason = "version changed from [" + currentIndexMetaData .version () + "] to [" + indexMetaData .version () + "]" ;
144
- }
145
-
146
- // we update the writeReason only if we really need to write it
147
- if (writeReason == null ) {
148
- continue ;
149
- }
141
+ Iterable <IndexMetaWriteInfo > writeInfo = new ArrayList <>();
142
+ if (isDataOnlyNode (event .state ())) {
143
+ writeInfo = indexMetaState .getIndicesToWriteDataOnlyNode (event , currentMetaData );
144
+ } else if (isMasterEligibleNode (event .state ())) {
145
+ writeInfo = indexMetaState .getIndicesToWriteMasterNode (event , currentMetaData );
146
+ }
150
147
148
+ // check and write changes in indices
149
+ for (IndexMetaWriteInfo indexMetaWrite : writeInfo ) {
151
150
try {
152
- metaStateService .writeIndex (writeReason , indexMetaData , currentIndexMetaData );
151
+ metaStateService .writeIndex (indexMetaWrite . reason , indexMetaWrite . newMetaData , indexMetaWrite . previousMetaData );
153
152
} catch (Throwable e ) {
154
153
success = false ;
155
154
}
@@ -163,24 +162,6 @@ public void clusterChanged(ClusterChangedEvent event) {
163
162
}
164
163
}
165
164
166
- protected boolean shardsAllocatedOnLocalNode (ClusterState state , IndexMetaData indexMetaData ) {
167
- boolean shardsAllocatedOnThisNode = false ;
168
- IndexRoutingTable indexRoutingTable = state .getRoutingTable ().index (indexMetaData .index ());
169
- if (indexRoutingTable == null ) {
170
- // nothing allocated ?
171
- return false ;
172
- }
173
- // iterate over shards and see if one is on our node
174
- for (IntObjectCursor it : indexRoutingTable .shards ()) {
175
- IndexShardRoutingTable shardRoutingTable = (IndexShardRoutingTable ) it .value ;
176
- for (ShardRouting shardRouting : shardRoutingTable .shards ()) {
177
- if (shardRouting .currentNodeId () != null && shardRouting .currentNodeId ().equals (state .nodes ().localNode ().getId ())) {
178
- shardsAllocatedOnThisNode = true ;
179
- }
180
- }
181
- }
182
- return shardsAllocatedOnThisNode ;
183
- }
184
165
185
166
protected boolean isDataOnlyNode (ClusterState state ) {
186
167
return ((isMasterEligibleNode (state ) == false ) && (state .nodes ().localNode ().dataNode () == true ));
0 commit comments