All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ray.streaming.state.strategy.DualStateStoreManager Maven / Gradle / Ivy

There is a newer version: 1.10.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.ray.streaming.state.strategy;

import com.google.common.primitives.Longs;
import io.ray.streaming.state.StateException;
import io.ray.streaming.state.StorageRecord;
import io.ray.streaming.state.store.KeyValueStore;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** This class define the checkpoint store strategy, which saves two-version data once. */
public class DualStateStoreManager extends AbstractStateStoreManager {

  private static final Logger LOG = LoggerFactory.getLogger(DualStateStoreManager.class);

  public DualStateStoreManager(KeyValueStore> backStore) {
    super(backStore);
  }

  @Override
  public void finish(long checkpointId) {
    LOG.info("do finish checkpointId:{}", checkpointId);
    Map cpStore = new HashMap<>();
    for (Entry> entry : frontStore.entrySet()) {
      String key = entry.getKey();
      StorageRecord value = entry.getValue();
      cpStore.put(key, toBytes(value));
    }
    middleStore.put(checkpointId, cpStore);
    frontStore.clear();
  }

  @Override
  public void commit(long checkpointId) {
    try {
      LOG.info("do commit checkpointId:{}", checkpointId);
      Map cpStore = middleStore.get(checkpointId);
      if (cpStore == null) {
        throw new StateException("why cp store is null");
      }
      for (Entry entry : cpStore.entrySet()) {
        String key = entry.getKey();
        byte[] value = entry.getValue();

        /**
         * 2 is specific key in kv store and indicates that new value should be stored with this key
         * after overwriting old value in key 1. i.e.
         *
         * 

-2 -1 1 2 k1 6 5 a b k2 9 7 d e * *

k1's value for checkpoint 5 is a, and b for checkpoint 6. */ Map remoteData = super.kvStore.get(key); if (remoteData == null || remoteData.size() == 0) { remoteData = new HashMap<>(); remoteData.put(2L, value); remoteData.put(-2L, Longs.toByteArray(checkpointId)); } else { long oldBatchId = Longs.fromByteArray(remoteData.get(-2L)); if (oldBatchId < checkpointId) { // move the old data remoteData.put(1L, remoteData.get(2L)); remoteData.put(-1L, remoteData.get(-2L)); } // put the new data here remoteData.put(2L, value); remoteData.put(-2L, Longs.toByteArray(checkpointId)); } super.kvStore.put(key, remoteData); } super.kvStore.flush(); } catch (Exception e) { LOG.error(e.getMessage(), e); throw new StateException(e); } } @Override public void rollBack(long checkpointId) { LOG.info("do rollBack checkpointId:{}", checkpointId); this.frontStore.clear(); this.middleStore.clear(); this.kvStore.clearCache(); } @Override public V get(long checkpointId, String key) { // get from current cp cache StorageRecord storageRecord = frontStore.get(key); if (storageRecord != null) { return storageRecord.getValue(); } // get from not commit cp info List checkpointIds = new ArrayList<>(middleStore.keySet()); Collections.sort(checkpointIds); for (int i = checkpointIds.size() - 1; i >= 0; i--) { Map cpStore = middleStore.get(checkpointIds.get(i)); if (cpStore != null) { if (cpStore.containsKey(key)) { byte[] cpData = cpStore.get(key); storageRecord = toStorageRecord(cpData); return storageRecord.getValue(); } } } try { Map remoteData = super.kvStore.get(key); if (remoteData != null) { for (Entry entry : remoteData.entrySet()) { if (entry.getKey() > 0) { StorageRecord tmp = toStorageRecord(entry.getValue()); if (tmp.getCheckpointId() < checkpointId) { if (storageRecord == null) { storageRecord = tmp; } else if (storageRecord.getCheckpointId() < tmp.getCheckpointId()) { storageRecord = tmp; } } } } if (storageRecord != null) { return storageRecord.getValue(); } } } catch (Exception e) { LOG.error("get checkpointId:" + checkpointId + " key:" + key, e); throw new StateException(e); } return null; } @Override public void ackCommit(long checkpointId) { LOG.info("do ackCommit checkpointId:{}", checkpointId); middleStore.remove(checkpointId); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy