Search in sources :

Example 1 with LogRoller

use of org.apache.hadoop.hbase.regionserver.LogRoller in project hbase by apache.

the class PeerProcedureHandlerImpl method transitSyncReplicationPeerState.

@Override
public void transitSyncReplicationPeerState(String peerId, int stage, HRegionServer rs) throws ReplicationException, IOException {
    ReplicationPeers replicationPeers = replicationSourceManager.getReplicationPeers();
    Lock peerLock = peersLock.acquireLock(peerId);
    try {
        ReplicationPeerImpl peer = replicationPeers.getPeer(peerId);
        if (peer == null) {
            throw new ReplicationException("Peer with id=" + peerId + " is not cached.");
        }
        if (!peer.getPeerConfig().isSyncReplication()) {
            throw new ReplicationException("Peer with id=" + peerId + " is not synchronous.");
        }
        SyncReplicationState newSyncReplicationState = peer.getNewSyncReplicationState();
        if (stage == 0) {
            if (newSyncReplicationState != SyncReplicationState.NONE) {
                LOG.warn("The new sync replication state for peer {} has already been set to {}, " + "this should be a retry, give up", peerId, newSyncReplicationState);
                return;
            }
            // refresh the peer state first, as when we transit to STANDBY, we may need to disable the
            // peer before processing the sync replication state.
            PeerState oldState = peer.getPeerState();
            boolean success = false;
            try {
                PeerState newState = replicationPeers.refreshPeerState(peerId);
                if (oldState.equals(PeerState.ENABLED) && newState.equals(PeerState.DISABLED)) {
                    replicationSourceManager.refreshSources(peerId);
                }
                success = true;
            } finally {
                if (!success) {
                    peer.setPeerState(oldState.equals(PeerState.ENABLED));
                }
            }
            newSyncReplicationState = replicationPeers.refreshPeerNewSyncReplicationState(peerId);
            SyncReplicationState oldSyncReplicationState = peer.getSyncReplicationState();
            peerActionListener.peerSyncReplicationStateChange(peerId, oldSyncReplicationState, newSyncReplicationState, stage);
        } else {
            if (newSyncReplicationState == SyncReplicationState.NONE) {
                LOG.warn("The new sync replication state for peer {} has already been clear, and the " + "current state is {}, this should be a retry, give up", peerId, newSyncReplicationState);
                return;
            }
            if (newSyncReplicationState == SyncReplicationState.STANDBY) {
                replicationSourceManager.drainSources(peerId);
                // Need to roll the wals and make the ReplicationSource for this peer track the new file.
                // If we do not do this, there will be two problems that can not be addressed at the same
                // time. First, if we just throw away the current wal file, and later when we transit the
                // peer to DA, and the wal has not been rolled yet, then the new data written to the wal
                // file will not be replicated and cause data inconsistency. But if we just track the
                // current wal file without rolling, it may contains some data before we transit the peer
                // to S, later if we transit the peer to DA, the data will also be replicated and cause
                // data inconsistency. So here we need to roll the wal, and let the ReplicationSource
                // track the new wal file, and throw the old wal files away.
                LogRoller roller = rs.getWalRoller();
                roller.requestRollAll();
                try {
                    roller.waitUntilWalRollFinished();
                } catch (InterruptedException e) {
                    // reset the interrupted flag
                    Thread.currentThread().interrupt();
                    throw (IOException) new InterruptedIOException("Interrupted while waiting for wal roll finish").initCause(e);
                }
            }
            SyncReplicationState oldState = peer.getSyncReplicationState();
            peerActionListener.peerSyncReplicationStateChange(peerId, oldState, newSyncReplicationState, stage);
            peer.transitSyncReplicationState();
        }
    } finally {
        peerLock.unlock();
    }
}
Also used : PeerState(org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState) InterruptedIOException(java.io.InterruptedIOException) ReplicationPeerImpl(org.apache.hadoop.hbase.replication.ReplicationPeerImpl) SyncReplicationState(org.apache.hadoop.hbase.replication.SyncReplicationState) ReplicationException(org.apache.hadoop.hbase.replication.ReplicationException) ReplicationPeers(org.apache.hadoop.hbase.replication.ReplicationPeers) Lock(java.util.concurrent.locks.Lock) LogRoller(org.apache.hadoop.hbase.regionserver.LogRoller)

Example 2 with LogRoller

