我已经通过Google App Engine为我的Android应用实施了在线排行榜。但在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
的内容。这是一种更好的方法吗?
答案 0 :(得分:3)
读操作返回的每个实体都需要读操作。在免费配额下你有50k的阅读操作。
每当你获得高分时,你似乎可以获得高分1000分。如果你有&gt; 1000分,然后拉50分将达到你的极限。
您的用户真的关心前1000名吗?这是你的决定,但我对此表示高度怀疑。如果你取得了前十名的高分,那么在你的配额用完之前,你的查询可能会增加100倍。
省钱的下一步是使用投影查询,以便您的读取使用小操作而不是读取操作。
答案 1 :(得分:2)
我遇到了同样的问题,我使用了GEA的缓存机制来解决问题。 基本上,Cache是分布式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>();
}
对于每个阅读弹出,你首先检查地图,如果你发现我在那里你返回,如果你没有找到它,你从数据库中读取并在返回之前将其放在地图中。
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的每个写操作,您也写入Map
cache.put(cat.getName(), cat);
答案 2 :(得分:0)