public void initialize() throws IOException, KeeperException, InterruptedException, BookieException { // instantiate zookeeper client to initialize ledger manager this.zk = instantiateZookeeperClient(conf); checkEnvironment(this.zk); activeLedgerManagerFactory = LedgerManagerFactory.newLedgerManagerFactory(conf, this.zk); activeLedgerManager = activeLedgerManagerFactory.newActiveLedgerManager(); // instantiate the journal journal = new Journal(conf, ledgerDirsManager, statsLogger); // Check the type of storage. if (conf.getSortedLedgerStorageEnabled()) { ledgerStorage = new SortedLedgerStorage( conf, activeLedgerManager, ledgerDirsManager, indexDirsManager, journal, statsLogger); } else { ledgerStorage = new InterleavedLedgerStorage( conf, activeLedgerManager, ledgerDirsManager, indexDirsManager, journal, statsLogger); } ledgerStorage.registerListener(this); // start sync thread syncThread = new SyncThread(conf, getLedgerDirsListener(), ledgerStorage, journal); handles = new HandleFactoryImpl(ledgerStorage, statsLogger); // Initialise ledgerDirManager. This would look through all the // configured directories. When disk errors or all the ledger // directories are full, would throws exception and fail bookie startup. try { checkDiskSpace(); } catch (NoWritableLedgerDirException nwlde) { LOG.info("Ledger storage is already full : ", nwlde); // if there is no writable ledger dir, we should try reclaimSpace reclaimDiskSpace(); // check disk again if we still can't have enough room for replaying journal, fail it checkDiskSpace(); } // ZK ephemeral node for this Bookie. String myID = getMyId(); zkBookieRegPath = this.bookieRegistrationPath + myID; zkBookieReadOnlyPath = this.bookieReadonlyRegistrationPath + "/" + myID; }
// internal shutdown method to let shutdown bookie gracefully // when encountering exception synchronized int shutdown(int exitCode) { try { if (running) { // avoid shutdown twice // the exitCode only set when first shutdown usually due to exception found this.exitCode = exitCode; // mark bookie as in shutting down progress shuttingdown = true; // Shutdown Sync thread syncThread.shutdown(); // Shutdown disk checker ledgerDirsManager.shutdown(); if (indexDirsManager != ledgerDirsManager) { indexDirsManager.shutdown(); } // Shutdown journal journal.shutdown(); this.join(); // Shutdown the EntryLogger which has the GarbageCollector Thread running ledgerStorage.shutdown(); // close Ledger Manager try { activeLedgerManager.close(); activeLedgerManagerFactory.uninitialize(); } catch (IOException ie) { LOG.error("Failed to close active ledger manager : ", ie); } // Shutdown the ZK client if (zk != null) zk.close(); // Shutdown State Service stateService.shutdown(); // setting running to false here, so watch thread in bookie server know it only after bookie // shut down running = false; } } catch (InterruptedException ie) { LOG.error("Interrupted during shutting down bookie : ", ie); } return this.exitCode; }
@Override public synchronized void start() { setDaemon(true); LOG.info("I'm starting a bookie with journal directory {}", journalDirectory.getName()); // Start DiskChecker thread ledgerDirsManager.start(); if (indexDirsManager != ledgerDirsManager) { indexDirsManager.start(); } // start sync thread first, so during replaying journals, we could do checkpoint // which reduce the chance that we need to replay journals again if bookie restarted // again before finished journal replays. syncThread.start(); // replay journals try { readJournal(); } catch (IOException ioe) { LOG.error("Exception while replaying journals, shutting down", ioe); shutdown(ExitCode.BOOKIE_EXCEPTION); return; } catch (BookieException be) { LOG.error("Exception while replaying journals, shutting down", be); shutdown(ExitCode.BOOKIE_EXCEPTION); return; } // Do a fully flush after journal replay try { syncThread.requestFlush().get(); } catch (InterruptedException e) { LOG.warn("Interrupting the fully flush after replaying journals : ", e); Thread.currentThread().interrupt(); } catch (ExecutionException e) { LOG.error("Error on executing a fully flush after replaying journals."); shutdown(ExitCode.BOOKIE_EXCEPTION); } // start bookie thread super.start(); // After successful bookie startup, register listener for disk // error/full notifications. ledgerDirsManager.addLedgerDirsListener(getLedgerDirsListener()); if (indexDirsManager != ledgerDirsManager) { indexDirsManager.addLedgerDirsListener(getLedgerDirsListener()); } ledgerStorage.start(); // set running here. // since bookie server use running as a flag to tell bookie server whether it is alive // if setting it in bookie thread, the watcher might run before bookie thread. running = true; try { registerBookie(true).get(); } catch (Exception ie) { LOG.error("Couldn't register bookie with zookeeper, shutting down : ", ie); shutdown(ExitCode.ZK_REG_FAIL); } }
private void reclaimDiskSpace() throws IOException { LOG.info("Reclaiming disk space from ledger storage."); ledgerStorage.reclaimDiskSpace(); LOG.info("Reclaimed disk space from ledger storage."); }
protected void addEntryByLedgerId(long ledgerId, ByteBuffer entry) throws IOException, BookieException { byte[] key = ledgerStorage.readMasterKey(ledgerId); LedgerDescriptor handle = handles.getHandle(ledgerId, key); handle.addEntry(entry); }