Jika data tidak sesuai dengan memori. Metode paling sederhana


Aardvark betina dengan cub. Foto: Scotto Bear , CC BY-SA 2.0

Anda menulis sebuah program untuk pemrosesan data, ia lulus tes dengan sempurna pada file kecil, tetapi crash pada beban nyata.

Masalahnya adalah kehabisan memori. Jika Anda memiliki RAM 16 gigabyte, Anda tidak akan dapat mengunduh file seratus gigabyte di sana. Pada titik tertentu, OS akan kehabisan memori, tidak akan dapat mengalokasikan yang baru, dan program akan macet.

Apa yang harus dilakukan

Nah, Anda bisa menggunakan cluster Big Data, cukup:

  • Temukan sekelompok komputer.
  • Atur dalam seminggu.
  • Pelajari API baru dan tulis ulang kode Anda.

Itu mahal dan tidak menyenangkan. Untungnya, seringkali tidak perlu.

Kami membutuhkan solusi sederhana dan mudah: untuk memproses data pada satu komputer, dengan pengaturan minimal dan penggunaan maksimum perpustakaan yang sudah terhubung. Ini hampir selalu mungkin dengan bantuan metode paling sederhana, kadang-kadang disebut komputasi out-of-core.

Pada artikel ini kita membahas:

  • Mengapa kita membutuhkan RAM sama sekali.
  • Cara termudah untuk memproses data yang tidak sesuai dengan memori adalah menghabiskan sedikit uang.
  • Tiga metode perangkat lunak utama untuk memproses jumlah data yang berlebihan: kompresi, pemblokiran, dan pengindeksan.

Artikel mendatang akan menunjukkan dalam praktiknya bagaimana menerapkan metode ini dengan perpustakaan tertentu seperti NumPy dan Panda. Tapi pertama-tama, teorinya.

Mengapa RAM diperlukan?


Sebelum kita membahas solusi, mari kita perjelas mengapa masalah ini ada. Anda dapat menulis data ke memori akses acak (RAM), tetapi juga ke hard drive Anda, jadi mengapa Anda perlu RAM? Disk lebih murah, biasanya tidak memiliki masalah dengan ruang yang terbatas, mengapa tidak membatasi diri Anda untuk membaca dan menulis dari disk?

Secara teoritis, ini mungkin berhasil. Tetapi bahkan SSD cepat modern bekerja banyak, jauh lebih lambat daripada RAM:

  • Baca dari SSD: ~ 16.000 nanodetik
  • Baca dari RAM: ~ 100 nanodetik

Untuk perhitungan cepat, kami tidak punya pilihan: data harus ditulis ke RAM, jika tidak, kode akan melambat 150 kali.

Solusi termudah: lebih banyak RAM


Solusi termudah untuk masalah kehabisan RAM adalah menghabiskan uang. Anda dapat membeli komputer yang kuat, server atau menyewa mesin virtual dengan banyak memori. Pada November 2019, pencarian cepat dan perbandingan harga yang sangat singkat memberikan opsi berikut:

  • Beli Thinkpad M720 Tower dengan 6 core dan 64 GB RAM seharga $ 1074
  • Sewa mesin virtual di cloud dengan 64 core dan RAM 432 GB untuk $ 3,62 / jam

Ini hanya angka setelah pencarian cepat. Setelah melakukan penelitian yang baik, Anda pasti akan menemukan penawaran yang lebih baik.

Menghabiskan sedikit uang pada perangkat keras untuk memasukkan data ke dalam RAM seringkali merupakan solusi termurah. Lagipula, waktu kita mahal. Tetapi terkadang ini tidak cukup.

Misalnya, jika Anda melakukan banyak tugas pemrosesan data selama periode waktu tertentu, komputasi awan dapat menjadi solusi alami, tetapi juga bisa mahal. Pada salah satu proyek kami, biaya komputasi seperti itu akan menghabiskan semua pendapatan yang diproyeksikan dari produk, termasuk pendapatan paling penting yang diperlukan untuk membayar gaji saya.

Jika membeli / menyewa sejumlah besar RAM tidak menyelesaikan masalah atau tidak mungkin, langkah selanjutnya adalah mengoptimalkan aplikasi itu sendiri sehingga menghabiskan lebih sedikit memori.

Teknik nomor 1. Kompresi


Kompresi memungkinkan Anda untuk memasukkan data yang sama dalam memori lebih sedikit. Ada dua bentuk kompresi:

  • Lossless : setelah kompresi, informasi yang persis sama disimpan seperti dalam data asli.
  • Rugi : data yang disimpan kehilangan beberapa detail, tetapi idealnya ini tidak terlalu mempengaruhi hasil perhitungan.

Hanya untuk kejelasan, ini bukan tentang file zip atau gzip ketika data dikompres pada disk . Untuk memproses data dari file ZIP, Anda biasanya perlu unzip, dan kemudian memuat file ke dalam memori. Jadi ini tidak akan membantu.

Yang kita butuhkan adalah kompresi representasi data dalam memori .

Misalkan data Anda hanya menyimpan dua nilai yang mungkin, dan tidak ada yang lain: "AVAILABLE" dan "UNAVAILABLE" "AVAILABLE" "UNAVAILABLE" . Alih-alih menyimpan string dengan 10 byte atau lebih per catatan, Anda dapat menyimpannya sebagai nilai Boolean True atau False , yang dikodekan hanya satu byte. Anda dapat memampatkan informasi bahkan menjadi satu bit, mengurangi konsumsi memori sebanyak delapan kali.

Teknik No. 2. Membelah menjadi blok, memuat data satu blok pada suatu waktu


Fragmentasi berguna dalam situasi di mana data tidak harus dimuat ke memori pada saat bersamaan. Sebagai gantinya, kita dapat memuatnya dalam beberapa bagian, memproses satu fragmen pada satu waktu (atau, seperti yang akan kita bahas di artikel berikutnya, beberapa bagian secara paralel).

Misalkan Anda ingin menemukan kata terbesar dalam sebuah buku. Anda dapat memuat semua data ke dalam memori sekaligus:

 largest_word = "" for word in book.get_text().split(): if len(word) > len(largest_word): largest_word = word 

Tetapi jika buku itu tidak sesuai dengan memori, Anda dapat memuatnya halaman demi halaman:

 largest_word = "" for page in book.iterpages(): for word in page.get_text().split(): if len(word) > len(largest_word): largest_word = word 

Ini sangat mengurangi konsumsi memori karena hanya satu halaman buku dimuat sekaligus. Dalam hal ini, hasilnya akan menjadi jawaban yang sama.

Teknik No. 3. Pengindeksan hanya jika diperlukan subset data


Pengindeksan berguna jika Anda ingin menggunakan hanya sebagian dari data dan Anda akan memuat subset yang berbeda pada waktu yang berbeda.

Pada prinsipnya, dalam situasi seperti itu, Anda dapat menyaring bagian yang diperlukan dan membuang yang tidak perlu. Tetapi penyaringan lambat dan tidak optimal, karena Anda harus memuat banyak data tambahan ke dalam memori sebelum menjatuhkannya.

Jika Anda hanya memerlukan sebagian data, alih-alih fragmentasi, lebih baik menggunakan indeks - pemerasan data yang menunjukkan lokasi sebenarnya.

Bayangkan Anda hanya ingin membaca bagian-bagian dari sebuah buku yang menyebutkan aardvark (mamalia imut di foto di awal artikel). Jika Anda memeriksa semua halaman secara bergantian, seluruh buku akan dimuat dalam bagian, halaman demi halaman, untuk mencari aardvarks - dan ini akan memakan banyak waktu.

Atau Anda dapat segera membuka indeks alfabet di akhir buku - dan menemukan kata "aardvark". Ini menyatakan bahwa kata tersebut disebutkan pada halaman 7, 19 dan 120-123. Sekarang Anda dapat membaca halaman-halaman ini, dan hanya mereka, yang jauh lebih cepat.

Ini adalah metode yang efektif karena indeksnya jauh lebih kecil dari keseluruhan buku, jadi lebih mudah memuat indeks saja ke dalam memori untuk menemukan data yang relevan.

Metode pengindeksan termudah


Cara termudah dan paling umum untuk mengindeks adalah menamai file dalam direktori:

 mydata/ 2019-Jan.csv 2019-Feb.csv 2019-Mar.csv 2019-Apr.csv ... 

Jika Anda memerlukan data untuk Maret 2019, Anda cukup mengunggah file 2019-Mar.csv - tidak perlu mengunduh data untuk Februari, Juli atau bulan lainnya.

Berikutnya: menerapkan metode ini


Masalah kurangnya RAM paling mudah diselesaikan dengan bantuan uang, setelah membeli RAM. Tetapi jika ini tidak mungkin atau tidak cukup, Anda akan tetap menggunakan kompresi, fragmentasi, atau pengindeksan.

Metode yang sama digunakan dalam berbagai paket dan alat perangkat lunak . Bahkan sistem Big Data berkinerja tinggi dibangun di atasnya: misalnya, pemrosesan paralel fragmen data individual.

Dalam artikel berikut, kita akan melihat bagaimana menerapkan metode ini di perpustakaan dan alat tertentu, termasuk NumPy dan Panda.

Source: https://habr.com/ru/post/id479282/


All Articles