blob: f10e9cfa5d0d2b233ac96a18c032ce2a68098c6a [file] [log] [blame]
// 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.doris;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.CommandLineOptions;
import org.apache.doris.common.Config;
import org.apache.doris.common.Log4jConfig;
import org.apache.doris.common.Version;
import org.apache.doris.common.util.JdkUtils;
import org.apache.doris.http.HttpServer;
import org.apache.doris.journal.bdbje.BDBTool;
import org.apache.doris.journal.bdbje.BDBToolOptions;
import org.apache.doris.qe.QeService;
import org.apache.doris.service.ExecuteEnv;
import org.apache.doris.service.FeServer;
import org.apache.doris.service.FrontendOptions;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
public class PaloFe {
private static final Logger LOG = LogManager.getLogger(PaloFe.class);
public static final String DORIS_HOME_DIR = System.getenv("DORIS_HOME");
public static final String PID_DIR = System.getenv("PID_DIR");
public static void main(String[] args) {
start(DORIS_HOME_DIR, PID_DIR, args);
}
// entrance for doris frontend
public static void start(String dorisHomeDir, String pidDir, String[] args) {
if (Strings.isNullOrEmpty(dorisHomeDir)) {
System.err.println("env DORIS_HOME is not set.");
return;
}
if (Strings.isNullOrEmpty(pidDir)) {
System.err.println("env PID_DIR is not set.");
return;
}
CommandLineOptions cmdLineOpts = parseArgs(args);
System.out.println(cmdLineOpts.toString());
try {
// pid file
if (!createAndLockPidFile(pidDir + "/fe.pid")) {
throw new IOException("pid file is already locked.");
}
// init config
new Config().init(dorisHomeDir + "/conf/fe.conf");
// check it after Config is initialized, otherwise the config 'check_java_version' won't work.
if (!JdkUtils.checkJavaVersion()) {
throw new IllegalArgumentException("Java version doesn't match");
}
Log4jConfig.initLogging();
// set dns cache ttl
java.security.Security.setProperty("networkaddress.cache.ttl" , "60");
// check command line options
checkCommandLineOptions(cmdLineOpts);
LOG.info("Palo FE starting...");
FrontendOptions.init();
ExecuteEnv.setup();
// init catalog and wait it be ready
Catalog.getInstance().initialize(args);
Catalog.getInstance().waitForReady();
// init and start:
// 1. QeService for MySQL Server
// 2. FeServer for Thrift Server
// 3. HttpServer for HTTP Server
QeService qeService = new QeService(Config.query_port, Config.mysql_service_nio_enabled, ExecuteEnv.getInstance().getScheduler());
FeServer feServer = new FeServer(Config.rpc_port);
HttpServer httpServer = new HttpServer(Config.http_port);
httpServer.setup();
feServer.start();
httpServer.start();
qeService.start();
while (true) {
Thread.sleep(2000);
}
} catch (Throwable e) {
e.printStackTrace();
return;
}
}
/*
* -v --version
* Print the version of Palo Frontend
* -h --helper
* Specify the helper node when joining a bdb je replication group
* -b --bdb
* Run bdbje debug tools
*
* -l --listdb
* List all database names in bdbje
* -d --db
* Specify a database in bdbje
*
* -s --stat
* Print statistic of a database, including count, first key, last key
* -f --from
* Specify the start scan key
* -t --to
* Specify the end scan key
* -m --metaversion
* Specify the meta version to decode log value
*
*/
private static CommandLineOptions parseArgs(String[] args) {
CommandLineParser commandLineParser = new BasicParser();
Options options = new Options();
options.addOption("v", "version", false, "Print the version of Palo Frontend");
options.addOption("h", "helper", true, "Specify the helper node when joining a bdb je replication group");
options.addOption("b", "bdb", false, "Run bdbje debug tools");
options.addOption("l", "listdb", false, "Run bdbje debug tools");
options.addOption("d", "db", true, "Specify a database in bdbje");
options.addOption("s", "stat", false, "Print statistic of a database, including count, first key, last key");
options.addOption("f", "from", true, "Specify the start scan key");
options.addOption("t", "to", true, "Specify the end scan key");
options.addOption("m", "metaversion", true, "Specify the meta version to decode log value");
CommandLine cmd = null;
try {
cmd = commandLineParser.parse(options, args);
} catch (final ParseException e) {
e.printStackTrace();
System.err.println("Failed to parse command line. exit now");
System.exit(-1);
}
// version
if (cmd.hasOption('v') || cmd.hasOption("version")) {
return new CommandLineOptions(true, "", null);
} else if (cmd.hasOption('b') || cmd.hasOption("bdb")) {
if (cmd.hasOption('l') || cmd.hasOption("listdb")) {
// list bdb je databases
BDBToolOptions bdbOpts = new BDBToolOptions(true, "", false, "", "", 0);
return new CommandLineOptions(false, "", bdbOpts);
} else if (cmd.hasOption('d') || cmd.hasOption("db")) {
// specify a database
String dbName = cmd.getOptionValue("db");
if (Strings.isNullOrEmpty(dbName)) {
System.err.println("BDBJE database name is missing");
System.exit(-1);
}
if (cmd.hasOption('s') || cmd.hasOption("stat")) {
BDBToolOptions bdbOpts = new BDBToolOptions(false, dbName, true, "", "", 0);
return new CommandLineOptions(false, "", bdbOpts);
} else {
String fromKey = "";
String endKey = "";
int metaVersion = 0;
if (cmd.hasOption('f') || cmd.hasOption("from")) {
fromKey = cmd.getOptionValue("from");
if (Strings.isNullOrEmpty(fromKey)) {
System.err.println("from key is missing");
System.exit(-1);
}
}
if (cmd.hasOption('t') || cmd.hasOption("to")) {
endKey = cmd.getOptionValue("to");
if (Strings.isNullOrEmpty(endKey)) {
System.err.println("end key is missing");
System.exit(-1);
}
}
if (cmd.hasOption('m') || cmd.hasOption("metaversion")) {
try {
metaVersion = Integer.valueOf(cmd.getOptionValue("metaversion"));
} catch (NumberFormatException e) {
System.err.println("Invalid meta version format");
System.exit(-1);
}
}
BDBToolOptions bdbOpts = new BDBToolOptions(false, dbName, false, fromKey, endKey, metaVersion);
return new CommandLineOptions(false, "", bdbOpts);
}
} else {
System.err.println("Invalid options when running bdb je tools");
System.exit(-1);
}
} else if (cmd.hasOption('h') || cmd.hasOption("helper")) {
String helperNode = cmd.getOptionValue("helper");
if (Strings.isNullOrEmpty(helperNode)) {
System.err.println("Missing helper node");
System.exit(-1);
}
return new CommandLineOptions(false, helperNode, null);
}
// helper node is null, means no helper node is specified
return new CommandLineOptions(false, null, null);
}
private static void checkCommandLineOptions(CommandLineOptions cmdLineOpts) {
if (cmdLineOpts.isVersion()) {
System.out.println("Build version: " + Version.DORIS_BUILD_VERSION);
System.out.println("Build time: " + Version.DORIS_BUILD_TIME);
System.out.println("Build info: " + Version.DORIS_BUILD_INFO);
System.out.println("Build hash: " + Version.DORIS_BUILD_HASH);
System.out.println("Java compile version: " + Version.DORIS_JAVA_COMPILE_VERSION);
System.exit(0);
} else if (cmdLineOpts.runBdbTools()) {
BDBTool bdbTool = new BDBTool(Catalog.getCurrentCatalog().getBdbDir(), cmdLineOpts.getBdbToolOpts());
if (bdbTool.run()) {
System.exit(0);
} else {
System.exit(-1);
}
}
// go on
}
private static boolean createAndLockPidFile(String pidFilePath) throws IOException {
File pid = new File(pidFilePath);
RandomAccessFile file = new RandomAccessFile(pid, "rws");
try {
FileLock lock = file.getChannel().tryLock();
if (lock == null) {
return false;
}
pid.deleteOnExit();
String name = ManagementFactory.getRuntimeMXBean().getName();
file.setLength(0);
file.write(name.split("@")[0].getBytes(Charsets.UTF_8));
return true;
} catch (OverlappingFileLockException e) {
file.close();
return false;
} catch (IOException e) {
file.close();
throw e;
}
}
}