【问题标题】:How to purge old content in firebase realtime database如何清除firebase实时数据库中的旧内容
【发布时间】:2017-11-22 15:03:40
【问题描述】:

我正在使用 Firebase 实时数据库,并且超时后其中有很多过时的数据,我编写了一个脚本来删除过时的内容。

我的节点结构如下所示:

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

数据规模

#Stores: ~110K
#Products: ~25

上下文

我想清理 30 个月前的所有数据。我尝试了以下方法:-

对于每个商店,遍历所有产品,对于每个日期,删除节点

我运行了大约 30 个线程/脚本实例,每个线程负责删除该月中特定日期的数据。整个脚本运行约 12 小时以删除具有上述结构的一个月数据。

我已经对每个脚本中的挂起调用数量设置了限制/上限,从日志中可以明显看出,每个脚本都很快达到了限制,并且触发删除调用的速度比删除速度快得多所以这里是 firebase成为瓶颈。

很明显,我在客户端运行清除脚本并获得性能脚本应该在靠近数据的地方执行以节省网络往返时间。

问题

第一季度。如何有效地删除 firebase 旧节点?

第二季度。有没有办法在每个节点上设置一个 TTL 以便它自动清理?

第三季度。我已从多个节点确认数据已从节点中删除,但 firebase 控制台未显示数据减少。我还尝试备份数据,它仍然显示一些当我手动检查节点时不存在的数据。我想知道这种不一致背后的原因。

firebase 是否进行软删除所以当我们进行备份时,数据实际上存在但通过 firebase sdk 或 firebase 控制台不可见,因为它们可以处理软删除但备份不能?

第四季度。在我的脚本运行的整个期间,我的带宽部分持续上升。使用下面的脚本,我只触发删除调用,我没有读取任何数据,但我看到与数据库读取的一致性。看看这张截图?

这是因为删除节点的回调吗?

代码

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:这不是我所拥有的确切结构,但它与我们所拥有的非常相似(我已更改节点名称并试图使示例成为现实示例)

【问题讨论】:

    标签: performance firebase firebase-realtime-database purge


    【解决方案1】:
    1. 是否可以更有效地完成删除操作取决于您现在的操作方式。由于您没有分享minimal code that reproduces your current behavior,所以很难说如何改进它。

    2. 不支持文档的生存时间属性。通常,开发人员在定期运行的管理程序/脚本中进行清理。运行清理脚本的频率越高,它要做的工作就越少,因此它会越快。

      另见:

    3. Firebase 实际上会在您告诉它时从磁盘中删除数据。无法通过 API 检索它,因为它真的消失了。但是,如果您有前一天的备份,那么数据当然仍然存在。

    【讨论】:

    • 谢谢@Frank!我想分享最少的代码,但删除实际节点和重命名变量太费力了。反正我现在已经做到了。其次! Firebase 控制台上的数据库大小多久刷新一次?
    • 你能看看我更新的问题,我还添加了一个问题。
    • 这里的问题太多了。我知道对你来说这可能只是一个问题,但 Stack Overflow 是一个非常低效的交互式调试器。如果您想知道您当前的脚本是否导致带宽问题,请单独运行它(可能在单独的项目中)并使用database profiler 来衡量其影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 2016-09-20
    • 2018-12-07
    • 1970-01-01
    相关资源
    最近更新 更多