/** * Validates the path, verifying that it contains the {@link Constants#HEADER} or {@link * Constants#HEADER_FT} and a hostname:port specified. * * @param path the path to be verified * @param tachyonConf the instance of {@link tachyon.conf.TachyonConf} to be used * @return the verified path in a form like tachyon://host:port/dir. If only the "/dir" or "dir" * part is provided, the host and port are retrieved from property, tachyon.master.hostname * and tachyon.master.port, respectively. * @throws IOException if the given path is not valid */ public static String validatePath(String path, TachyonConf tachyonConf) throws IOException { if (path.startsWith(Constants.HEADER) || path.startsWith(Constants.HEADER_FT)) { if (!path.contains(":")) { throw new IOException( "Invalid Path: " + path + ". Use " + Constants.HEADER + "host:port/ ," + Constants.HEADER_FT + "host:port/" + " , or /file"); } else { return path; } } else { String hostname = NetworkAddressUtils.getConnectHost(ServiceType.MASTER_RPC, tachyonConf); int port = tachyonConf.getInt(Constants.MASTER_PORT); if (tachyonConf.getBoolean(Constants.ZOOKEEPER_ENABLED)) { return PathUtils.concatPath(Constants.HEADER_FT + hostname + ":" + port, path); } return PathUtils.concatPath(Constants.HEADER + hostname + ":" + port, path); } }
/** * Starts the Tachyon worker server. * * @throws Exception if the workers fail to start */ public void start() throws Exception { // NOTE: the order to start different services is sensitive. If you change it, do it cautiously. // Start serving metrics system, this will not block mWorkerMetricsSystem.start(); // Start serving the web server, this will not block // Requirement: metrics system started so we could add the metrics servlet to the web server // Consequence: when starting webserver, the webport will be updated. mWebServer.addHandler(mWorkerMetricsSystem.getServletHandler()); mWebServer.startWebServer(); // Set updated net address for this worker in context // Requirement: RPC, web, and dataserver ports are updated // Consequence: create a NetAddress object and set it into WorkerContext mNetAddress = new NetAddress( NetworkAddressUtils.getConnectHost(ServiceType.WORKER_RPC, mTachyonConf), mTachyonConf.getInt(Constants.WORKER_RPC_PORT), getDataLocalPort(), mTachyonConf.getInt(Constants.WORKER_WEB_PORT)); WorkerContext.setWorkerNetAddress(mNetAddress); // Start each worker // Requirement: NetAddress set in WorkerContext, so block worker can initialize BlockMasterSync // Consequence: worker id is granted startWorkers(); LOG.info("Started worker with id {}", WorkerIdRegistry.getWorkerId()); mIsServingRPC = true; // Start serving RPC, this will block LOG.info("Tachyon Worker version {} started @ {}", Version.VERSION, mWorkerAddress); mThriftServer.serve(); LOG.info("Tachyon Worker version {} ended @ {}", Version.VERSION, mWorkerAddress); }
private LocalTachyonMaster(final String tachyonHome) throws IOException { mTachyonHome = tachyonHome; TachyonConf tachyonConf = MasterContext.getConf(); mHostname = NetworkAddressUtils.getConnectHost(ServiceType.MASTER_RPC, tachyonConf); // To start the UFS either for integration or unit test. If it targets the unit test, UFS is // setup over the local file system (see also {@link LocalFilesystemCluster} - under folder of // "mTachyonHome/tachyon*". Otherwise, it starts some distributed file system cluster e.g., // miniDFSCluster (see also {@link tachyon.LocalMiniDFScluster} and setup the folder like // "hdfs://xxx:xxx/tachyon*". mUnderFSCluster = UnderFileSystemCluster.get(mTachyonHome + "/dfs", tachyonConf); mUnderFSFolder = mUnderFSCluster.getUnderFilesystemAddress() + "/tachyon_underfs_folder"; // To setup the journalFolder under either local file system or distributed ufs like // miniDFSCluster mJournalFolder = mUnderFSCluster.getUnderFilesystemAddress() + "/journal"; UnderFileSystemUtils.mkdirIfNotExists(mJournalFolder, tachyonConf); String[] masterServiceNames = new String[] { Constants.BLOCK_MASTER_SERVICE_NAME, Constants.FILE_SYSTEM_MASTER_SERVICE_NAME, Constants.RAW_TABLE_MASTER_SERVICE_NAME, }; for (String masterServiceName : masterServiceNames) { UnderFileSystemUtils.mkdirIfNotExists( PathUtils.concatPath(mJournalFolder, masterServiceName), tachyonConf); } UnderFileSystemUtils.touch( mJournalFolder + "/_format_" + System.currentTimeMillis(), tachyonConf); tachyonConf.set(Constants.MASTER_JOURNAL_FOLDER, mJournalFolder); tachyonConf.set(Constants.UNDERFS_ADDRESS, mUnderFSFolder); tachyonConf.set(Constants.MASTER_MIN_WORKER_THREADS, "1"); tachyonConf.set(Constants.MASTER_MAX_WORKER_THREADS, "100"); // If tests fail to connect they should fail early rather than using the default ridiculously // high retries tachyonConf.set(Constants.MASTER_RETRY_COUNT, "3"); // Since tests are always running on a single host keep the resolution timeout low as otherwise // people running with strange network configurations will see very slow tests tachyonConf.set(Constants.HOST_RESOLUTION_TIMEOUT_MS, "250"); tachyonConf.set(Constants.WEB_THREAD_COUNT, "1"); tachyonConf.set( Constants.WEB_RESOURCES, PathUtils.concatPath(System.getProperty("user.dir"), "../servers/src/main/webapp")); mTachyonMaster = TachyonMaster.Factory.createMaster(); // Reset the master port tachyonConf.set(Constants.MASTER_PORT, Integer.toString(getRPCLocalPort())); Runnable runMaster = new Runnable() { @Override public void run() { try { mTachyonMaster.start(); } catch (Exception e) { throw new RuntimeException(e + " \n Start Master Error \n" + e.getMessage(), e); } } }; mMasterThread = new Thread(runMaster); }
/** * Creates a new instance of {@link BlockWorker}. * * @throws ConnectionFailedException if network connection failed * @throws IOException for other exceptions */ public BlockWorker() throws IOException, ConnectionFailedException { super( Executors.newFixedThreadPool( 4, ThreadFactoryUtils.build("block-worker-heartbeat-%d", true))); mTachyonConf = WorkerContext.getConf(); mStartTimeMs = System.currentTimeMillis(); // Setup MasterClientBase mBlockMasterClient = new BlockMasterClient( NetworkAddressUtils.getConnectAddress(ServiceType.MASTER_RPC, mTachyonConf), mTachyonConf); mFileSystemMasterClient = new FileSystemMasterClient( NetworkAddressUtils.getConnectAddress(ServiceType.MASTER_RPC, mTachyonConf), mTachyonConf); // Set up BlockDataManager WorkerSource workerSource = new WorkerSource(); mBlockDataManager = new BlockDataManager( workerSource, mBlockMasterClient, mFileSystemMasterClient, new TieredBlockStore()); // Setup metrics collection mWorkerMetricsSystem = new MetricsSystem("worker", mTachyonConf); workerSource.registerGauges(mBlockDataManager); mWorkerMetricsSystem.registerSource(workerSource); // Setup DataServer mDataServer = DataServer.Factory.create( NetworkAddressUtils.getBindAddress(ServiceType.WORKER_DATA, mTachyonConf), mBlockDataManager, mTachyonConf); // Reset data server port mTachyonConf.set(Constants.WORKER_DATA_PORT, Integer.toString(mDataServer.getPort())); // Setup RPC Server mServiceHandler = new BlockWorkerClientServiceHandler(mBlockDataManager); mThriftServerSocket = createThriftServerSocket(); mPort = NetworkAddressUtils.getThriftPort(mThriftServerSocket); // Reset worker RPC port mTachyonConf.set(Constants.WORKER_RPC_PORT, Integer.toString(mPort)); mThriftServer = createThriftServer(); // Setup web server mWebServer = new WorkerUIWebServer( ServiceType.WORKER_WEB, NetworkAddressUtils.getBindAddress(ServiceType.WORKER_WEB, mTachyonConf), mBlockDataManager, NetworkAddressUtils.getConnectAddress(ServiceType.WORKER_RPC, mTachyonConf), mStartTimeMs, mTachyonConf); mWorkerMetricsSystem.start(); // Add the metrics servlet to the web server, this must be done after the metrics system starts mWebServer.addHandler(mWorkerMetricsSystem.getServletHandler()); mWebServer.startWebServer(); int webPort = mWebServer.getLocalPort(); // Get the worker id mWorkerNetAddress = new NetAddress( NetworkAddressUtils.getConnectHost(ServiceType.WORKER_RPC, mTachyonConf), mPort, mDataServer.getPort(), webPort); WorkerIdRegistry.registerWithBlockMaster(mBlockMasterClient, mWorkerNetAddress); mBlockMasterSync = new BlockMasterSync(mBlockDataManager, mWorkerNetAddress, mBlockMasterClient); // Setup PinListSyncer mPinListSync = new PinListSync(mBlockDataManager, mFileSystemMasterClient); // Setup session cleaner mSessionCleanerThread = new SessionCleaner(mBlockDataManager); // Setup space reserver if (mTachyonConf.getBoolean(Constants.WORKER_TIERED_STORE_RESERVER_ENABLED)) { mSpaceReserver = new SpaceReserver(mBlockDataManager); } }
@Override public List<String> getFileLocations(String path) throws IOException { List<String> ret = new ArrayList<String>(); ret.add(NetworkAddressUtils.getConnectHost(ServiceType.WORKER_RPC, mTachyonConf)); return ret; }
/** * Reads from a remote byte buffer. * * @param tachyonFS a TachyonFS * @param blockInfo the block information * @param offset offset to start the read at * @param len number of bytes to read * @param conf Tachyon configuration * @return <code>ByteBuffer</code> containing the bytes read */ public ByteBuffer readRemoteByteBuffer( TachyonFS tachyonFS, ClientBlockInfo blockInfo, long offset, long len, TachyonConf conf) { ByteBuffer buf = null; try { List<NetAddress> blockLocations = blockInfo.getLocations(); LOG.info("Block locations:" + blockLocations); String localhost = NetworkAddressUtils.getConnectHost(ServiceType.WORKER_RPC, conf); for (NetAddress blockLocation : blockLocations) { String host = blockLocation.mHost; int port = blockLocation.mSecondaryPort; // The data is not in remote machine's memory if primary port == -1. We check primary port // because if the data is in the under storage, the secondary port (data transfer port) // will be set. if (blockLocation.mPort == -1) { continue; } if (host.equals(InetAddress.getLocalHost().getHostName()) || host.equals(InetAddress.getLocalHost().getHostAddress()) || host.equals(localhost)) { LOG.warn( "Master thinks the local machine has data, but not!" + "(or local read is disabled) blockId:{}", blockInfo.blockId); } LOG.info( host + ":" + port + " current host is " + localhost + " " + NetworkAddressUtils.getLocalIpAddress(conf)); try { buf = retrieveByteBufferFromRemoteMachine( new InetSocketAddress(host, port), blockInfo.blockId, offset, len, conf); if (buf != null) { break; } } catch (IOException e) { LOG.error( "Fail to retrieve byte buffer for block " + blockInfo.blockId + " from remote " + host + ":" + port + " with offset " + offset + " and length " + len, e); buf = null; } } } catch (IOException e) { LOG.error("Failed to get read data from remote ", e); buf = null; } return buf; }