2012-02-03 9 views
18

Mój model ma różne jednostki, które chciałbym obliczyć raz jak pracowników firmy. Aby uniknąć powtarzania tego samego zapytania, wyliczona lista jest zapisywana w memcache (czas trwania = 1 dzień). Problem polega na tym, że aplikacja czasami daje mi błąd, że w Memcache jest więcej bajtów niż jest to dopuszczalne:Unikanie memcache "Limit długości 1000000 bajtów" dla wartości

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

Czy przechowujesz listę obiektów, które powinieneś robić z Memcache? Jeśli tak, jakie są najlepsze praktyki w unikaniu powyższego błędu? Obecnie przeciągam 1000 obiektów. Czy ograniczasz wartości do < 200? Sprawdzanie rozmiaru obiektu w pamięci nie wydaje się zbyt dobrym pomysłem, ponieważ prawdopodobnie są przetwarzane (serializowane lub coś w tym stylu) przed wejściem do Memcache.

+0

Po pierwszym przeczytaniu tytułu pytania pomyślałem, że Memcache tutaj może przechowywać tylko 1M jak 1 milion wartości.Czy tytuł można zmienić na "Unikanie limitu wartości 1MB memcache"? –

Odpowiedz

28

David, nie mówisz jakiego języka używasz, ale w Pythonie możesz zrobić to samo, co Ibrahim sugeruje używanie marynarki. Wszystko, co musisz zrobić, to napisać dwie małe funkcje pomocnicze, które odczytują i zapisują duży obiekt do memcache. Oto (niesprawdzone) szkic:

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

Dzięki Guido za szkicowanie, daje mi to właściwą podstawę do posunięcia się naprzód. –

+0

Miałem podobny problem, jak @Nikolay, linia pickle.loads zawodziła, ponieważ wartości wracały w innej kolejności niż zostały wytrawione. Użyłem serialized_data = [result [key] dla klucza w kluczach, jeśli kluczem w wyniku i wyniku [key] nie jest None], aby rozwiązać mój problem. – John

+0

Mam problem z pełnym zrozumieniem tego kodu. Czy mogę poprosić kogoś o wyjaśnienie, co robi krok po kroku? – puoyaahhh

8

Często przechowuję obiekty o wielkości kilku megabajtów na memcache. Nie mogę komentować, czy jest to dobra praktyka, czy nie, ale moim zdaniem, po prostu potrzebujemy stosunkowo szybkiego transferu megabajtów danych między naszymi instancjami mechanizmu aplikacji.

Ponieważ używam języka Java, to co zrobiłem, jest serializowanie moich obiektów surowych za pomocą serializatora Java, tworząc serializowaną tablicę bajtów. Ponieważ rozmiar serializowanego obiektu jest już znany, mogłem wyciąć fragmenty macierzy bajtowych o wielkości 800 kilobajtów. Następnie hermetyzuję tablicę bajtów w obiekcie kontenera i przechowuję ten obiekt zamiast obiektów surowych.

Każdy obiekt kontenera może mieć wskaźnik do następnego klucza memcache, w którym mógłbym pobrać następny fragment tablicy bajtów lub null, jeśli nie ma więcej porcji, które trzeba pobrać z memcache. (tj. podobnie jak lista połączona), a następnie ponownie scalam porcje tablic bajtowych w tablicę o dużych bajtach i deserializuję ją za pomocą deserializera Java.

+0

Dzięki Ibrahim, to zdecydowanie twórcze rozwiązanie. Chciałbym zobaczyć, jakie prostsze, bardziej standardowe podejścia do przechowywania list obiektów w memcache. –

5

Czy zawsze potrzebujesz dostępu do wszystkich danych, które przechowujesz? Jeśli nie, skorzystasz z partycjonowania zestawu danych i dostępu tylko do części potrzebnych danych.

Jeśli wyświetlisz listę 1000 pracowników, prawdopodobnie będziesz ją paginować. Jeśli będziesz stronił, to na pewno możesz podzielić.

Możesz utworzyć dwie listy danych: jedna lżejsza z najważniejszymi informacjami, które mogą zmieścić się w 1 MB i innej liście, która jest podzielona na kilka części z pełną informacją. Na liście lekkiej będziesz mógł zastosować najważniejsze operacje, na przykład filtrowanie przez nazwę pracownika lub paginację. A kiedy trzeba załadować ciężki zestaw danych, będziesz mógł załadować tylko te części, których naprawdę potrzebujesz.

Ale te sugestie wymagają czasu. Jeśli możesz żyć z aktualnym projektem, po prostu podziel listę na kawałki o wartości ~ 300 elementów lub dowolną liczbę, która jest bezpieczna i załaduj je wszystkie i scal.

+1

Miejsce na pomysły Skirmantas! Masz rację, że poświęcą czas na wdrożenie, ale warto się nimi zająć. Dzięki za podzielenie się twoją radą. –

3

Jeśli wiesz, jak duże będą przedmioty być może użyć opcji memcached aby umożliwić większych obiektów:

memcached -I 10m 

Pozwoli obiektów do 10 MB.

+2

Dzięki. Warto wiedzieć, ale wygląda na to, że nie jest to opcja w AppEngine, która jest oznaczona jako platforma oryginalnego pytania: https://cloud.google.com/appengine/docs/python/memcache/#Python_Limits – Michael

Powiązane problemy