/* * 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 tachyon.master; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import org.apache.curator.test.TestingServer; import org.apache.log4j.Logger; import tachyon.Constants; import tachyon.UnderFileSystem; import tachyon.UnderFileSystemCluster; import tachyon.client.TachyonFS; import tachyon.conf.CommonConf; import tachyon.conf.MasterConf; import tachyon.conf.UserConf; import tachyon.conf.WorkerConf; import tachyon.util.CommonUtils; import tachyon.worker.TachyonWorker; /** * A local Tachyon cluster with Multiple masters */ public class LocalTachyonClusterMultiMaster { public class MasterThread extends Thread { private TachyonMaster mMaster = null; public MasterThread(TachyonMaster master) { mMaster = master; } @Override public void run() { try { mMaster.start(); } catch (Exception e) { CommonUtils.runtimeException(e + " \n Start Master Error \n" + e.getMessage()); } } public void shutdown() { try { mMaster.stop(); } catch (Exception e) { e.printStackTrace(); } } } private static final Logger LOG = Logger.getLogger(Constants.LOGGER_TYPE); public static void main(String[] args) throws Exception { LocalTachyonCluster cluster = new LocalTachyonCluster(100); cluster.start(); CommonUtils.sleepMs(null, Constants.SECOND_MS); cluster.stop(); CommonUtils.sleepMs(null, Constants.SECOND_MS); cluster = new LocalTachyonCluster(100); cluster.start(); CommonUtils.sleepMs(null, Constants.SECOND_MS); cluster.stop(); CommonUtils.sleepMs(null, Constants.SECOND_MS); } private TestingServer mCuratorServer = null; private int mNumOfMasters = 0; private List<TachyonMaster> mMasters = null; private TachyonWorker mWorker = null; private List<Integer> mMastersPorts; private int mWorkerPort; private long mWorkerCapacityBytes; private String mTachyonHome; private String mWorkerDataFolder; private List<MasterThread> mMasterThreads = null; private Thread mWorkerThread = null; private String mLocalhostName = null; private UnderFileSystemCluster mUnderFSCluster = null; private List<TachyonFS> mClients = new ArrayList<TachyonFS>(); public LocalTachyonClusterMultiMaster(int masterPort, int workerPort, long workerCapacityBytes, int masters) { mNumOfMasters = masters; mMastersPorts = new ArrayList<Integer>(masters); for (int k = 0; k < mNumOfMasters; k ++) { mMastersPorts.add(masterPort + k * 10); } mWorkerPort = workerPort; mWorkerCapacityBytes = workerCapacityBytes; try { mCuratorServer = new TestingServer(); } catch (Exception e) { CommonUtils.runtimeException(e); } } public LocalTachyonClusterMultiMaster(long workerCapacityBytes, int masters) { this(Constants.DEFAULT_MASTER_PORT - 1000, Constants.DEFAULT_WORKER_PORT - 1000, workerCapacityBytes, masters); } public synchronized TachyonFS getClient() throws IOException { mClients.add(TachyonFS.get(Constants.HEADER_FT + mCuratorServer.getConnectString())); return mClients.get(mClients.size() - 1); } public synchronized List<TachyonFS> getClients() { return mClients; } String getEditLogPath() { return mUnderFSCluster.getUnderFilesystemAddress() + "/journal/log.data"; } String getImagePath() { return mUnderFSCluster.getUnderFilesystemAddress() + "/journal/image.data"; } MasterInfo getMasterInfo(int masterIndex) { return mMasters.get(masterIndex).getMasterInfo(); } public List<Integer> getMastersPorts() { return mMastersPorts; } public String getTachyonHome() { return mTachyonHome; } public String getTempFolderInUnderFs() { return CommonConf.get().UNDERFS_ADDRESS; } public int getWorkerPort() { return mWorkerPort; } public boolean killLeader() { for (int k = 0; k < mNumOfMasters; k ++) { if (mMasters.get(k).isStarted()) { try { mMasters.get(k).stop(); } catch (Exception e) { LOG.error(e.getMessage(), e); return false; } return true; } } return false; } private void deleteDir(String path) throws IOException { UnderFileSystem ufs = UnderFileSystem.get(path); if (ufs.exists(path) && !ufs.delete(path, true)) { throw new IOException("Folder " + path + " already exists but can not be deleted."); } } private void mkdir(String path) throws IOException { UnderFileSystem ufs = UnderFileSystem.get(path); if (!ufs.mkdirs(path, true)) { throw new IOException("Failed to make folder: " + path); } } public void start() throws IOException { mTachyonHome = File.createTempFile("Tachyon", "").getAbsoluteFile() + "U" + System.currentTimeMillis(); mWorkerDataFolder = mTachyonHome + "/ramdisk"; String masterDataFolder = mTachyonHome + "/data"; String masterLogFolder = mTachyonHome + "/logs"; deleteDir(mTachyonHome); mkdir(mTachyonHome); mkdir(masterDataFolder); mkdir(masterLogFolder); mLocalhostName = InetAddress.getLocalHost().getCanonicalHostName(); mUnderFSCluster = UnderFileSystemCluster.get(mTachyonHome + "/dfs"); String underfsFolder = mUnderFSCluster.getUnderFilesystemAddress() + "/tachyon_underfs_folder"; String masterJournalFolder = mUnderFSCluster.getUnderFilesystemAddress() + "/journal"; System.setProperty("tachyon.home", mTachyonHome); System.setProperty("tachyon.underfs.address", underfsFolder); System.setProperty("tachyon.master.journal.folder", masterJournalFolder + Constants.PATH_SEPARATOR); System.setProperty("tachyon.usezookeeper", "true"); System.setProperty("tachyon.zookeeper.address", mCuratorServer.getConnectString()); System.setProperty("tachyon.zookeeper.election.path", "/election"); System.setProperty("tachyon.zookeeper.leader.path", "/leader"); System.setProperty("tachyon.master.hostname", mLocalhostName); System.setProperty("tachyon.master.port", mMastersPorts.get(0) + ""); System.setProperty("tachyon.master.web.port", (mMastersPorts.get(0) + 1) + ""); System.setProperty("tachyon.worker.port", mWorkerPort + ""); System.setProperty("tachyon.worker.data.port", (mWorkerPort + 1) + ""); System.setProperty("tachyon.worker.data.folder", mWorkerDataFolder); System.setProperty("tachyon.worker.memory.size", mWorkerCapacityBytes + ""); System.setProperty("tachyon.worker.to.master.heartbeat.interval.ms", 15 + ""); CommonConf.clear(); MasterConf.clear(); WorkerConf.clear(); UserConf.clear(); mkdir(masterJournalFolder); CommonUtils.touch(masterJournalFolder + "/_format_" + System.currentTimeMillis()); mkdir(CommonConf.get().UNDERFS_DATA_FOLDER); mkdir(CommonConf.get().UNDERFS_WORKERS_FOLDER); mMasters = new ArrayList<TachyonMaster>(); mMasterThreads = new ArrayList<MasterThread>(); for (int k = 0; k < mNumOfMasters; k ++) { mMasters.add(new TachyonMaster(new InetSocketAddress(mLocalhostName, mMastersPorts.get(k)), mMastersPorts.get(k) + 1, 1, 1, 1)); MasterThread thread = new MasterThread(mMasters.get(k)); thread.start(); mMasterThreads.add(thread); } CommonUtils.sleepMs(null, 10); mWorker = TachyonWorker.createWorker( CommonUtils.parseInetSocketAddress(mCuratorServer.getConnectString()), new InetSocketAddress(mLocalhostName, mWorkerPort), mWorkerPort + 1, 1, 1, 1, mWorkerDataFolder, mWorkerCapacityBytes); Runnable runWorker = new Runnable() { @Override public void run() { try { mWorker.start(); } catch (Exception e) { CommonUtils.runtimeException(e + " \n Start Master Error \n" + e.getMessage()); } } }; mWorkerThread = new Thread(runWorker); mWorkerThread.start(); } public void stop() throws Exception { stopTFS(); stopUFS(); } public void stopTFS() throws Exception { for (TachyonFS fs : mClients) { fs.close(); } mWorker.stop(); for (int k = 0; k < mNumOfMasters; k ++) { mMasterThreads.get(k).shutdown(); } mCuratorServer.stop(); System.clearProperty("tachyon.home"); System.clearProperty("tachyon.usezookeeper"); System.clearProperty("tachyon.zookeeper.address"); System.clearProperty("tachyon.zookeeper.election.path"); System.clearProperty("tachyon.zookeeper.leader.path"); System.clearProperty("tachyon.master.hostname"); System.clearProperty("tachyon.master.port"); System.clearProperty("tachyon.master.web.port"); System.clearProperty("tachyon.worker.port"); System.clearProperty("tachyon.worker.data.port"); System.clearProperty("tachyon.worker.data.folder"); System.clearProperty("tachyon.worker.memory.size"); System.clearProperty("tachyon.worker.to.master.heartbeat.interval.ms"); } public void stopUFS() throws Exception { if (null != mUnderFSCluster) { mUnderFSCluster.cleanup(); } System.clearProperty("tachyon.master.journal.folder"); System.clearProperty("tachyon.underfs.address"); } }