2011-07-07 16 views
10

Używam django staticfiles + django-storages i Amazon S3 do przechowywania moich danych. Wszystko działa dobrze, ale za każdym razem, gdy uruchamiam manage.py collectstatic, polecenie przesyła wszystkie pliki na serwer.Django StaticFiles i Amazon S3: jak wykrywać zmodyfikowane pliki?

Wygląda na to, że polecenie zarządzania porównuje sygnatury czasowe z Storage.modified_time(), które nie są zaimplementowane w pamięci S3 z django-magazynów.

Jak ustalić, czy plik S3 został zmodyfikowany?

Mogłem przechowywać ścieżki plików i dane ostatniej modyfikacji w mojej bazie danych. Czy istnieje prosty sposób na pobranie ostatnio zmodyfikowanych danych z Amazon?

Inna opcja: wygląda na to, że mogę przypisać dowolne metadane z python-boto, gdzie mogę umieścić lokalnie zmodyfikowaną datę, kiedy przesyłam za pierwszym razem.

W każdym razie wydaje się, że jest to powszechny problem, dlatego chciałbym zapytać, jakie rozwiązanie zastosowano w innych urządzeniach. Dzięki!

Odpowiedz

10

Najnowsza wersja django-storages (1.1.3) obsługuje wykrywanie modyfikacji plików za pośrednictwem S3 Boto.

pip install django-storages i jesteś teraz dobra :) Gotta open source!

Aktualizacja: ustaw opcję AWS_PRELOAD_METADATA na True w pliku ustawień, aby uzyskać bardzo szybkie synchronizacje w przypadku korzystania z klasy S3Boto. Jeśli używasz jego S3, użyj jego klasy PreloadedS3.


Aktualizacja 2: Uruchomienie polecenia jest nadal bardzo powolne.


Aktualizacja 3: I forked the django-storages repository w celu rozwiązania problemu i dodania żądania pobrania.

Problem jest w metodzie modified_time, w której wywoływana jest wartość rezerwowa, nawet jeśli nie jest używana. I przeniósł awaryjna do bloku if być wykonywane tylko wtedy, gdy get powraca None

entry = self.entries.get(name, self.bucket.get_key(self._encode_name(name))) 

Powinny być

entry = self.entries.get(name) 
    if entry is None: 
     entry = self.bucket.get_key(self._encode_name(name)) 

Teraz różnica w wydajności jest od < .5s na 1000 wniosków od 100s


Aktualizacja 4:

Do synchronizacji 10k + plików, uważam, że boto musi wysyłać wiele żądań, ponieważ S3 dzieli wyniki powodując 5-10 sekundowy czas synchronizacji. To będzie tylko gorsze, ponieważ otrzymamy więcej plików.

Myślę, że rozwiązaniem jest posiadanie niestandardowego polecenia zarządzania lub aktualizacji django-storages gdzie plik jest przechowywany na S3, który ma metadane wszystkich innych plików, który jest aktualizowany za każdym razem, gdy plik jest aktualizowany za pomocą polecenia collectstatic.

Nie wykryje plików przesłanych za pomocą innych środków, ale nie ma znaczenia, czy jedynym punktem wejścia jest polecenie zarządzania.

+0

Jak korzystać z metody modified_time? Uruchomiono tylko ./manage.py collecstatic, nie działa dla mnie. Używa metody _save z botos3, aby zapisać pliki, ale w żadnym momencie nie sprawdza, czy plik jest nowy czy nie. Jakie jest twoje rozwiązanie? – duduklein

+0

To wydaje się już nieaktualne: python-dateutil> 2.1 obsługuje teraz zarówno Python 2, jak i 3 we wspólnej bazie kodu i python-dateutil == 2.1 działa dobrze dla mnie z botos3. –

+0

Hej Yuji; Zdaję sobie sprawę z tego samego problemu (bardzo powolna kolosie z S3Boto z kilkoma tysiącami plików). Zastanawiam się, gdzie się w tej sprawie spisałeś. Czy mógłbyś podsumować swoje najlepsze najlepsze rekomendacje, aby zoptymalizować ten proces, ponieważ wyraźnie zmarnowałeś czas na zmaganie się z tym problemem? –

0

Odpowiedziałem na to samo pytanie tutaj https://stackoverflow.com/a/17528513/1220706. Sprawdź https://github.com/FundedByMe/collectfast. Jest to plug-inowa aplikacja Django, która buforuje ETag zdalnych plików S3 i porównuje buforowaną sumę kontrolną zamiast wykonywać wyszukiwanie za każdym razem. Postępuj zgodnie z instrukcjami instalacji i normalnie działaj zgodnie z collectstatic. Zajęło mi to średnio od 1 do 30 do około 10 na wdrożenie.