use of org.apache.hadoop.hbase.regionserver.LogRoller in project hbase by apache.

the class WALPerformanceEvaluation method run.

@Override
public int run(String[] args) throws Exception {
    Path rootRegionDir = null;
    int numThreads = 1;
    long numIterations = 1000000;
    int numFamilies = 1;
    int syncInterval = 0;
    boolean noSync = false;
    boolean verify = false;
    boolean verbose = false;
    boolean cleanup = true;
    boolean noclosefs = false;
    long roll = Long.MAX_VALUE;
    boolean compress = false;
    String cipher = null;
    int numRegions = 1;
    // Process command line args
    for (int i = 0; i < args.length; i++) {
        String cmd = args[i];
        try {
            if (cmd.equals("-threads")) {
                numThreads = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-iterations")) {
                numIterations = Long.parseLong(args[++i]);
            } else if (cmd.equals("-path")) {
                rootRegionDir = new Path(args[++i]);
            } else if (cmd.equals("-families")) {
                numFamilies = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-qualifiers")) {
                numQualifiers = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-keySize")) {
                keySize = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-valueSize")) {
                valueSize = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-syncInterval")) {
                syncInterval = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-nosync")) {
                noSync = true;
            } else if (cmd.equals("-verify")) {
                verify = true;
            } else if (cmd.equals("-verbose")) {
                verbose = true;
            } else if (cmd.equals("-nocleanup")) {
                cleanup = false;
            } else if (cmd.equals("-noclosefs")) {
                noclosefs = true;
            } else if (cmd.equals("-roll")) {
                roll = Long.parseLong(args[++i]);
            } else if (cmd.equals("-compress")) {
                compress = true;
            } else if (cmd.equals("-encryption")) {
                cipher = args[++i];
            } else if (cmd.equals("-regions")) {
                numRegions = Integer.parseInt(args[++i]);
            } else if (cmd.equals("-traceFreq")) {
                // keep it here for compatible
                System.err.println("-traceFreq is not supported any more");
            } else if (cmd.equals("-h")) {
                printUsageAndExit();
            } else if (cmd.equals("--help")) {
                printUsageAndExit();
            } else {
                System.err.println("UNEXPECTED: " + cmd);
                printUsageAndExit();
            }
        } catch (Exception e) {
            printUsageAndExit();
        }
    }
    if (compress) {
        Configuration conf = getConf();
        conf.setBoolean(HConstants.ENABLE_WAL_COMPRESSION, true);
    }
    if (cipher != null) {
        // Set up WAL for encryption
        Configuration conf = getConf();
        conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, KeyProviderForTesting.class.getName());
        conf.set(HConstants.CRYPTO_MASTERKEY_NAME_CONF_KEY, "hbase");
        conf.setClass("hbase.regionserver.hlog.reader.impl", SecureProtobufLogReader.class, WAL.Reader.class);
        conf.setClass("hbase.regionserver.hlog.writer.impl", SecureProtobufLogWriter.class, Writer.class);
        conf.setBoolean(HConstants.ENABLE_WAL_ENCRYPTION, true);
        conf.set(HConstants.CRYPTO_WAL_ALGORITHM_CONF_KEY, cipher);
    }
    if (numThreads < numRegions) {
        LOG.warn("Number of threads is less than the number of regions; some regions will sit idle.");
    }
    // Internal config. goes off number of threads; if more threads than handlers, stuff breaks.
    // In regionserver, number of handlers == number of threads.
    getConf().setInt(HConstants.REGION_SERVER_HANDLER_COUNT, numThreads);
    if (rootRegionDir == null) {
        TEST_UTIL = new HBaseTestingUtil(getConf());
        rootRegionDir = TEST_UTIL.getDataTestDirOnTestFS("WALPerformanceEvaluation");
    }
    // Run WAL Performance Evaluation
    // First set the fs from configs.  In case we are on hadoop1
    CommonFSUtils.setFsDefault(getConf(), CommonFSUtils.getRootDir(getConf()));
    FileSystem fs = FileSystem.get(getConf());
    LOG.info("FileSystem={}, rootDir={}", fs, rootRegionDir);
    Span span = TraceUtil.getGlobalTracer().spanBuilder("WALPerfEval").startSpan();
    try (Scope scope = span.makeCurrent()) {
        rootRegionDir = rootRegionDir.makeQualified(fs.getUri(), fs.getWorkingDirectory());
        cleanRegionRootDir(fs, rootRegionDir);
        CommonFSUtils.setRootDir(getConf(), rootRegionDir);
        final WALFactory wals = new WALFactory(getConf(), "wals");
        final HRegion[] regions = new HRegion[numRegions];
        final Runnable[] benchmarks = new Runnable[numRegions];
        final MockRegionServerServices mockServices = new MockRegionServerServices(getConf());
        final LogRoller roller = new LogRoller(mockServices);
        Threads.setDaemonThreadRunning(roller, "WALPerfEval.logRoller");
        try {
            for (int i = 0; i < numRegions; i++) {
                // Initialize Table Descriptor
                // a table per desired region means we can avoid carving up the key space
                final TableDescriptor htd = createHTableDescriptor(i, numFamilies);
                regions[i] = openRegion(fs, rootRegionDir, htd, wals, roll, roller);
                benchmarks[i] = new WALPutBenchmark(regions[i], htd, numIterations, noSync, syncInterval);
            }
            ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).outputTo(System.out).convertRatesTo(TimeUnit.SECONDS).filter(MetricFilter.ALL).build();
            reporter.start(30, TimeUnit.SECONDS);
            long putTime = runBenchmark(benchmarks, numThreads);
            logBenchmarkResult("Summary: threads=" + numThreads + ", iterations=" + numIterations + ", syncInterval=" + syncInterval, numIterations * numThreads, putTime);
            for (int i = 0; i < numRegions; i++) {
                if (regions[i] != null) {
                    closeRegion(regions[i]);
                    regions[i] = null;
                }
            }
            if (verify) {
                LOG.info("verifying written log entries.");
                Path dir = new Path(CommonFSUtils.getRootDir(getConf()), AbstractFSWALProvider.getWALDirectoryName("wals"));
                long editCount = 0;
                FileStatus[] fsss = fs.listStatus(dir);
                if (fsss.length == 0)
                    throw new IllegalStateException("No WAL found");
                for (FileStatus fss : fsss) {
                    Path p = fss.getPath();
                    if (!fs.exists(p))
                        throw new IllegalStateException(p.toString());
                    editCount += verify(wals, p, verbose);
                }
                long expected = numIterations * numThreads;
                if (editCount != expected) {
                    throw new IllegalStateException("Counted=" + editCount + ", expected=" + expected);
                }
            }
        } finally {
            mockServices.stop("test clean up.");
            for (int i = 0; i < numRegions; i++) {
                if (regions[i] != null) {
                    closeRegion(regions[i]);
                }
            }
            if (null != roller) {
                LOG.info("shutting down log roller.");
                roller.close();
            }
            wals.shutdown();
            // Remove the root dir for this test region
            if (cleanup)
                cleanRegionRootDir(fs, rootRegionDir);
        }
    } finally {
        span.end();
        // We may be called inside a test that wants to keep on using the fs.
        if (!noclosefs) {
            fs.close();
        }
    }
    return 0;
}
Also used : FileStatus(org.apache.hadoop.fs.FileStatus) Configuration(org.apache.hadoop.conf.Configuration) HBaseConfiguration(org.apache.hadoop.hbase.HBaseConfiguration) ConsoleReporter(com.codahale.metrics.ConsoleReporter) Span(io.opentelemetry.api.trace.Span) FileSystem(org.apache.hadoop.fs.FileSystem) Path(org.apache.hadoop.fs.Path) MockRegionServerServices(org.apache.hadoop.hbase.MockRegionServerServices) HBaseTestingUtil(org.apache.hadoop.hbase.HBaseTestingUtil) KeyProviderForTesting(org.apache.hadoop.hbase.io.crypto.KeyProviderForTesting) IOException(java.io.IOException) TableDescriptor(org.apache.hadoop.hbase.client.TableDescriptor) HRegion(org.apache.hadoop.hbase.regionserver.HRegion) Scope(io.opentelemetry.context.Scope) LogRoller(org.apache.hadoop.hbase.regionserver.LogRoller)

