我正在使用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:这不是我所拥有的确切结构,但它与我们的结构非常相似(我已经更改了节点名称并试图使示例成为一个现实的例子)
答案 0 :(得分:2)
删除是否可以更有效地完成取决于您现在的操作方式。由于您没有分享minimal code that reproduces your current behavior,因此很难说如何改进它。
不支持文档上的生存时间属性。通常,开发人员会在定期运行的管理程序/脚本中进行清理。运行清理脚本的频率越高,它所做的工作就越少,因此它的速度就越快。
另见:
Firebase实际上会在您告知时从磁盘中删除数据。没有办法通过API来检索它,因为它真的消失了。但是如果你有前一天的备份,数据当然仍然存在。