簡體   English   中英

如何使用大量數據的Google App Engine MapReduce(> 1000000)

[英]How to use Google App Engine MapReduce with large amount of data ( >1000000 )

我實現了非常簡單的mapreduce管道並堆積了一些問題。

場景是,雲數據存儲中的一種模型中有超過1000000個實體,我想檢查所有實體是否每個實體都有不一致屬性。

這是我的代碼片段。

class User(ndb.model)
    parent = ndb.KeyProperty(Group) # want to check if this key property actually exist


class CheckKeyExistencePipeline(pipeline.Pipeline):

    def map(self, entity):
        logging.info(entity.urlsafe()) # added for debug
        prop = getattr(entity, 'parent')
        if not prop.get():
            yield 'parent does not exist: %s\n' % (entity.key.urlsafe())

    def run(self, modelname, shards):
        mapreduce_pipeline.MapperPipeline(
            'parent check',
            handler_spec='CheckKeyExistencePipeline.map',
            input_reader_spec='mapreduce.input_readers.DatastoreInputReader',
            output_writer_spec="mapreduce.output_writers.GoogleCloudStorageOutputWriter",
            params={
                'input_reader': {
                    'entity_kind': 'User',
                },
                'output_writer': {
                    'bucket_name': app_identity.get_default_gcs_bucket_name(),
                    'content_type': 'text/plain'
                }
            },
            shards=10)

問題是,它經常顯示出如下的錯誤。

在為2個請求提供服務后,超過128 MB的軟私有內存限制(133 MB)

使用大約10000個實體的數據運行此代碼時沒有問題。 什么是問題,如何正確配置此管道以應用大量數據?

EDIT1

我修改了不使用ndb緩存,但似乎沒有任何改進。 根據源代碼,我猜緩存已經默認關閉。

https://github.com/GoogleCloudPlatform/appengine-mapreduce/blob/6e103ac52855c3214de3ec3721d6ec0e7edd5f77/python/src/mapreduce/util.py#L381-L383

def _set_ndb_cache_policy():
    """Tell NDB to never cache anything in memcache or in-process.
    This ensures that entities fetched from Datastore input_readers via NDB
    will not bloat up the request memory size and Datastore Puts will avoid
    doing calls to memcache. Without this you get soft memory limit exits,
    which hurts overall throughput.
    """
    ndb_ctx = ndb.get_context()
    ndb_ctx.set_cache_policy(lambda key: False)
    ndb_ctx.set_memcache_policy(lambda key: False)

我做了進一步調查以找出問題。 我將mapper參數processing_rate一個設置為10並將分shards為100,這樣它每個任務只處理1個或2個實體。

這是mapreduce屬性。 圖表似乎合理。 (此時管道尚未完成。)

mapreduce細節

但是當我檢查其中一個工作任務的跟蹤日志時,這真的很奇怪。 它顯示了一堆/datastore_v3.Next/datastore_v3.Get盡管'map'函數只被調用兩次(根據我的調試日志。)因為我沒有更改batch_size,所以它應該是50.所以,在我的理解,/ /datastore_v3.Next應該只被調用一次而/datastore_v3.Get兩次。

追蹤日志

有誰知道為什么會觸發這么多對數據庫的RPC調用?

EDIT2

我再次進行了進一步調查,並使代碼變得簡單。 map函數只是通過調用它的get函數使用ndb.Key獲取數據。

class CheckKeyExistencePipeline(pipeline.Pipeline):

    def map(self, entity):
        logging.info('start')
        entity.parent.get()
        logging.info('end')


    def run(self):
        mapreduce_pipeline.MapperPipeline(
            'parent check',
            handler_spec='CheckKeyExistencePipeline.map',
            input_reader_spec='mapreduce.input_readers.DatastoreInputReader',
            output_writer_spec="mapreduce.output_writers.GoogleCloudStorageOutputWriter",
            params={
                'input_reader': {
                    'entity_kind': 'User',
                },
                'output_writer': {
                    'bucket_name': app_identity.get_default_gcs_bucket_name(),
                    'content_type': 'text/plain'
                }
            },
            shards=10)

Stackdriver的Tracelog是這樣的。

跟蹤日志

它只是調用get但它在'start'和'end'之間多次觸發RPC調用。 這似乎有點奇怪,可能是這種內存消耗的原因之一。 這是常規行為嗎?

我想我終於找到了問題所在。

關鍵是MapReduce使用ndb.query.iter ,它使用eventloops來管理異步RPC調用。 在我的MapReduce調用中,它觸發兩種類型的RPC調用,一種是由MapReduce庫觸發來獲取數據庫記錄(A),另一種是由我的map函數(B)觸發。

如果我沒有在map函數中觸發任何RPC調用,則沒有地方可以觸發下一個RPC調用。 這意味着下一個(A)僅在批量處理50個記錄后觸發。 但是,嘗試(B)觸發下一個RPC調用,並且由於RPC調用不是串行觸發的(這意味着它不是FIFO隊列),因此很可能(A)連續觸發,直到它獲取所有實體。

我將分shards設置為100但仍然有一個分shards負責完全10000條記錄。 因此,超過了軟內存限制。

當我將分shards增加到10000時,會發生另一個錯誤......

總之,沒有辦法將MapReduce與具有低內存實例的大數據一起使用。 我猜。

有關詳細信息,請查看以下問題。

https://code.google.com/p/googleappengine/issues/detail?id=11648 https://code.google.com/p/googleappengine/issues/detail?id=9610 (原始期刊)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM