Google app engine 用于评估数据存储模型中数据压缩导致的CPU损失和内存增加之间权衡的任何策略';什么是文本属性?
非常大的文本属性是一种负担吗?他们应该被压缩吗 假设我的数据存储实体中有一个信息存储在2个TextProperty类型的属性中。 字符串的长度始终相同,为65000个字符,并且有许多重复整数,示例如下所示:Google app engine 用于评估数据存储模型中数据压缩导致的CPU损失和内存增加之间权衡的任何策略';什么是文本属性?,google-app-engine,google-cloud-datastore,Google App Engine,Google Cloud Datastore,非常大的文本属性是一种负担吗?他们应该被压缩吗 假设我的数据存储实体中有一个信息存储在2个TextProperty类型的属性中。 字符串的长度始终相同,为65000个字符,并且有许多重复整数,示例如下所示: entity.pixel_idx = 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,5,5,5,5,5,5,5....etc. entity.pixel_color = 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
entity.pixel_idx = 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,5,5,5,5,5,5,5....etc.
entity.pixel_color = 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,...etc.
因此,也可以使用更少的存储内存来表示上述内容,比如只压缩每个整数及其序列的长度('0,0,0,0,0,0,0,0'
),但压缩和解压缩需要时间和CPU吗?
有什么一般性的想法吗?
是否有一些技巧可用于测试解决问题的不同尝试?我认为这应该很容易测试。只需创建两个处理程序,一个压缩数据,另一个不压缩数据,并记录每个处理程序使用的cpu量(无论使用哪种语言进行开发),还应创建两个实体类型,一个用于压缩数据,一个用于未压缩数据 加载几十万或一百万个实体(可能使用任务队列)。然后,您可以在管理员控制台中检查磁盘空间使用情况,并查看每种实体类型使用了多少磁盘空间。如果数据是由appengine内部压缩的,那么在使用的空间上应该不会有太大的差异(除非他们的压缩比你的好很多),如果数据没有压缩,那么应该会有明显的差异 当然,您可能希望推迟这种类型的测试,直到您确定这些实体将占配额使用和/或页面加载时间的很大一部分
或者,您可以等待Nick或Alex出现,他们可能会告诉您数据是否在数据存储中压缩。如果您的所有整数都是单位数(如示例中所示),则只需省略逗号即可将存储空间减少一半 简短的回答 如果您希望有大量的重复,那么压缩数据是有意义的-您的数据不是很小(65K),而且重复性很高=>压缩效果很好。这将节省存储空间,并减少查询数据时从数据存储区传回数据所需的时间 长话短说 我从您提供的简短示例字符串开始做了一些测试,该字符串重复了65000个字符(可能比实际数据重复得多)。这个字符串从65K压缩到几百字节;您可能需要根据数据的实际压缩程度进行一些额外的测试 无论如何,测试表明使用压缩数据比使用未压缩数据节省了大量成本(仅针对上面的测试,压缩效果非常好!)。特别是对于压缩数据:
- 单个实体的API时间缩短了10倍(平均为41ms,平均为387ms)
- 使用的存储空间明显减少(因此GAE看起来并没有对您的数据进行任何压缩)
- 出乎意料的是,CPU时间减少了约50%(获取100个实体时为130ms,而获取100个实体时为180ms)。我预计CPU时间会稍差一些,因为压缩数据必须解压缩。必须有一些其他的CPU工作(比如解码协议缓冲区),这对于更大的未压缩数据来说是更多的CPU工作
- 这些差异意味着压缩版本的挂钟时间也要快得多(还有,有人能确认谷歌还没有存储压缩的实体(这会降低应用程序端压缩的相关性)?根据GAE最近的一篇文章,字符串与UTF-8一样。它们没有提到任何压缩,因此即使在这样的非索引字段上也不太可能进行任何压缩。干得好。当然,你的结果自然在我脑海中引发了一个新问题-它的大小不再值得压缩?看起来它可能仍然值得压缩即使“小”到10k也可以压缩。谢谢:)。不幸的是,我认为压缩变得有用的转折点在很大程度上取决于您的数据。毕竟,你甚至可能有一兆字节的数据,并且可能从压缩中得到很少的数据-例如,试图压缩
可能会产生比输入更大的数据。谢天谢地,我认为由人类编写的长文章往往压缩得更好(例如,我的答案压缩到原始大小的40%左右)。感谢您提供了信息丰富的答案、代码,以及令人惊喜的重新计算较低的CPU时间。os。Uradom(2**20)
from google.appengine.ext import db import zlib class CompressedDataProperty(db.Property): """A property for storing compressed data or text. Example usage: >>> class CompressedDataModel(db.Model): ... ct = CompressedDataProperty() You create a compressed data property, simply specifying the data or text: >>> model = CompressedDataModel(ct='example uses text too short to compress well') >>> model.ct 'example uses text too short to compress well' >>> model.ct = 'green' >>> model.ct 'green' >>> model.put() # doctest: +ELLIPSIS datastore_types.Key.from_path(u'CompressedDataModel', ...) >>> model2 = CompressedDataModel.all().get() >>> model2.ct 'green' Compressed data is not indexed and therefore cannot be filtered on: >>> CompressedDataModel.gql("WHERE v = :1", 'green').count() 0 """ data_type = db.Blob def __init__(self, level=6, *args, **kwargs): """Constructor. Args: level: Controls the level of zlib's compression (between 1 and 9). """ super(CompressedDataProperty, self).__init__(*args, **kwargs) self.level = level def get_value_for_datastore(self, model_instance): value = self.__get__(model_instance, model_instance.__class__) if value is not None: return db.Blob(zlib.compress(value, self.level)) def make_value_from_datastore(self, value): if value is not None: return zlib.decompress(value)