🚀 Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratis—rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI

Persiapan

  • Engineering
April 13, 2020
milvus

Pada artikel ini, kami akan menjelaskan bagaimana data vektor direkam dalam memori Milvus, dan bagaimana data ini dipertahankan.

Di bawah ini adalah tujuan desain utama kami:

  1. Efisiensi impor data harus tinggi.
  2. Data dapat dilihat sesegera mungkin setelah impor data.
  3. Hindari fragmentasi file data.

Oleh karena itu, kami telah membuat penyangga memori (insert buffer) untuk menyisipkan data untuk mengurangi jumlah peralihan konteks IO acak pada disk dan sistem operasi untuk meningkatkan kinerja penyisipan data. Arsitektur penyimpanan memori berdasarkan MemTable dan MemTableFile memungkinkan kami untuk mengelola dan melakukan serialisasi data dengan lebih nyaman. Status buffer dibagi menjadi Mutable dan Immutable, yang memungkinkan data disimpan ke disk sambil tetap menyediakan layanan eksternal.

Persiapan

Ketika pengguna siap untuk memasukkan vektor ke dalam Milvus, pertama-tama ia harus membuat Collection (* Milvus mengganti nama Table menjadi Collection pada versi 0.7.0). Collection adalah unit paling dasar untuk merekam dan mencari vektor di Milvus.

Setiap Collection memiliki nama yang unik dan beberapa properti yang dapat diatur, dan vektor-vektor dimasukkan atau dicari berdasarkan nama Collection. Ketika membuat sebuah Collection baru, Milvus akan mencatat informasi dari Collection ini di dalam metadata.

Penyisipan Data

Ketika pengguna mengirimkan permintaan untuk menyisipkan data, data diserialisasikan dan dideserialisasikan untuk mencapai server Milvus. Data sekarang ditulis ke dalam memori. Penulisan memori secara garis besar dibagi menjadi beberapa langkah berikut:

2-data-insertion-milvus.png 2-penyisipan-data-milvus.png

  1. Pada MemManager, cari atau buat MemTable baru yang sesuai dengan nama Koleksi. Setiap MemTable berhubungan dengan buffer Koleksi dalam memori.
  2. Sebuah MemTable akan berisi satu atau lebih MemTableFile. Setiap kali kita membuat MemTableFile baru, kita akan mencatat informasi ini di Meta pada saat yang sama. Kita membagi MemTableFile ke dalam dua status: Dapat berubah dan Tidak Dapat Berubah. Ketika ukuran MemTableFile mencapai ambang batas, ia akan menjadi Immutable. Setiap MemTable hanya dapat memiliki satu MemTableFile Mutable yang dapat ditulis kapan saja.
  3. Data dari setiap MemTableFile pada akhirnya akan direkam dalam memori dalam format tipe indeks yang ditetapkan. MemTableFile adalah unit paling dasar untuk mengelola data dalam memori.
  4. Setiap saat, penggunaan memori dari data yang disisipkan tidak akan melebihi nilai yang telah ditetapkan (insert_buffer_size). Hal ini dikarenakan setiap ada permintaan untuk menyisipkan data yang masuk, MemManager dapat dengan mudah menghitung memori yang ditempati oleh MemTableFile yang terdapat pada setiap MemTable, lalu mengkoordinasikan permintaan penyisipan data sesuai dengan memori yang ada.

Melalui arsitektur multi-level MemManager, MemTable dan MemTableFile, penyisipan data dapat dikelola dan dipelihara dengan lebih baik. Tentu saja, mereka dapat melakukan lebih dari itu.

Query yang Hampir Real-time

Dalam Milvus, Anda hanya perlu menunggu paling lama satu detik untuk memindahkan data yang disisipkan dari memori ke disk. Keseluruhan proses ini secara kasar dapat diringkas oleh gambar berikut:

2-near-real-time-query-milvus.png 2-hampir-real-time-query-milvus.png

