Firebase 数据库带宽计算

Firebase Database Bandwidth Calculation

我在 2 周前发布了一个名为 MyPetrol 的 android 应用程序,并在三天内在马来西亚吸引了大约 90,000 名用户。之后,由于巨大的 Firebase 数据库带宽消耗(3 天 117GB),我关闭了该应用程序。我是一个没有IT相关背景的自学成才的爱好者,所以我真的为此感到困扰。希望有人能帮忙。

该应用程序是一款汽油价格众包应用程序。用户可以输入特定加油站的汽油价格,其他同意该价格的用户可以 "like" 输入。价格更新后,"like" 计数将重置。

打开应用程序后,它会查询附近加油站(最多 20 个加油站)的 Google Places API Web 服务。这样,它将听众挂钩到 Firebase 数据库中的电台数据。每个站的数据结构如下所示。

prices{
    ChIJpXJ4phI4zDERJqFTBzawpXk={
        placeID='ChIJpXJ4phI4zDERJqFTBzawpXk',
        company=500,
        lat=3.2095573,
        lng=101.7185698,
        name='Shell Malaysia (Iznora Enterprise)',
        firebaseID='xxx',
        userName='xxx',
        time=1491833181946,
        ron95=2.0,
        ron97=1.7,
        diesel=2.0,
        isValid=true
    }
}

为了记录点赞数,有一段数据为

likes{
    ChIJpXJ4phI4zDERJqFTBzawpXk={
        firebaseID1=true,
        firebaseID2=true,
        firebaseID3=true
    }
}

我读到 我们可以使用 (Firebase.getDefaultConfig().setLogLevel(Level.DEBUG)) 进行流量检查,但我在 logcat 中没有看到有关上传和下载带宽的任何信息。只有这样...

04-10 22:39:19.250 3015-3192/? D/RepoOperation: onDataUpdate: /prices/ChIJpXJ4phI4zDERJqFTBzawpXk
04-10 22:39:19.250 3015-3192/? D/RepoOperation: onDataUpdate: /prices/ChIJpXJ4phI4zDERJqFTBzawpXk {time=1491833181946, firebaseID=xxx, valid=true, diesel=2, ron97=1.7000000476837158, ron95=2, placeID=ChIJpXJ4phI4zDERJqFTBzawpXk, name=Shell Malaysia (Iznora Enterprise), userName=xxx, company=500, lat=3.2095573, lng=101.7185698}
04-10 22:39:19.268 3015-3015/? D/EventRaiser: Raising /prices/ChIJpXJ4phI4zDERJqFTBzawpXk: VALUE: {time=1491833181946, firebaseID=xxx, valid=true, diesel=2, ron97=1.7000000476837158, ron95=2, placeID=ChIJpXJ4phI4zDERJqFTBzawpXk, name=Shell Malaysia (Iznora Enterprise), userName=xxx, company=500, lat=3.2095573, lng=101.7185698}
04-10 22:39:19.273 3015-3015/? D/EventRaiser: Raising /likes/ChIJpXJ4phI4zDERJqFTBzawpXk: VALUE: null

最后,我使用Android Device Monitor 来检查每个动作的流量。以下是仅 Firebase 的平均结果。 Google 不包括地图和其他 http 查询。

+----------------------------+-----------+-----------+-----------------------------------------+
|           Action           | Rx(bytes) | Tx(bytes) |                  Notes                  |
+----------------------------+-----------+-----------+-----------------------------------------+
| onPause                    |      2942 |      4680 | detach all listeners                    |
| onResume                   |     10143 |      5204 | reattach all listeners for 15 stations  |
| click "like" by self       |       620 |       535 | write action + download /likes/placeID  |
| update price by self       |      1642 |      1783 | write action + download /places/placeID |
| click "like" by other user |       382 |       112 | download /likes/placeID                 |
| update price by other user |       423 |       104 | download /places/placeID                |
+----------------------------+-----------+-----------+-----------------------------------------+

就在我关闭应用程序之前,数据库中有 5.7MB 的数据。我可以保证我直接为每个电台连接了监听器 /prices/placeID,所以我没有检索整个 "Station" 数据,而是只检索了那个特定电台的数据。同样对于 "like"。监听器也在暂停时分离。

我没有任何可用的用户操作日志,因此我很难追溯发生了什么。但是,每当用户打开应用程序时,必须查询 Google 地方 API,所以我知道在这 3 天内,我有 245k 个查询。因此对于每个用户会话。

117GB / 245k session = ~480kB/session

这似乎很大。我对带宽等的经验为零,所以我可能是错的。即使我假设所有用户都做了下面极不可能的操作,我仍然无法填满带宽。

+----------------------------+-----------+-------+--------------+----------------------------------------------------------+
|           Action           | Rx(bytes) | Times | Total(bytes) |                          Notes                           |
+----------------------------+-----------+-------+--------------+----------------------------------------------------------+
| onPause                    |      2942 |    10 |        29420 | Pause and resume 10 times, this does not update the map. |
| onResume                   |     10143 |    10 |       101430 |                                                          |
| click "like" by self       |       620 |    15 |         9300 | Click like on all 15 stations                            |
| update price by self       |      1642 |    15 |        24630 | Update price on all 15 stations                          |
| click "like" by other user |       382 |   100 |        38200 | 100 other users clicked per session                      |
| update price by other user |       423 |   100 |        42300 | 100 other users updated the price per session            |
| Total                      |           |       |       245280 |                                                          |
+----------------------------+-----------+-------+--------------+----------------------------------------------------------+

对于普通用户,我预计每个会话最多只有 50kB 左右,因此 Firebase 似乎消耗了 10 倍的带宽。所以我的问题:

  1. 我是否正确计算了每个会话的带宽?
  2. 使用Android Device Monitor 确定的流量是否正确?我错过了什么吗?有没有更好的检查方法?
  3. Firebase 如何计算带宽?它也包括上传吗?有没有隐藏带宽?

抱歉这么久 post。感谢有人可以提供帮助。 谢谢。

我发现了这个错误。它与上述问题完全无关,但我在这里记录它以帮助其他用户。所以首先,回答我自己的问题。

问题 (1) - 是的。每个会话 480kB 的估计应该是相当准确的。

问题 (2) 和 (3) - Firebase 消耗的带宽应低于 Android Device Monitor 记录的带宽。我联系了支持团队并得到了以下回复。

For your bandwidth questions, the GB downloaded only measures the amount of data being sent by the Firebase database to your client app. This means data retrieval to your application.You might want to check the following links for more information:

因此,扣除一些开销,实际带宽应该略低。

所以,回到高带宽消耗。它与 Firebase 数据库的 Query 有关。当新用户注册时,我在下面有一个查询。

Query priceQuery = getPricesRef().orderByChild("firebaseID").equalTo(myFirebaseID);

这是我噩梦的开始,因为我没有为该数据库设置 .indexOn。阅读官方 Firebase 文档 here。关于 Query 的文档很差。它只说没有索引性能会很差,但没有提到带宽:

根据上述陈述,我的假设是如果没有.indexOn,对 Firebase 的查询可能需要更长的时间才能回复,因为 Firebase 服务器可能需要更长的时间来提供搜索结果。

但是,正如 中的回答,首先从 Firebase 下载整个数据库,然后在客户端进行排序和查询! 我想这就是他们的意思实时客户端库可以在不指定索引的情况下执行临时查询

随着我的数据库的增长,每个注册用户开始通过下载整个 prices 数据库来消耗更高的带宽。到最后,每个用户仅注册就消耗约 800kB。 所以请务必始终使用 .indexOn