Search in sources :

Example 1 with OfflineSegmentZKMetadata

use of com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata in project pinot by linkedin.

the class SegmentFetcherAndLoader method addOrReplaceOfflineSegment.

public void addOrReplaceOfflineSegment(String tableName, String segmentId, boolean retryOnFailure) {
    OfflineSegmentZKMetadata offlineSegmentZKMetadata = ZKMetadataProvider.getOfflineSegmentZKMetadata(_propertyStore, tableName, segmentId);
    // Try to load table schema from Helix property store.
    // This schema is used for adding default values for newly added columns.
    Schema schema = null;
    try {
        schema = getSchema(tableName);
    } catch (Exception e) {
        LOGGER.error("Caught exception while trying to load schema for table: {}", tableName, e);
    }
    LOGGER.info("Adding or replacing segment {} for table {}, metadata {}", segmentId, tableName, offlineSegmentZKMetadata);
    try {
        SegmentMetadata segmentMetadataForCheck = new SegmentMetadataImpl(offlineSegmentZKMetadata);
        // We lock the segment in order to get its metadata, and then release the lock, so it is possible
        // that the segment is dropped after we get its metadata.
        SegmentMetadata localSegmentMetadata = _dataManager.getSegmentMetadata(tableName, segmentId);
        if (localSegmentMetadata == null) {
            LOGGER.info("Segment {} of table {} is not loaded in memory, checking disk", segmentId, tableName);
            final String localSegmentDir = getSegmentLocalDirectory(tableName, segmentId);
            if (new File(localSegmentDir).exists()) {
                LOGGER.info("Segment {} of table {} found on disk, attempting to load it", segmentId, tableName);
                try {
                    localSegmentMetadata = _metadataLoader.loadIndexSegmentMetadataFromDir(localSegmentDir);
                    LOGGER.info("Found segment {} of table {} with crc {} on disk", segmentId, tableName, localSegmentMetadata.getCrc());
                } catch (Exception e) {
                    // The localSegmentDir should help us get the table name,
                    LOGGER.error("Failed to load segment metadata from {}. Deleting it.", localSegmentDir, e);
                    FileUtils.deleteQuietly(new File(localSegmentDir));
                    localSegmentMetadata = null;
                }
                try {
                    if (!isNewSegmentMetadata(localSegmentMetadata, segmentMetadataForCheck, segmentId, tableName)) {
                        LOGGER.info("Segment metadata same as before, loading {} of table {} (crc {}) from disk", segmentId, tableName, localSegmentMetadata.getCrc());
                        AbstractTableConfig tableConfig = ZKMetadataProvider.getOfflineTableConfig(_propertyStore, tableName);
                        _dataManager.addSegment(localSegmentMetadata, tableConfig, schema);
                        // TODO Update zk metadata with CRC for this instance
                        return;
                    }
                } catch (V3RemoveIndexException e) {
                    LOGGER.info("Unable to remove local index from V3 format segment: {}, table: {}, try to reload it from controller.", segmentId, tableName, e);
                    FileUtils.deleteQuietly(new File(localSegmentDir));
                    localSegmentMetadata = null;
                } catch (Exception e) {
                    LOGGER.error("Failed to load {} of table {} from local, will try to reload it from controller!", segmentId, tableName, e);
                    FileUtils.deleteQuietly(new File(localSegmentDir));
                    localSegmentMetadata = null;
                }
            }
        }
        // that we have is different from that in zookeeper.
        if (isNewSegmentMetadata(localSegmentMetadata, segmentMetadataForCheck, segmentId, tableName)) {
            if (localSegmentMetadata == null) {
                LOGGER.info("Loading new segment {} of table {} from controller", segmentId, tableName);
            } else {
                LOGGER.info("Trying to refresh segment {} of table {} with new data.", segmentId, tableName);
            }
            int retryCount;
            int maxRetryCount = 1;
            if (retryOnFailure) {
                maxRetryCount = _segmentLoadMaxRetryCount;
            }
            for (retryCount = 0; retryCount < maxRetryCount; ++retryCount) {
                long attemptStartTime = System.currentTimeMillis();
                try {
                    AbstractTableConfig tableConfig = ZKMetadataProvider.getOfflineTableConfig(_propertyStore, tableName);
                    final String uri = offlineSegmentZKMetadata.getDownloadUrl();
                    final String localSegmentDir = downloadSegmentToLocal(uri, tableName, segmentId);
                    final SegmentMetadata segmentMetadata = _metadataLoader.loadIndexSegmentMetadataFromDir(localSegmentDir);
                    _dataManager.addSegment(segmentMetadata, tableConfig, schema);
                    LOGGER.info("Downloaded segment {} of table {} crc {} from controller", segmentId, tableName, segmentMetadata.getCrc());
                    // Successfully loaded the segment, break out of the retry loop
                    break;
                } catch (Exception e) {
                    long attemptDurationMillis = System.currentTimeMillis() - attemptStartTime;
                    LOGGER.warn("Caught exception while loading segment " + segmentId + "(table " + tableName + "), attempt " + (retryCount + 1) + " of " + maxRetryCount, e);
                    // Do we need to wait for the next retry attempt?
                    if (retryCount < maxRetryCount - 1) {
                        // Exponentially back off, wait for (minDuration + attemptDurationMillis) *
                        // 1.0..(2^retryCount)+1.0
                        double maxRetryDurationMultiplier = Math.pow(2.0, (retryCount + 1));
                        double retryDurationMultiplier = Math.random() * maxRetryDurationMultiplier + 1.0;
                        long waitTime = (long) ((_segmentLoadMinRetryDelayMs + attemptDurationMillis) * retryDurationMultiplier);
                        LOGGER.warn("Waiting for " + TimeUnit.MILLISECONDS.toSeconds(waitTime) + " seconds to retry(" + segmentId + " of table " + tableName);
                        long waitEndTime = System.currentTimeMillis() + waitTime;
                        while (System.currentTimeMillis() < waitEndTime) {
                            try {
                                Thread.sleep(Math.max(System.currentTimeMillis() - waitEndTime, 1L));
                            } catch (InterruptedException ie) {
                            // Ignore spurious wakeup
                            }
                        }
                    }
                }
            }
            if (_segmentLoadMaxRetryCount <= retryCount) {
                String msg = "Failed to download segment " + segmentId + " (table " + tableName + " after " + retryCount + " retries";
                LOGGER.error(msg);
                throw new RuntimeException(msg);
            }
        } else {
            LOGGER.info("Got already loaded segment {} of table {} crc {} again, will do nothing.", segmentId, tableName, localSegmentMetadata.getCrc());
        }
    } catch (final Exception e) {
        LOGGER.error("Cannot load segment : " + segmentId + " for table " + tableName, e);
        Utils.rethrowException(e);
        throw new AssertionError("Should not reach this");
    }
}
Also used : V3RemoveIndexException(com.linkedin.pinot.core.segment.index.loader.V3RemoveIndexException) OfflineSegmentZKMetadata(com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata) Schema(com.linkedin.pinot.common.data.Schema) IOException(java.io.IOException) V3RemoveIndexException(com.linkedin.pinot.core.segment.index.loader.V3RemoveIndexException) SegmentMetadata(com.linkedin.pinot.common.segment.SegmentMetadata) SegmentMetadataImpl(com.linkedin.pinot.core.segment.index.SegmentMetadataImpl) AbstractTableConfig(com.linkedin.pinot.common.config.AbstractTableConfig) File(java.io.File)

Example 2 with OfflineSegmentZKMetadata

use of com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata in project pinot by linkedin.

the class TimeBoundaryServiceTest method constructExternalView.

private ExternalView constructExternalView(String tableName) {
    ExternalView externalView = new ExternalView(tableName);
    List<OfflineSegmentZKMetadata> offlineResourceZKMetadataListForResource = ZKMetadataProvider.getOfflineSegmentZKMetadataListForTable(_propertyStore, tableName);
    for (OfflineSegmentZKMetadata segmentMetadata : offlineResourceZKMetadataListForResource) {
        externalView.setState(segmentMetadata.getSegmentName(), "localhost", "ONLINE");
    }
    return externalView;
}
Also used : ExternalView(org.apache.helix.model.ExternalView) OfflineSegmentZKMetadata(com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata)

Example 3 with OfflineSegmentZKMetadata

use of com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata in project pinot by linkedin.

the class TimeBoundaryServiceTest method addingSegmentsToPropertyStore.

private void addingSegmentsToPropertyStore(int numSegments, ZkHelixPropertyStore<ZNRecord> propertyStore, String tableName) {
    for (int i = 0; i < numSegments; ++i) {
        OfflineSegmentZKMetadata offlineSegmentZKMetadata = new OfflineSegmentZKMetadata();
        offlineSegmentZKMetadata.setSegmentName(tableName + "_" + System.currentTimeMillis() + "_" + i);
        offlineSegmentZKMetadata.setTimeUnit(TimeUnit.DAYS);
        offlineSegmentZKMetadata.setEndTime(i);
        offlineSegmentZKMetadata.setCrc(-1);
        offlineSegmentZKMetadata.setCreationTime(-1);
        offlineSegmentZKMetadata.setStartTime(i - 1);
        offlineSegmentZKMetadata.setIndexVersion("0");
        offlineSegmentZKMetadata.setPushTime(i + 5);
        offlineSegmentZKMetadata.setTableName(tableName);
        offlineSegmentZKMetadata.setSegmentType(SegmentType.OFFLINE);
        ZKMetadataProvider.setOfflineSegmentZKMetadata(_propertyStore, offlineSegmentZKMetadata);
    }
}
Also used : OfflineSegmentZKMetadata(com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata)