Pertama, data yang disisipkan akan masuk ke dalam buffer penyisipan di memori. Buffer secara berkala akan berubah dari kondisi awal Mutable ke kondisi Immutable sebagai persiapan untuk serialisasi. Kemudian, buffer Immutable ini akan diserialisasi ke disk secara berkala oleh thread serialisasi latar belakang. Setelah data ditempatkan, informasi pesanan akan dicatat dalam metadata. Pada titik ini, data dapat dicari!

Sekarang, kami akan menjelaskan langkah-langkah dalam gambar secara rinci.

Kita sudah mengetahui proses memasukkan data ke dalam buffer yang dapat diubah. Langkah berikutnya adalah beralih dari buffer yang dapat diubah ke buffer yang tidak dapat diubah:

3-mutable-buffer-immutable-buffer-milvus.png 3-mutable-buffer-immutable-buffer-milvus.png

Antrian yang tidak dapat diubah akan menyediakan latar belakang thread serialisasi dengan status yang tidak dapat diubah dan MemTableFile yang siap untuk diserialisasi. Setiap MemTable mengelola antrean tidak berubahnya sendiri, dan ketika ukuran satu-satunya MemTableFile yang dapat diubah mencapai ambang batas, ia akan masuk ke antrean tidak berubah. Thread latar belakang yang bertanggung jawab atas ToImmutable akan secara berkala menarik semua MemTableFile dalam antrean tidak dapat diubah yang dikelola oleh MemTable dan mengirimkannya ke antrean tidak dapat diubah secara keseluruhan. Perlu dicatat bahwa dua operasi menulis data ke dalam memori dan mengubah data dalam memori ke dalam keadaan yang tidak dapat ditulis tidak dapat terjadi pada saat yang sama, dan diperlukan penguncian bersama. Namun demikian, pengoperasian ToImmutable sangat sederhana dan hampir tidak menyebabkan penundaan apa pun, sehingga dampak performa pada data yang dimasukkan sangat minimal.

Langkah selanjutnya adalah menserialisasikan MemTableFile dalam antrian serialisasi ke disk. Ini terutama dibagi menjadi tiga langkah:

4-serialize-memtablefile-milvus.png 4-serialisasi-memtablefile-milvus.png

Pertama, thread serialisasi latar belakang akan menarik MemTableFile dari antrean yang tidak dapat diubah secara berkala. Kemudian, mereka diserialisasi menjadi file mentah berukuran tetap (Raw TableFiles). Terakhir, kita akan mencatat informasi ini dalam metadata. Ketika kita melakukan pencarian vektor, kita akan menanyakan TableFile yang sesuai dalam metadata. Dari sini, data-data ini dapat dicari!

Selain itu, menurut set index_file_size, setelah thread serialisasi menyelesaikan siklus serialisasi, ia akan menggabungkan beberapa TableFile dengan ukuran tetap ke dalam TableFile, dan juga mencatat informasi ini dalam metadata. Pada saat ini, TableFile dapat diindeks. Pembuatan indeks juga bersifat asinkron. Thread latar belakang lain yang bertanggung jawab atas pembuatan indeks akan secara berkala membaca TableFile dalam status ToIndex pada metadata untuk melakukan pembuatan indeks yang sesuai.

Faktanya, Anda akan menemukan bahwa dengan bantuan TableFile dan metadata, pencarian vektor menjadi lebih intuitif dan nyaman. Secara umum, kita perlu mendapatkan TableFile yang sesuai dengan Koleksi yang ditanyakan dari metadata, mencari di setiap TableFile, dan akhirnya menggabungkan. Pada artikel ini, kami tidak membahas implementasi spesifik dari pencarian.

Jika Anda ingin tahu lebih banyak, silakan baca kode sumber kami, atau baca artikel teknis kami yang lain tentang Milvus!

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started

Like the article? Spread the word

Terus Baca