use of com.twitter.distributedlog.AsyncLogReader in project distributedlog by twitter.
the class AsyncReaderBenchmark method benchmark.
@Override
protected void benchmark(DistributedLogNamespace namespace, String logName, StatsLogger statsLogger) {
DistributedLogManager dlm = null;
while (null == dlm) {
try {
dlm = namespace.openLog(streamName);
} catch (IOException ioe) {
logger.warn("Failed to create dlm for stream {} : ", streamName, ioe);
}
if (null == dlm) {
try {
TimeUnit.MILLISECONDS.sleep(conf.getZKSessionTimeoutMilliseconds());
} catch (InterruptedException e) {
}
}
}
logger.info("Created dlm for stream {}.", streamName);
// Stats
OpStatsLogger openReaderStats = statsLogger.getOpStatsLogger("open_reader");
OpStatsLogger blockingReadStats = statsLogger.getOpStatsLogger("blocking_read");
Counter readCounter = statsLogger.getCounter("reads");
AsyncLogReader reader = null;
DLSN lastDLSN = null;
Long lastTxId = null;
while (null == reader) {
// initialize the last txid
if (null == lastTxId) {
switch(readMode) {
case OLDEST:
lastTxId = 0L;
lastDLSN = DLSN.InitialDLSN;
break;
case LATEST:
lastTxId = Long.MAX_VALUE;
try {
lastDLSN = dlm.getLastDLSN();
} catch (IOException ioe) {
continue;
}
break;
case REWIND:
lastTxId = System.currentTimeMillis() - rewindMs;
lastDLSN = null;
break;
case POSITION:
lastTxId = fromTxId;
lastDLSN = null;
break;
default:
logger.warn("Unsupported mode {}", readMode);
printUsage();
System.exit(0);
break;
}
logger.info("Reading from transaction id = {}, dlsn = {}", lastTxId, lastDLSN);
}
// Open the reader
Stopwatch stopwatch = Stopwatch.createStarted();
try {
if (null == lastDLSN) {
reader = FutureUtils.result(dlm.openAsyncLogReader(lastTxId));
} else {
reader = FutureUtils.result(dlm.openAsyncLogReader(lastDLSN));
}
long elapsedMs = stopwatch.elapsed(TimeUnit.MICROSECONDS);
openReaderStats.registerSuccessfulEvent(elapsedMs);
logger.info("It took {} ms to position the reader to transaction id = {}, dlsn = {}", lastTxId, lastDLSN);
} catch (IOException ioe) {
openReaderStats.registerFailedEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
logger.warn("Failed to create reader for stream {} reading from tx id = {}, dlsn = {}.", new Object[] { streamName, lastTxId, lastDLSN });
}
if (null == reader) {
try {
TimeUnit.MILLISECONDS.sleep(conf.getZKSessionTimeoutMilliseconds());
} catch (InterruptedException e) {
}
continue;
}
List<LogRecordWithDLSN> records;
stopwatch = Stopwatch.createUnstarted();
while (true) {
try {
stopwatch.start();
records = FutureUtils.result(reader.readBulk(batchSize));
long elapsedMicros = stopwatch.stop().elapsed(TimeUnit.MICROSECONDS);
blockingReadStats.registerSuccessfulEvent(elapsedMicros);
if (!records.isEmpty()) {
readCounter.add(records.size());
LogRecordWithDLSN lastRecord = records.get(records.size() - 1);
lastTxId = lastRecord.getTransactionId();
lastDLSN = lastRecord.getDlsn();
}
stopwatch.reset();
} catch (IOException e) {
logger.warn("Encountered reading record from stream {} : ", streamName, e);
reader = null;
break;
}
}
try {
TimeUnit.MILLISECONDS.sleep(conf.getZKSessionTimeoutMilliseconds());
} catch (InterruptedException e) {
}
}
}
use of com.twitter.distributedlog.AsyncLogReader in project distributedlog by twitter.
the class TestDistributedLogServer method testDeleteStream.
@Test(timeout = 60000)
public void testDeleteStream() throws Exception {
String name = "dlserver-delete-stream";
dlClient.routingService.addHost(name, dlServer.getAddress());
long txid = 101;
for (long i = 1; i <= 10; i++) {
long curTxId = txid++;
logger.debug("Write entry {} to stream {}.", curTxId, name);
dlClient.dlClient.write(name, ByteBuffer.wrap(("" + curTxId).getBytes())).get();
}
checkStream(1, 1, 1, name, dlServer.getAddress(), true, true);
dlClient.dlClient.delete(name).get();
checkStream(0, 0, 0, name, dlServer.getAddress(), false, false);
Thread.sleep(1000);
DistributedLogManager dlm101 = DLMTestUtil.createNewDLM(name, conf, getUri());
AsyncLogReader reader101 = FutureUtils.result(dlm101.openAsyncLogReader(DLSN.InitialDLSN));
try {
FutureUtils.result(reader101.readNext());
fail("Should fail with LogNotFoundException since the stream is deleted");
} catch (LogNotFoundException lnfe) {
// expected
}
FutureUtils.result(reader101.asyncClose());
dlm101.close();
txid = 201;
for (long i = 1; i <= 10; i++) {
long curTxId = txid++;
logger.debug("Write entry {} to stream {}.", curTxId, name);
DLSN dlsn = dlClient.dlClient.write(name, ByteBuffer.wrap(("" + curTxId).getBytes())).get();
}
Thread.sleep(1000);
DistributedLogManager dlm201 = DLMTestUtil.createNewDLM(name, conf, getUri());
LogReader reader201 = dlm201.getInputStream(1);
int numRead = 0;
int curTxId = 201;
LogRecord r = reader201.readNext(false);
while (null != r) {
int i = Integer.parseInt(new String(r.getPayload()));
assertEquals(curTxId++, i);
++numRead;
r = reader201.readNext(false);
}
assertEquals(10, numRead);
reader201.close();
dlm201.close();
}
use of com.twitter.distributedlog.AsyncLogReader in project distributedlog by twitter.
the class TestDistributedLogAdmin method testChangeSequenceNumber.
/**
* {@link https://issues.apache.org/jira/browse/DL-44}
*/
@DistributedLogAnnotations.FlakyTest
@Ignore
@Test(timeout = 60000)
@SuppressWarnings("deprecation")
public void testChangeSequenceNumber() throws Exception {
DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
confLocal.addConfiguration(conf);
confLocal.setLogSegmentSequenceNumberValidationEnabled(false);
URI uri = createDLMURI("/change-sequence-number");
zooKeeperClient.get().create(uri.getPath(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
com.twitter.distributedlog.DistributedLogManagerFactory factory = new com.twitter.distributedlog.DistributedLogManagerFactory(confLocal, uri);
String streamName = "change-sequence-number";
// create completed log segments
DistributedLogManager dlm = factory.createDistributedLogManagerWithSharedClients(streamName);
DLMTestUtil.generateCompletedLogSegments(dlm, confLocal, 4, 10);
DLMTestUtil.injectLogSegmentWithGivenLogSegmentSeqNo(dlm, confLocal, 5, 41, false, 10, true);
dlm.close();
// create a reader
DistributedLogManager readDLM = factory.createDistributedLogManagerWithSharedClients(streamName);
AsyncLogReader reader = readDLM.getAsyncLogReader(DLSN.InitialDLSN);
// read the records
long expectedTxId = 1L;
for (int i = 0; i < 4 * 10; i++) {
LogRecord record = Await.result(reader.readNext());
assertNotNull(record);
DLMTestUtil.verifyLogRecord(record);
assertEquals(expectedTxId, record.getTransactionId());
expectedTxId++;
}
dlm = factory.createDistributedLogManagerWithSharedClients(streamName);
DLMTestUtil.injectLogSegmentWithGivenLogSegmentSeqNo(dlm, confLocal, 3L, 5 * 10 + 1, true, 10, false);
// Wait for reader to be aware of new log segments
TimeUnit.SECONDS.sleep(2);
DLSN dlsn = readDLM.getLastDLSN();
assertTrue(dlsn.compareTo(new DLSN(5, Long.MIN_VALUE, Long.MIN_VALUE)) < 0);
assertTrue(dlsn.compareTo(new DLSN(4, -1, Long.MIN_VALUE)) > 0);
// there isn't records should be read
Future<LogRecordWithDLSN> readFuture = reader.readNext();
try {
Await.result(readFuture, Duration.fromMilliseconds(1000));
fail("Should fail reading next when there is a corrupted log segment");
} catch (TimeoutException te) {
// expected
}
// Dryrun
DistributedLogAdmin.fixInprogressSegmentWithLowerSequenceNumber(factory, new DryrunLogSegmentMetadataStoreUpdater(confLocal, getLogSegmentMetadataStore(factory)), streamName, false, false);
// Wait for reader to be aware of new log segments
TimeUnit.SECONDS.sleep(2);
dlsn = readDLM.getLastDLSN();
assertTrue(dlsn.compareTo(new DLSN(5, Long.MIN_VALUE, Long.MIN_VALUE)) < 0);
assertTrue(dlsn.compareTo(new DLSN(4, -1, Long.MIN_VALUE)) > 0);
// there isn't records should be read
try {
Await.result(readFuture, Duration.fromMilliseconds(1000));
fail("Should fail reading next when there is a corrupted log segment");
} catch (TimeoutException te) {
// expected
}
// Actual run
DistributedLogAdmin.fixInprogressSegmentWithLowerSequenceNumber(factory, LogSegmentMetadataStoreUpdater.createMetadataUpdater(confLocal, getLogSegmentMetadataStore(factory)), streamName, false, false);
// Wait for reader to be aware of new log segments
TimeUnit.SECONDS.sleep(2);
expectedTxId = 51L;
LogRecord record = Await.result(readFuture);
assertNotNull(record);
DLMTestUtil.verifyLogRecord(record);
assertEquals(expectedTxId, record.getTransactionId());
expectedTxId++;
for (int i = 1; i < 10; i++) {
record = Await.result(reader.readNext());
assertNotNull(record);
DLMTestUtil.verifyLogRecord(record);
assertEquals(expectedTxId, record.getTransactionId());
expectedTxId++;
}
dlsn = readDLM.getLastDLSN();
LOG.info("LastDLSN after fix inprogress segment : {}", dlsn);
assertTrue(dlsn.compareTo(new DLSN(7, Long.MIN_VALUE, Long.MIN_VALUE)) < 0);
assertTrue(dlsn.compareTo(new DLSN(6, -1, Long.MIN_VALUE)) > 0);
Utils.close(reader);
readDLM.close();
dlm.close();
factory.close();
}
use of com.twitter.distributedlog.AsyncLogReader in project distributedlog by twitter.
the class ReaderWorker method close.
@Override
public void close() throws IOException {
this.running = false;
for (AsyncLogReader reader : logReaders) {
if (null != reader) {
FutureUtils.result(reader.asyncClose());
}
}
for (DistributedLogManager dlm : dlms) {
if (null != dlm) {
dlm.close();
}
}
namespace.close();
SchedulerUtils.shutdownScheduler(executorService, 2, TimeUnit.MINUTES);
SchedulerUtils.shutdownScheduler(callbackExecutor, 2, TimeUnit.MINUTES);
if (this.dlc != null) {
this.dlc.close();
}
for (DLZkServerSet serverSet : serverSets) {
serverSet.close();
}
}
Aggregations