Example 4 with OfflineSegmentZKMetadata

use of com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata in project pinot by linkedin.

the class ZKMetadataProvider method getOfflineSegmentZKMetadataListForTable.

public static List<OfflineSegmentZKMetadata> getOfflineSegmentZKMetadataListForTable(ZkHelixPropertyStore<ZNRecord> propertyStore, String tableName) {
    List<OfflineSegmentZKMetadata> resultList = new ArrayList<OfflineSegmentZKMetadata>();
    if (propertyStore == null) {
        return resultList;
    }
    String offlineTableName = TableNameBuilder.OFFLINE_TABLE_NAME_BUILDER.forTable(tableName);
    if (propertyStore.exists(constructPropertyStorePathForResource(offlineTableName), AccessOption.PERSISTENT)) {
        List<ZNRecord> znRecordList = propertyStore.getChildren(constructPropertyStorePathForResource(offlineTableName), null, AccessOption.PERSISTENT);
        if (znRecordList != null) {
            for (ZNRecord record : znRecordList) {
                resultList.add(new OfflineSegmentZKMetadata(record));
            }
        }
    }
    return resultList;
}
Also used : OfflineSegmentZKMetadata(com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata) ArrayList(java.util.ArrayList) ZNRecord(org.apache.helix.ZNRecord)

Example 5 with OfflineSegmentZKMetadata

use of com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata in project pinot by linkedin.

the class SegmentZKMetadataTest method getTestOfflineSegmentMetadata.

private OfflineSegmentZKMetadata getTestOfflineSegmentMetadata() {
    OfflineSegmentZKMetadata offlineSegmentMetadata = new OfflineSegmentZKMetadata();
    offlineSegmentMetadata.setSegmentName("testTable_O_3000_4000");
    offlineSegmentMetadata.setTableName("testTable");
    offlineSegmentMetadata.setSegmentType(SegmentType.OFFLINE);
    offlineSegmentMetadata.setIndexVersion("v1");
    offlineSegmentMetadata.setStartTime(1000);
    offlineSegmentMetadata.setEndTime(2000);
    offlineSegmentMetadata.setTimeUnit(TimeUnit.HOURS);
    offlineSegmentMetadata.setTotalRawDocs(50000);
    offlineSegmentMetadata.setCrc(54321);
    offlineSegmentMetadata.setCreationTime(1000);
    offlineSegmentMetadata.setDownloadUrl("http://localhost:8000/testTable_O_3000_4000");
    offlineSegmentMetadata.setPushTime(4000);
    offlineSegmentMetadata.setRefreshTime(8000);
    return offlineSegmentMetadata;
}
Also used : OfflineSegmentZKMetadata(com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata)

Aggregations

OfflineSegmentZKMetadata (com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata)19 ArrayList (java.util.ArrayList)5 ZNRecord (org.apache.helix.ZNRecord)5 SegmentMetadata (com.linkedin.pinot.common.segment.SegmentMetadata)4 SegmentMetadataImpl (com.linkedin.pinot.core.segment.index.SegmentMetadataImpl)4 Test (org.testng.annotations.Test)4 TimeUnit (java.util.concurrent.TimeUnit)3 ExternalView (org.apache.helix.model.ExternalView)3 AbstractTableConfig (com.linkedin.pinot.common.config.AbstractTableConfig)2 RealtimeSegmentZKMetadata (com.linkedin.pinot.common.metadata.segment.RealtimeSegmentZKMetadata)2 SegmentZKMetadata (com.linkedin.pinot.common.metadata.segment.SegmentZKMetadata)2 TableType (com.linkedin.pinot.common.utils.CommonConstants.Helix.TableType)2 IOException (java.io.IOException)2 IdealState (org.apache.helix.model.IdealState)2 SegmentsValidationAndRetentionConfig (com.linkedin.pinot.common.config.SegmentsValidationAndRetentionConfig)1 Schema (com.linkedin.pinot.common.data.Schema)1 BrokerMetrics (com.linkedin.pinot.common.metrics.BrokerMetrics)1 V3RemoveIndexException (com.linkedin.pinot.core.segment.index.loader.V3RemoveIndexException)1 MetricsRegistry (com.yammer.metrics.core.MetricsRegistry)1 File (java.io.File)1