| /* |
| * 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.ignite.internal.suggestions; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.nio.charset.StandardCharsets; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.ArrayList; |
| import java.util.List; |
| import org.apache.ignite.internal.util.typedef.internal.S; |
| import org.apache.ignite.internal.util.typedef.internal.U; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| /** |
| * Operation System configuration suggestions. |
| */ |
| public class OsConfigurationSuggestions { |
| /** */ |
| private static final String VM_PARAMS_BASE_PATH = "/proc/sys/vm/"; |
| |
| /** */ |
| private static final String DIRTY_WRITEBACK_CENTISECS = "dirty_writeback_centisecs"; |
| |
| /** */ |
| private static final String DIRTY_EXPIRE_CENTISECS = "dirty_expire_centisecs"; |
| |
| /** */ |
| private static final String SWAPPINESS = "swappiness"; |
| |
| /** */ |
| private static final String ZONE_RECLAIM_MODE = "zone_reclaim_mode"; |
| |
| /** */ |
| private static final String EXTRA_FREE_KBYTES = "extra_free_kbytes"; |
| |
| /** |
| * Checks OS configurations and produces tuning suggestions. |
| * |
| * @return List of suggestions of Operation system configuration tuning to increase Ignite performance. |
| */ |
| public static synchronized List<String> getSuggestions() { |
| List<String> suggestions = new ArrayList<>(); |
| |
| if (U.isRedHat()) { |
| String value; |
| String expected = "500"; |
| |
| boolean dwcParamFlag = (value = readVmParam(DIRTY_WRITEBACK_CENTISECS)) != null && !value.equals(expected); |
| boolean decParamFlag = (value = readVmParam(DIRTY_EXPIRE_CENTISECS)) != null && !value.equals(expected); |
| |
| if (dwcParamFlag || decParamFlag) |
| suggestions.add(String.format("Speed up flushing of dirty pages by OS " + |
| "(alter %s%s%s parameter%s by setting to %s)", |
| (dwcParamFlag ? "vm." + DIRTY_WRITEBACK_CENTISECS : ""), |
| (dwcParamFlag && decParamFlag ? " and " : ""), |
| (decParamFlag ? "vm." + DIRTY_EXPIRE_CENTISECS : ""), |
| (dwcParamFlag && decParamFlag ? "s" : ""), |
| expected)); |
| |
| if ((value = readVmParam(SWAPPINESS)) != null) { |
| try { |
| double maxSwappiness = 10.0; |
| |
| if (Float.parseFloat(value) > maxSwappiness) |
| suggestions.add(String.format("Reduce pages swapping ratio (set vm.%s=%f or less)", SWAPPINESS, |
| maxSwappiness)); |
| } |
| catch (NumberFormatException ignored) { |
| // OS param not parsable as a number |
| } |
| } |
| |
| if ((value = readVmParam(ZONE_RECLAIM_MODE)) != null && !value.equals(expected = "0")) |
| suggestions.add(String.format("Disable NUMA memory reclaim (set vm.%s=%s)", ZONE_RECLAIM_MODE, |
| expected)); |
| |
| if ((value = readVmParam(EXTRA_FREE_KBYTES)) != null && !value.equals(expected = "1240000")) |
| suggestions.add(String.format("Avoid direct reclaim and page allocation failures (set vm.%s=%s)", |
| EXTRA_FREE_KBYTES, expected)); |
| } |
| |
| return suggestions; |
| } |
| |
| /** |
| * @param name Parameter name. |
| * @return Value (possibly null). |
| */ |
| @Nullable private static String readVmParam(@NotNull String name) { |
| try { |
| Path path = Paths.get(VM_PARAMS_BASE_PATH + name); |
| |
| if (!Files.exists(path)) |
| return null; |
| |
| return readLine(path); |
| } |
| catch (Exception ignored) { |
| return null; |
| } |
| } |
| |
| /** |
| * @param path Path. |
| * @return Read line. |
| * @throws IOException If failed. |
| */ |
| @Nullable private static String readLine(@NotNull Path path) throws IOException { |
| try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { |
| return reader.readLine(); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return S.toString(OsConfigurationSuggestions.class, this); |
| } |
| } |