发布于2020-02-25 19:53 阅读(779) 评论(0) 点赞(21) 收藏(3)
我正在尝试对GAE数据存储进行一些练习,以对查询和计费机制有所了解。
我已经阅读了有关GAE的Oreilly书,并观看了有关数据存储区的Google视频。我的问题是,最佳实践方法通常涉及的是读取而不是写入数据存储区。
我构建了一个超级简单的应用程序:
在这种情况下,由于用户可以选择任意数量的链接,因此我的应用程序随时可以向数据存储写入数据,而读取次数远远大于读取次数(写-用户选择另一个链接时读-用户打开链接时读-网页上查看他的“链接供稿”)
问题1: 我可以想到(至少)两个选项如何处理此应用程序的数据:
选项A: -使用用户详细信息,注册等信息维护每个用户的实体-维护拥有他最近选择的10个链接的每个用户的另一个实体,该实体将在用户要求后呈现到用户的网页
选项B: -维护每个URL链接的实体-这意味着所有用户的所有URL都将存储为相同的对象-维护每个用户的实体的详细信息(与选项A中的相同),但在大处添加对用户URL的引用网址表
有什么更好的方法?
问题2: 如果我要计算直到今天为止选择的URL总数,或者用户选择的每日URL数量,或进行其他计数-我应该将其与我的SDK工具一起使用,还是应该在实体中插入计数器?如上所述?(我想尽可能减少数据存储的写入量)
编辑(回答@Elad的评论):假设我只想为每个用户保存10个最后一个URL。我想摆脱它们的其余部分(以免不必要的数据过多填充我的数据库)。
编辑2:添加代码后, 所以我尝试使用以下代码(尝试第一个Elad的方法):
这是我的课:
class UserChannel(db.Model):
currentUser = db.UserProperty()
userCount = db.IntegerProperty(default=0)
currentList = db.StringListProperty() #holds the last 20-30 urls
然后我将url和元数据序列化为JSON字符串,用户从第一页开始发布。POST的处理方式如下:
def post(self):
user = users.get_current_user()
if user:
logging messages for debugging
self.response.headers['Content-Type'] = 'text/html'
#self.response.out.write('<p>the user_id is: %s</p>' % user.user_id())
updating the new item that user adds
current_user = UserChannel.get_by_key_name(user.nickname())
dataJson = self.request.get('dataJson')
#self.response.out.write('<p>the dataJson is: %s</p>' % dataJson)
current_user.currentPlaylist.append(dataJson)
sizePlaylist= len(current_user.currentPlaylist)
self.response.out.write('<p>size of currentplaylist is: %s</p>' % sizePlaylist)
#whenever the list gets to 30 I cut it to be 20 long
if sizePlaylist > 30:
for i in range (0,9):
current_user.currentPlaylist.pop(i)
current_user.userCount +=1
current_user.put()
Updater().send_update(dataJson)
else:
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('user_not_logged_in')
其中Updater是我使用Channel-API更新包含提要的网页的方法。
现在,一切正常,我可以看到每个用户都有一个具有20-30个链接的ListProperty(当它达到30时,我使用pop()将其缩减为20),但是!价格非常高...每个POST都需要200毫秒,121 cpu_ms,cpm_usd = 0.003588。考虑到我要做的就是将一个字符串保存到列表中,因此这是非常昂贵的……我认为问题可能在于该实体随着大型ListProperty而变大了?
首先,您不必担心会大量写入GAE数据存储-我自己的经验是,与读取相比,它们非常昂贵。例如,我的一个仅在单个模型表中插入记录就什么都没做的应用程序已经耗尽了免费配额,每天只有几十万次写入。因此,有效地处理写入将直接转化为您的底线。
第一个问题
我不会将链接存储为单独的实体。数据存储区不是RDBMS,因此标准规范化实践不一定适用。对于每个用户实体,使用ListProperty来存储最新的URL及其元数据(您可以将所有内容序列化为字符串)。
另一个优化思路:如果您的用户通常在短时间内添加多个链接,则可以尝试成批编写而不是分别编写。使用内存缓存来存储新添加的用户URL,并使用任务队列将该临时数据定期写入持久性数据存储中。我不确定使用Tasks的资源成本是多少-您必须检查一下。 这是一篇有关该主题的好文章。
第二个问题
使用计数器。请记住,它们在分布式环境中并非无关紧要,因此请仔细阅读-有关该主题的许多GAE文章,食谱和博客文章-只是Google Appengine计数器。同样在这里,使用memcache应该是一个不错的选择,以减少数据存储写入的总数。
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/233617/eee5b3cec5d94ce15eca/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!