Как удалить старый контент в базе данных Firebase в реальном времени

Я использую базу данных Firebase в реальном времени, и сверхурочно в ней много устаревших данных, и я написал скрипт для удаления устаревшего контента.

Моя структура узлов выглядит примерно так:

store
  - {store_name}
    - products
      - {product_name}
        - data
          - {date} e.g. 01_Sep_2017
            - some_event

Масштаб данных

#Stores: ~110K
#Products: ~25

контекст

Я хочу очистить все данные за 30 месяцев. Я попробовал следующий подход:-

Для каждого магазина просмотрите все товары и для каждой даты удалите узел

Я запустил ~30 потоков / экземпляров сценария, и каждый поток отвечает за удаление определенной даты данных в этом месяце. Весь сценарий выполняется в течение ~12 часов, чтобы удалить данные за месяц с вышеуказанной структурой.

Я поместил ограничение / ограничение на количество ожидающих вызовов в каждом сценарии, и из журнала видно, что каждый сценарий достигает предела очень быстро, и скорость запуска вызова удаления намного быстрее, чем скорость удаления. Так что в этом случае firebase становится узким местом.,

Совершенно очевидно, что я запускаю сценарий очистки на стороне клиента и для достижения производительности сценарий должен выполняться близко к данным, чтобы сэкономить время на передачу данных по сети.

Вопросы

Q1. Как эффективно удалить старые узлы firebase?

Q2. Есть ли способ, которым мы можем установить TTL на каждом узле, чтобы он очищался автоматически?

Q3. Я подтвердил с нескольких узлов, что данные были удалены с узлов, но консоль Firebase не показывает уменьшение данных. Я также попытался сделать резервную копию данных, и она все еще показывает некоторые данные, которых не было, когда я проверял узлы вручную. Я хочу знать причину этого несоответствия.

Делает ли firebase мягкие удаления? Итак, когда мы берем резервные копии, данные на самом деле там, но не видны через firebase sdk или консоль firebase, потому что они могут обрабатывать мягкие удаления, а резервные копии - нет?

Q4. В течение всего времени работы моего скрипта у меня постоянно увеличивается пропускная способность. С помощью приведенного ниже сценария я запускаю только вызовы на удаление и не читаю никаких данных, но вижу согласованность с чтением из базы данных. Посмотрите на этот скриншот?

Это из-за обратных вызовов удаленных узлов?

Код

var stores = [];
var storeIndex = 0;
var products = [];
var productIndex = -1;

const month = 'Oct';
const year = 2017;

if (process.argv.length < 3) {
  console.log("Usage: node purge.js $beginDate $endDate i.e. node purge 1 2 | Exiting..");
  process.exit();
}

var beginDate = process.argv[2];
var endDate = process.argv[3];

var numPendingCalls = 0;

const maxPendingCalls = 500;

/**
 * Url Pattern: /store/{domain}/products/{product_name}/data/{date}
 * date Pattern: 01_Jan_2017
 */
function deleteNode() {
  var storeName = stores[storeIndex],
    productName = products[productIndex],
    date = (beginDate < 10 ? '0' + beginDate : beginDate) + '_' + month + '_' + year;

  numPendingCalls++;

  db.ref('store')
    .child(storeName)
    .child('products')
    .child(productName)
    .child('data')
    .child(date)
    .remove(function() {
      numPendingCalls--;
    });
}

function deleteData() {
  productIndex++;

  // When all products for a particular store are complete, start for the new store for given date
  if (productIndex === products.length) {
    if (storeIndex % 1000 === 0) {
      console.log('Script: ' + beginDate, 'PendingCalls: ' + numPendingCalls, 'StoreIndex: ' + storeIndex, 'Store: ' + stores[storeIndex], 'Time: ' + (new Date()).toString());
    }

    productIndex = 0;
    storeIndex++;
  }

  // When all stores have been completed, start deleting for next date
  if (storeIndex === stores.length) {
    console.log('Script: ' + beginDate, 'Successfully deleted data for date: ' + beginDate + '_' + month + '_' + year + '. Time: ' + (new Date()).toString());
    beginDate++;
    storeIndex = 0;
  }

  // When you have reached endDate, all data has been deleted call the original callback
  if (beginDate > endDate) {
    console.log('Script: ' + beginDate, 'Deletion script finished successfully at: ' + (new Date()).toString());
    process.exit();
    return;
  }

  deleteNode();
}

function init() {
  console.log('Script: ' + beginDate, 'Deletion script started at: ' + (new Date()).toString());

  getStoreNames(function() {
    getProductNames(function() {
      setInterval(function() {
        if (numPendingCalls < maxPendingCalls) {
          deleteData();
        }
      }, 0);
    });
  });
}

PS: это не та структура, которая у меня есть, но она очень похожа на ту, что у нас есть (я изменил имена узлов и попытался сделать пример реалистичным)

1 ответ

  1. Будет ли удаление выполняться более эффективно, зависит от того, как вы сейчас делаете их. Поскольку вы не поделились минимальным кодом, который воспроизводит ваше текущее поведение, трудно сказать, как его улучшить.

  2. В документах отсутствует поддержка времени жизни. Обычно разработчики выполняют очистку в административной программе / скрипте, которые запускаются периодически. Чем чаще вы запускаете скрипт очистки, тем меньше работы он должен выполнять и, следовательно, тем быстрее он будет.

    Также см:

  3. Firebase фактически удаляет данные с диска, когда вы указываете это. Через API нет способа получить его, так как он действительно исчез. Но если у вас есть резервная копия с предыдущего дня, данные, конечно же, будут там.

Другие вопросы по тегам