Example 3 with LogRoller

use of org.apache.hadoop.hbase.regionserver.LogRoller in project hbase by apache.

the class TestSerialSyncReplication method test.

@Test
public void test() throws Exception {
    // change to serial
    UTIL1.getAdmin().updateReplicationPeerConfig(PEER_ID, ReplicationPeerConfig.newBuilder(UTIL1.getAdmin().getReplicationPeerConfig(PEER_ID)).setSerial(true).build());
    UTIL2.getAdmin().updateReplicationPeerConfig(PEER_ID, ReplicationPeerConfig.newBuilder(UTIL2.getAdmin().getReplicationPeerConfig(PEER_ID)).setSerial(true).build());
    UTIL2.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID, SyncReplicationState.STANDBY);
    UTIL1.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID, SyncReplicationState.ACTIVE);
    UTIL2.getAdmin().disableReplicationPeer(PEER_ID);
    writeAndVerifyReplication(UTIL1, UTIL2, 0, 100);
    MasterFileSystem mfs = UTIL2.getMiniHBaseCluster().getMaster().getMasterFileSystem();
    Path remoteWALDir = ReplicationUtils.getPeerRemoteWALDir(new Path(mfs.getWALRootDir(), ReplicationUtils.REMOTE_WAL_DIR_NAME), PEER_ID);
    FileStatus[] remoteWALStatus = mfs.getWALFileSystem().listStatus(remoteWALDir);
    assertEquals(1, remoteWALStatus.length);
    Path remoteWAL = remoteWALStatus[0].getPath();
    assertThat(remoteWAL.getName(), endsWith(ReplicationUtils.SYNC_WAL_SUFFIX));
    // will not replay this wal when transiting to DA.
    for (RegionServerThread t : UTIL1.getMiniHBaseCluster().getRegionServerThreads()) {
        LogRoller roller = t.getRegionServer().getWalRoller();
        roller.requestRollAll();
        roller.waitUntilWalRollFinished();
    }
    waitUntilDeleted(UTIL2, remoteWAL);
    UTIL2.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID, SyncReplicationState.DOWNGRADE_ACTIVE);
    UTIL1.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID, SyncReplicationState.STANDBY);
    // let's reopen the region
    RegionInfo region = Iterables.getOnlyElement(UTIL2.getAdmin().getRegions(TABLE_NAME));
    HRegionServer target = UTIL2.getOtherRegionServer(UTIL2.getRSForFirstRegionInTable(TABLE_NAME));
    UTIL2.getAdmin().move(region.getEncodedNameAsBytes(), target.getServerName());
    // here we will remove all the pending wals. This is not a normal operation sequence but anyway,
    // user could do this.
    UTIL2.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID, SyncReplicationState.STANDBY);
    // transit back to DA
    UTIL2.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID, SyncReplicationState.DOWNGRADE_ACTIVE);
    UTIL2.getAdmin().enableReplicationPeer(PEER_ID);
    // make sure that the async replication still works
    writeAndVerifyReplication(UTIL2, UTIL1, 100, 200);
}
Also used : MasterFileSystem(org.apache.hadoop.hbase.master.MasterFileSystem) Path(org.apache.hadoop.fs.Path) FileStatus(org.apache.hadoop.fs.FileStatus) RegionInfo(org.apache.hadoop.hbase.client.RegionInfo) RegionServerThread(org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread) LogRoller(org.apache.hadoop.hbase.regionserver.LogRoller) HRegionServer(org.apache.hadoop.hbase.regionserver.HRegionServer) Test(org.junit.Test)

Example 4 with LogRoller

use of org.apache.hadoop.hbase.regionserver.LogRoller in project hbase by apache.

the class TestAsyncFSWAL method testBrokenWriter.

@Test
public void testBrokenWriter() throws Exception {
    RegionServerServices services = mock(RegionServerServices.class);
    when(services.getConfiguration()).thenReturn(CONF);
    TableDescriptor td = TableDescriptorBuilder.newBuilder(TableName.valueOf("table")).setColumnFamily(ColumnFamilyDescriptorBuilder.of("row")).build();
    RegionInfo ri = RegionInfoBuilder.newBuilder(td.getTableName()).build();
    MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl();
    NavigableMap<byte[], Integer> scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
    for (byte[] fam : td.getColumnFamilyNames()) {
        scopes.put(fam, 0);
    }
    long timestamp = EnvironmentEdgeManager.currentTime();
    String testName = currentTest.getMethodName();
    AtomicInteger failedCount = new AtomicInteger(0);
    try (LogRoller roller = new LogRoller(services);
        AsyncFSWAL wal = new AsyncFSWAL(FS, CommonFSUtils.getWALRootDir(CONF), DIR.toString(), testName, CONF, null, true, null, null, GROUP, CHANNEL_CLASS) {

            @Override
            protected AsyncWriter createWriterInstance(Path path) throws IOException {
                AsyncWriter writer = super.createWriterInstance(path);
                return new AsyncWriter() {

                    @Override
                    public void close() throws IOException {
                        writer.close();
                    }

                    @Override
                    public long getLength() {
                        return writer.getLength();
                    }

                    @Override
                    public long getSyncedLength() {
                        return writer.getSyncedLength();
                    }

                    @Override
                    public CompletableFuture<Long> sync(boolean forceSync) {
                        CompletableFuture<Long> result = writer.sync(forceSync);
                        if (failedCount.incrementAndGet() < 1000) {
                            CompletableFuture<Long> future = new CompletableFuture<>();
                            FutureUtils.addListener(result, (r, e) -> future.completeExceptionally(new IOException("Inject Error")));
                            return future;
                        } else {
                            return result;
                        }
                    }

                    @Override
                    public void append(Entry entry) {
                        writer.append(entry);
                    }
                };
            }
        }) {
        wal.init();
        roller.addWAL(wal);
        roller.start();
        int numThreads = 10;
        AtomicReference<Exception> error = new AtomicReference<>();
        Thread[] threads = new Thread[numThreads];
        for (int i = 0; i < 10; i++) {
            final int index = i;
            threads[index] = new Thread("Write-Thread-" + index) {

                @Override
                public void run() {
                    byte[] row = Bytes.toBytes("row" + index);
                    WALEdit cols = new WALEdit();
                    cols.add(new KeyValue(row, row, row, timestamp + index, row));
                    WALKeyImpl key = new WALKeyImpl(ri.getEncodedNameAsBytes(), td.getTableName(), SequenceId.NO_SEQUENCE_ID, timestamp, WALKey.EMPTY_UUIDS, HConstants.NO_NONCE, HConstants.NO_NONCE, mvcc, scopes);
                    try {
                        wal.append(ri, key, cols, true);
                    } catch (IOException e) {
                        // should not happen
                        throw new UncheckedIOException(e);
                    }
                    try {
                        wal.sync();
                    } catch (IOException e) {
                        error.set(e);
                    }
                }
            };
        }
        for (Thread t : threads) {
            t.start();
        }
        for (Thread t : threads) {
            t.join();
        }
        assertNull(error.get());
    }
}
Also used : KeyValue(org.apache.hadoop.hbase.KeyValue) MultiVersionConcurrencyControl(org.apache.hadoop.hbase.regionserver.MultiVersionConcurrencyControl) RegionInfo(org.apache.hadoop.hbase.client.RegionInfo) UncheckedIOException(java.io.UncheckedIOException) CompletableFuture(java.util.concurrent.CompletableFuture) WALEdit(org.apache.hadoop.hbase.wal.WALEdit) Path(org.apache.hadoop.fs.Path) RegionServerServices(org.apache.hadoop.hbase.regionserver.RegionServerServices) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) TreeMap(java.util.TreeMap) TableDescriptor(org.apache.hadoop.hbase.client.TableDescriptor) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AsyncWriter(org.apache.hadoop.hbase.wal.WALProvider.AsyncWriter) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WALKeyImpl(org.apache.hadoop.hbase.wal.WALKeyImpl) LogRoller(org.apache.hadoop.hbase.regionserver.LogRoller) Test(org.junit.Test)

Aggregations

LogRoller (org.apache.hadoop.hbase.regionserver.LogRoller)4 Path (org.apache.hadoop.fs.Path)3 IOException (java.io.IOException)2 FileStatus (org.apache.hadoop.fs.FileStatus)2 RegionInfo (org.apache.hadoop.hbase.client.RegionInfo)2 TableDescriptor (org.apache.hadoop.hbase.client.TableDescriptor)2 Test (org.junit.Test)2 ConsoleReporter (com.codahale.metrics.ConsoleReporter)1 Span (io.opentelemetry.api.trace.Span)1 Scope (io.opentelemetry.context.Scope)1 InterruptedIOException (java.io.InterruptedIOException)1 UncheckedIOException (java.io.UncheckedIOException)1 TreeMap (java.util.TreeMap)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Lock (java.util.concurrent.locks.Lock)1 Configuration (org.apache.hadoop.conf.Configuration)1 FileSystem (org.apache.hadoop.fs.FileSystem)1 HBaseConfiguration (org.apache.hadoop.hbase.HBaseConfiguration)1