Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine 用于评估数据存储模型中数据压缩导致的CPU损失和内存增加之间权衡的任何策略';什么是文本属性?_Google App Engine_Google Cloud Datastore - Fatal编程技术网

Google app engine 用于评估数据存储模型中数据压缩导致的CPU损失和内存增加之间权衡的任何策略';什么是文本属性?

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,

非常大的文本属性是一种负担吗?他们应该被压缩吗

假设我的数据存储实体中有一个信息存储在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,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也可以压缩。谢谢:)。不幸的是,我认为压缩变得有用的转折点在很大程度上取决于您的数据。毕竟,你甚至可能有一兆字节的数据,并且可能从压缩中得到很少的数据-例如,试图压缩
    os。Uradom(2**20)
    可能会产生比输入更大的数据。谢天谢地,我认为由人类编写的长文章往往压缩得更好(例如,我的答案压缩到原始大小的40%左右)。感谢您提供了信息丰富的答案、代码,以及令人惊喜的重新计算较低的CPU时间。
    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)