PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Błąd pamięci podczas używania metody read() do odczytu dużego rozmiaru pliku JSON z Amazon S3

Znaczne oszczędności można uzyskać, unikając pożerania całego pliku wejściowego w pamięci jako list linii.

W szczególności te wiersze są straszne pod względem wykorzystania pamięci, ponieważ obejmują szczytowe użycie pamięci bytes określ rozmiar całego pliku plus list wierszy z pełną zawartością pliku:

file_content = obj['Body'].read().decode('utf-8').splitlines(True)
for line in file_content:

Dla pliku tekstowego ASCII o pojemności 1 GB z 5 milionami wierszy, w 64-bitowym Pythonie 3.3+, szczytowe zapotrzebowanie na pamięć wynosi około 2,3 GB dla tylko bytes obiekt, list i indywidualny str s na list . Program, który potrzebuje 2,3 razy więcej pamięci RAM niż rozmiar przetwarzanych plików, nie będzie skalowany do dużych plików.

Aby naprawić, zmień oryginalny kod na:

file_content = io.TextIOWrapper(obj['Body'], encoding='utf-8')
for line in file_content:

Biorąc pod uwagę, że obj['Body'] wydaje się, że nadaje się do leniwego przesyłania strumieniowego to powinno usunąć oba kopie pełnych danych pliku z pamięci. Korzystanie z TextIOWrapper oznacza obj['Body'] jest leniwie odczytywany i dekodowany w kawałkach (po kilka KB na raz), a wiersze są również leniwie iterowane; zmniejsza to zapotrzebowanie na pamięć do małej, w dużej mierze stałej wartości (szczytowy koszt pamięci zależy od długości najdłuższej linii), niezależnie od rozmiaru pliku.

Aktualizacja:

Wygląda jak StreamingBody nie implementuje io.BufferedIOBase ABC. Ma własny udokumentowany interfejs API jednak można to wykorzystać w podobnym celu. Jeśli nie możesz utworzyć TextIOWrapper wykonać pracę za Ciebie (jest to o wiele bardziej wydajne i prostsze, jeśli można sprawić, aby działał), alternatywą byłoby:

file_content = (line.decode('utf-8') for line in obj['Body'].iter_lines())
for line in file_content:

W przeciwieństwie do używania TextIOWrapper , nie korzysta z masowego dekodowania bloków (każda linia jest dekodowana indywidualnie), ale poza tym powinna nadal osiągać te same korzyści pod względem zmniejszonego zużycia pamięci.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wstawianie danych analitycznych ze Sparka do Postgres

  2. Wygeneruj SQL, aby zaktualizować klucz podstawowy

  3. Nadaj uprawnienia wszystkim użytkownikom, obecnym i przyszłym

  4. Zapytanie o konkretną kolumnę JSON (postgres) za pomocą sqlalchemy

  5. Jak przyspieszyć strony administracyjne Django za pomocą szacowania liczby PostgreSQL?