2012-02-03 70 views
18

我的模型有不同的實體,我希望計算一次就像公司的員工一樣。爲避免一次又一次地進行相同的查詢,計算的列表被保存在Memcache(duration = 1day)中。問題是,應用程序有時會給我一個錯誤,指出存儲在Memcache中的字節數多於允許的數量:避免Memcache「長度爲1000000字節」值的限制

Values may not be more than 1000000 bytes in length; received 1071339 bytes 

是否正在存儲一個對象列表,您應該使用Memcache做什麼?如果是這樣,避免上述錯誤的最佳做法是什麼?我目前正在拉1000件物品。你是否將限制值設爲< 200?在內存中檢查對象的大小似乎不是一個好主意,因爲在進入Memcache之前,它們可能正在被處理(序列化或類似的東西)。

+0

我第一次看到這個問題的標題時,我認爲這裏的Memcache只能存儲100萬個值。標題可以更改爲「避免Memcache 1MB限制值」? – 2015-06-30 07:00:45

回答

28

大衛,你不會說你使用哪種語言,但在Python中,你可以做同樣的事情,易卜拉欣建議使用泡菜。你所需要做的就是編寫兩個小幫助函數,它們可以讀取和寫入一個大對象給memcache。下面是一個(未經測試)素描:

def store(key, value, chunksize=950000): 
    serialized = pickle.dumps(value, 2) 
    values = {} 
    for i in xrange(0, len(serialized), chunksize): 
    values['%s.%s' % (key, i//chunksize)] = serialized[i : i+chunksize] 
    return memcache.set_multi(values) 

def retrieve(key): 
    result = memcache.get_multi(['%s.%s' % (key, i) for i in xrange(32)]) 
    serialized = ''.join([v for k, v in sorted(result.items()) if v is not None]) 
    return pickle.loads(serialized) 
+1

感謝Guido提供的素描,它爲我提供了前進的正確基礎。 – 2012-02-06 16:01:37

+0

我有一個和@Nikolay類似的問題,pickle.loads行失敗了,因爲這些值的返回順序與它們被醃製的順序不同。我使用了serialized_data = [result [key]作爲key中的鍵值,如果key中的result和result [key]不是None]來解決我的問題。 – John 2014-03-31 12:51:09

+0

我無法完全理解此代碼。我可以請一個人解釋一步一步的做法嗎? – puoyaahhh 2014-07-17 15:47:37

8

我經常在memcache上存儲大小爲幾兆字節的對象。我無法評論這是否是一種好的做法,但我認爲有時我們只需要一種相對較快的方式在我們的應用引擎實例之間傳輸兆字節的數據。

由於我使用Java,我所做的就是使用Java的序列化器序列化我的原始對象,生成一個序列化的字節數組。由於現在已知序列化對象的大小,因此我可以將其分割爲800 KB的字節數組塊。然後我將字節數組封裝在容器對象中,並存儲該對象而不是原始對象。

每個容器對象都可以有一個指向下一個memcache鍵的指針,在這裏我可以獲取下一個字節數組塊,如果沒有更多的塊需要從memcache中獲取,則爲null。 (就像鏈接列表一樣),然後我重新將字節數組塊合併成一個大的字節數組,並使用Java的解串器對其進行反序列化。

+0

感謝易卜拉欣,這絕對是一個創造性的解決方案。我期待看到在memcache中存儲對象列表的更簡單更標準的方法。 – 2012-02-03 11:57:29

5

您是否總是需要訪問您存儲的所有數據?如果不是,那麼您將受益於對數據集進行分區並僅訪問所需的部分數據。

如果您顯示1000名員工的列表,您可能會對其進行分頁。如果你分頁,那麼你一定可以分區。

您可以創建兩個數據集列表:一個打火機只包含最基本的信息,可以放入1 MB,另一個列表可以分成幾個部分,包含全部信息。在燈光列表中,您將能夠應用最重要的操作,例如通過員工姓名或分頁進行過濾。然後當需要加載沉重的數據集時,您將只能加載您真正需要的零件。

但是,這些建議需要時間來實施。如果你可以接受你目前的設計,那麼只需將你的列表分成300個物品的塊或任何數量是安全的,並加載它們併合並。

+1

現貨在想法Skirmantas!你說得對,他們需要實施時間,但他們值得研究。感謝您分享您的建議。 – 2012-02-03 14:18:34

3

如果你知道如何大會的對象是你可以使用memcached的選項,允許更大的物體:

memcached -I 10m 

這將使對象達到10MB。

+2

謝謝。有用的知道,但它似乎不是在AppEngine上被標記爲原始問題的平臺的選項:https://cloud.google.com/appengine/docs/python/memcache/#Python_Limits – Michael 2015-06-22 13:52:35