Add direct in-memory journal threshold
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / DefaultConfigParamsImpl.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.raft;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.base.Strings;
14 import com.google.common.base.Suppliers;
15 import java.util.concurrent.TimeUnit;
16 import java.util.function.Supplier;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.controller.cluster.raft.policy.DefaultRaftPolicy;
19 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import scala.concurrent.duration.FiniteDuration;
23
24 /**
25  * Default implementation of the ConfigParams.
26  */
27 public class DefaultConfigParamsImpl implements ConfigParams {
28
29     private static final Logger LOG = LoggerFactory.getLogger(DefaultConfigParamsImpl.class);
30
31     private static final int SNAPSHOT_BATCH_COUNT = 20000;
32     /**
33      * Interval after which a snapshot should be taken during the recovery process. 0 if never.
34      */
35     private static final int RECOVERY_SNAPSHOT_INTERVAL_SECONDS = 0;
36
37     private static final int JOURNAL_RECOVERY_LOG_BATCH_SIZE = 1000;
38
39     /**
40      * The maximum election time variance.
41      */
42     private static final int ELECTION_TIME_MAX_VARIANCE = 100;
43
44     private static final int SNAPSHOT_CHUNK_SIZE = 2048 * 1000; //2MB
45
46
47     /**
48      * The interval at which a heart beat message will be sent to the remote
49      * RaftActor.
50      *
51      * <p>
52      * Since this is set to 100 milliseconds the Election timeout should be
53      * at least 200 milliseconds
54      */
55     public static final FiniteDuration HEART_BEAT_INTERVAL =
56         new FiniteDuration(100, TimeUnit.MILLISECONDS);
57
58     private final Supplier<RaftPolicy> policySupplier = Suppliers.memoize(this::getPolicy);
59
60     private FiniteDuration heartBeatInterval = HEART_BEAT_INTERVAL;
61     private long snapshotBatchCount = SNAPSHOT_BATCH_COUNT;
62     private int journalRecoveryLogBatchSize = JOURNAL_RECOVERY_LOG_BATCH_SIZE;
63     private int recoverySnapshotIntervalSeconds = RECOVERY_SNAPSHOT_INTERVAL_SECONDS;
64     private long isolatedLeaderCheckInterval = HEART_BEAT_INTERVAL.$times(1000).toMillis();
65     private FiniteDuration electionTimeOutInterval;
66
67     // 12 is just an arbitrary percentage. This is the amount of the total memory that a raft actor's
68     // in-memory journal can use before it needs to snapshot
69     private int snapshotDataThresholdPercentage = 12;
70
71     // max size of in-memory journal in MB
72     // 0 means direct threshold if disabled
73     private int snapshotDataThreshold = 0;
74
75     private int snapshotChunkSize = SNAPSHOT_CHUNK_SIZE;
76
77     private long electionTimeoutFactor = 2;
78     private long candidateElectionTimeoutDivisor = 1;
79     private String customRaftPolicyImplementationClass;
80
81     private PeerAddressResolver peerAddressResolver = NoopPeerAddressResolver.INSTANCE;
82
83     private String tempFileDirectory = "";
84
85     private int fileBackedStreamingThreshold = 128 * MEGABYTE;
86
87     private long syncIndexThreshold = 10;
88
89     public void setHeartBeatInterval(final FiniteDuration heartBeatInterval) {
90         this.heartBeatInterval = heartBeatInterval;
91         electionTimeOutInterval = null;
92     }
93
94     public void setSnapshotBatchCount(final long snapshotBatchCount) {
95         this.snapshotBatchCount = snapshotBatchCount;
96     }
97
98     public void setRecoverySnapshotIntervalSeconds(int recoverySnapshotInterval) {
99         checkArgument(recoverySnapshotInterval >= 0);
100         this.recoverySnapshotIntervalSeconds = recoverySnapshotInterval;
101     }
102
103     public void setSnapshotDataThresholdPercentage(final int snapshotDataThresholdPercentage) {
104         this.snapshotDataThresholdPercentage = snapshotDataThresholdPercentage;
105     }
106
107     public void setSnapshotDataThreshold(final int snapshotDataThreshold) {
108         this.snapshotDataThreshold = snapshotDataThreshold;
109     }
110
111     public void setSnapshotChunkSize(final int snapshotChunkSize) {
112         this.snapshotChunkSize = snapshotChunkSize;
113     }
114
115     public void setJournalRecoveryLogBatchSize(final int journalRecoveryLogBatchSize) {
116         this.journalRecoveryLogBatchSize = journalRecoveryLogBatchSize;
117     }
118
119     public void setIsolatedLeaderCheckInterval(final FiniteDuration isolatedLeaderCheckInterval) {
120         this.isolatedLeaderCheckInterval = isolatedLeaderCheckInterval.toMillis();
121     }
122
123     public void setElectionTimeoutFactor(final long electionTimeoutFactor) {
124         this.electionTimeoutFactor = electionTimeoutFactor;
125         electionTimeOutInterval = null;
126     }
127
128     public void setCandidateElectionTimeoutDivisor(final long candidateElectionTimeoutDivisor) {
129         this.candidateElectionTimeoutDivisor = candidateElectionTimeoutDivisor;
130     }
131
132     public void setTempFileDirectory(final String tempFileDirectory) {
133         this.tempFileDirectory = tempFileDirectory;
134     }
135
136     public void setFileBackedStreamingThreshold(final int fileBackedStreamingThreshold) {
137         this.fileBackedStreamingThreshold = fileBackedStreamingThreshold;
138     }
139
140     public void setCustomRaftPolicyImplementationClass(final String customRaftPolicyImplementationClass) {
141         this.customRaftPolicyImplementationClass = customRaftPolicyImplementationClass;
142     }
143
144     @Override
145     public String getCustomRaftPolicyImplementationClass() {
146         return customRaftPolicyImplementationClass;
147     }
148
149     @Override
150     public long getSnapshotBatchCount() {
151         return snapshotBatchCount;
152     }
153
154     @Override
155     public int getSnapshotDataThresholdPercentage() {
156         return snapshotDataThresholdPercentage;
157     }
158
159     @Override
160     public int getSnapshotDataThreshold() {
161         return snapshotDataThreshold;
162     }
163
164     @Override
165     public int getRecoverySnapshotIntervalSeconds() {
166         return this.recoverySnapshotIntervalSeconds;
167     }
168
169     @Override
170     public FiniteDuration getHeartBeatInterval() {
171         return heartBeatInterval;
172     }
173
174     @Override
175     public FiniteDuration getElectionTimeOutInterval() {
176         if (electionTimeOutInterval == null) {
177             electionTimeOutInterval = getHeartBeatInterval().$times(electionTimeoutFactor);
178         }
179
180         return electionTimeOutInterval;
181     }
182
183     @Override
184     public long getCandidateElectionTimeoutDivisor() {
185         return candidateElectionTimeoutDivisor;
186     }
187
188     @Override
189     public int getElectionTimeVariance() {
190         return ELECTION_TIME_MAX_VARIANCE;
191     }
192
193     @Override
194     public int getSnapshotChunkSize() {
195         return snapshotChunkSize;
196     }
197
198     @Override
199     public int getJournalRecoveryLogBatchSize() {
200         return journalRecoveryLogBatchSize;
201     }
202
203     @Override
204     public long getIsolatedCheckIntervalInMillis() {
205         return isolatedLeaderCheckInterval;
206     }
207
208     @Override
209     public long getElectionTimeoutFactor() {
210         return electionTimeoutFactor;
211     }
212
213     @Override
214     public RaftPolicy getRaftPolicy() {
215         return policySupplier.get();
216     }
217
218     @Override
219     public String getTempFileDirectory() {
220         return tempFileDirectory;
221     }
222
223     @Override
224     public int getFileBackedStreamingThreshold() {
225         return fileBackedStreamingThreshold;
226     }
227
228
229     @Override
230     public PeerAddressResolver getPeerAddressResolver() {
231         return peerAddressResolver;
232     }
233
234     public void setPeerAddressResolver(final @NonNull PeerAddressResolver peerAddressResolver) {
235         this.peerAddressResolver = requireNonNull(peerAddressResolver);
236     }
237
238     @Override
239     public long getSyncIndexThreshold() {
240         return syncIndexThreshold;
241     }
242
243     public void setSyncIndexThreshold(final long syncIndexThreshold) {
244         checkArgument(syncIndexThreshold >= 0);
245         this.syncIndexThreshold = syncIndexThreshold;
246     }
247
248     @SuppressWarnings("checkstyle:IllegalCatch")
249     private RaftPolicy getPolicy() {
250         if (Strings.isNullOrEmpty(DefaultConfigParamsImpl.this.customRaftPolicyImplementationClass)) {
251             LOG.debug("No custom RaftPolicy specified. Using DefaultRaftPolicy");
252             return DefaultRaftPolicy.INSTANCE;
253         }
254
255         try {
256             String className = DefaultConfigParamsImpl.this.customRaftPolicyImplementationClass;
257             LOG.info("Trying to use custom RaftPolicy {}", className);
258             return (RaftPolicy)Class.forName(className).getDeclaredConstructor().newInstance();
259         } catch (ClassCastException | ReflectiveOperationException e) {
260             if (LOG.isDebugEnabled()) {
261                 LOG.error("Could not create custom raft policy, will stick with default", e);
262             } else {
263                 LOG.error("Could not create custom raft policy, will stick with default : cause = {}",
264                     e.getMessage());
265             }
266         }
267         return DefaultRaftPolicy.INSTANCE;
268     }
269 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.