4

Android アプリ用に Google App Engine を介してオンライン リーダーボードを実装しました。しかし、2 時間後、「データストアの読み取り操作」でクォータの 100% に達しました。読み取り操作を減らすためにコードを変更するのを手伝ってくれる人はいますか?
これが私のコードです:

public class The_Big_Bang_Theory_Quiz_HighscoreserverServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String game = req.getParameter("game");
    String name = req.getParameter("name");
    String pointsStr = req.getParameter("points");
    String behaviorStr = req.getParameter("behavior");
    int behavior = 0; // 0 = upload, 1 = download
    if (behaviorStr != null) {
        try {
            behavior = Integer.parseInt(behaviorStr);
        } catch (NumberFormatException e) {
            behavior = 0;
        }
    }
    if (behavior == 0) {
        int points = 0;
        if (pointsStr != null) {
            try {
                points = Integer.parseInt(pointsStr);
            } catch (NumberFormatException e) {
                points = 0;
            }
        }
        if (points > 0 && name != null) {
            addHighscore(game, name, points);
        }
    } else {
        String maxStr = req.getParameter("max");
        int max = 1000;
        if (maxStr != null) {
            try {
                max = Integer.parseInt(maxStr);
            } catch (NumberFormatException e) {
                max = 1000;
            }
        }
        returnHighscores(resp, game, max);
    }
}

private void returnHighscores(HttpServletResponse resp, String game, int max) {
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    Key gameKey = KeyFactory.createKey("game", game);
    Query query = new Query("highscore", gameKey);
    query.addSort("points", Query.SortDirection.DESCENDING);
    List<Entity> highscores = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(max));
    for(Entity e : highscores) {
        try {
            resp.getWriter().println(e.getProperty("name") + ";" +e.getProperty("points"));
        } catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}

private void addHighscore(String game, String name, int points) {
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    Key gameKey = KeyFactory.createKey("game", game);
    Entity highscore = new Entity("highscore", gameKey);
    highscore.setProperty("name", name);
    highscore.setProperty("points", points);
    datastore.put(highscore);
}
}

について何かを読みましたBlobStore。それはより良い方法ですか?

4

3 に答える 3

3

読み取り操作によって返されるすべてのエンティティには、読み取り操作が必要です。無料クォータで 50,000 回の読み取り操作があります。

ハイスコ​​アを取得するたびに、最大 1000 のハイスコアが表示されるようです。スコアが 1000 を超える場合、スコアを 50 回引くと限界に達します。

ユーザーは上位 1000 のスコアを本当に気にしていますか? それはあなたの決断ですが、私はそれを非常に疑っています。上位 10 件のハイスコアを取得した場合、クォータを使い果たす前に 100 倍のクエリを実行できる可能性があります。

お金を節約するための次のステップは、射影クエリを使用して、読み取り操作ではなく小さな操作を使用することです。

于 2012-10-17T19:45:10.110 に答える
2

私は同じ問題を抱えていました.GEAのキャッシュメカニズムを使用して問題を解決しました. 基本的に、キャッシュは分散 HasMap です

いくつかのコード: マップを作成します:

try {
            cache = CacheManager.getInstance().getCacheFactory().createCache(
                    new ConcurrentHashMap<String, Category>());
        } catch (CacheException e) {
            Logger
                    .getLogger(TipsDAO.class.getName())
                    .severe(
                            "unable to cretate cache using an internal ConcurrentHashMap");
            cache = new ConcurrentHashMap<String, Category>();
        }

読み取りポップごとに、最初にマップをチェックします。見つかった場合は戻ります。見つからない場合は、DB から読み取り、マップに配置してから戻ります。

if (cache.containsKey(cat)) {
            return (Category) cache.get(cat);
        }
        try {
            Query query = entityManager
                    .createQuery("SELECT FROM Category WHERE name = ?1");
            query.setParameter(1, cat);
            Category temp = (Category) query.getSingleResult();
            cache.put(cat, temp);
            return temp;
        } catch (Exception e) {
            LOG.severe(e.getMessage());
            return null;
        }

DBへの書き込み操作ごとに、マップにも書き込みます

cache.put(cat.getName(), cat);
于 2012-10-17T17:06:10.200 に答える
0

参考までに、GAEのAppStatsオプションを有効にすると、各データベーストランザクションの正確な時間とコストを示すクールなレポートを取得できます。

これは、リソースの使用状況をデバッグするときに非常に役立ちます。

ここに画像の説明を入力してください

于 2012-10-17T20:52:55.120 に答える