diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java index e813ffcb1c..18449e939c 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java @@ -50,6 +50,7 @@ import org.apache.activemq.artemis.cli.commands.tools.DecodeJournal; import org.apache.activemq.artemis.cli.commands.tools.EncodeJournal; import org.apache.activemq.artemis.cli.commands.tools.HelpData; import org.apache.activemq.artemis.cli.commands.tools.PrintData; +import org.apache.activemq.artemis.cli.commands.tools.SyncRecalc; import org.apache.activemq.artemis.cli.commands.tools.XmlDataExporter; import org.apache.activemq.artemis.cli.commands.tools.XmlDataImporter; import org.apache.activemq.artemis.cli.commands.user.AddUser; @@ -162,7 +163,7 @@ public class Artemis { withDefaultCommand(HelpData.class).withCommands(PrintData.class, XmlDataExporter.class, XmlDataImporter.class, DecodeJournal.class, EncodeJournal.class, CompactJournal.class); builder.withGroup("user").withDescription("default file-based user management (add|rm|list|reset) (example ./artemis user list)"). withDefaultCommand(HelpUser.class).withCommands(ListUser.class, AddUser.class, RemoveUser.class, ResetUser.class); - builder = builder.withCommands(Run.class, Stop.class, Kill.class); + builder = builder.withCommands(Run.class, Stop.class, Kill.class, SyncRecalc.class); } else { builder.withGroup("data").withDescription("data tools group (print) (example ./artemis data print)"). withDefaultCommand(HelpData.class).withCommands(PrintData.class); diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java index 5691c6813b..20a8043f90 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java @@ -868,7 +868,7 @@ public class Create extends InputAbstract { System.out.println("Auto tuning journal ..."); long time = SyncCalculation.syncTest(dataFolder, 4096, writes, 5, verbose, !noJournalSync, aio); - long nanoseconds = SyncCalculation.toNanos(time, writes); + long nanoseconds = SyncCalculation.toNanos(time, writes, verbose); double writesPerMillisecond = (double) writes / (double) time; String writesPerMillisecondStr = new DecimalFormat("###.##").format(writesPerMillisecond); diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/SyncRecalc.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/SyncRecalc.java new file mode 100644 index 0000000000..3b0bc3d238 --- /dev/null +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/SyncRecalc.java @@ -0,0 +1,55 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.activemq.artemis.cli.commands.tools; + +import java.text.DecimalFormat; + +import io.airlift.airline.Command; +import org.apache.activemq.artemis.cli.commands.ActionContext; +import org.apache.activemq.artemis.cli.commands.util.SyncCalculation; +import org.apache.activemq.artemis.core.config.impl.FileConfiguration; +import org.apache.activemq.artemis.core.server.JournalType; + +@Command(name = "sync", description = "Calculates the journal-buffer-timeout you should use with the current data folder") +public class SyncRecalc extends LockAbstract { + + @Override + public Object execute(ActionContext context) throws Exception { + super.execute(context); + + FileConfiguration fileConfiguration = getFileConfiguration(); + + int writes = 250; + System.out.println(""); + System.out.println("Auto tuning journal ..."); + + long time = SyncCalculation.syncTest(fileConfiguration.getJournalLocation(), 4096, writes, 5, verbose, fileConfiguration.isJournalDatasync(), fileConfiguration.getJournalType() == JournalType.ASYNCIO); + long nanosecondsWait = SyncCalculation.toNanos(time, writes, verbose); + double writesPerMillisecond = (double) writes / (double) time; + + String writesPerMillisecondStr = new DecimalFormat("###.##").format(writesPerMillisecond); + + context.out.println("Your system can execute " + writesPerMillisecondStr + " syncs per millisecond"); + context.out.println("Your journal-buffer-timeout should be:" + nanosecondsWait); + context.out.println("You should use this following configuration:"); + context.out.println(); + context.out.println("" + nanosecondsWait + ""); + + return null; + } +} diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java index 315ebdccb1..52ef87b0d2 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java @@ -49,6 +49,10 @@ public class SyncCalculation { boolean fsync, boolean aio) throws Exception { SequentialFileFactory factory = newFactory(datafolder, fsync, aio); + + if (verbose) { + System.out.println("Using " + factory.getClass().getName() + " to calculate sync times"); + } SequentialFile file = factory.createSequentialFile("test.tmp"); try { @@ -106,9 +110,9 @@ public class SyncCalculation { if (verbose) { double writesPerMillisecond = (double) blocks / (double) result[ntry]; - System.out.println("Time = " + result[ntry]); + System.out.println("Time = " + result[ntry] + " milliseconds"); System.out.println("Writes / millisecond = " + dcformat.format(writesPerMillisecond)); - System.out.println("bufferTimeout = " + toNanos(result[ntry], blocks)); + System.out.println("bufferTimeout = " + toNanos(result[ntry], blocks, verbose)); System.out.println("**************************************************"); } } @@ -139,14 +143,22 @@ public class SyncCalculation { } } - public static long toNanos(long time, long blocks) { + public static long toNanos(long time, long blocks, boolean verbose) { double blocksPerMillisecond = (double) blocks / (double) (time); + if (verbose) { + System.out.println("Blocks per millisecond::" + blocksPerMillisecond); + } + long nanoSeconds = TimeUnit.NANOSECONDS.convert(1, TimeUnit.MILLISECONDS); long timeWait = (long) (nanoSeconds / blocksPerMillisecond); + if (verbose) { + System.out.println("your system could make a sync every " + timeWait + " nanoseconds, and this will be your timeout"); + } + return timeWait; } diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java index 7a8ee8f635..a8bd54179f 100644 --- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java +++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java @@ -117,7 +117,7 @@ public class ArtemisTest extends CliTestBase { long totalAvg = SyncCalculation.syncTest(temporaryFolder.getRoot(), 4096, writes, tries, true, true, true); System.out.println(); System.out.println("TotalAvg = " + totalAvg); - long nanoTime = SyncCalculation.toNanos(totalAvg, writes); + long nanoTime = SyncCalculation.toNanos(totalAvg, writes, false); System.out.println("nanoTime avg = " + nanoTime); assertEquals(0, LibaioContext.getTotalMaxIO());