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

milvus-logo
LFAI
  • Home
  • Blog
  • Bagaimana manajemen data dilakukan di Milvus

Bagaimana manajemen data dilakukan di Milvus

  • Engineering
November 08, 2019
Yihua Mo

Penulis Yihua Mo

Tanggal: 2019-11-08

Bagaimana manajemen data dilakukan di Milvus

Pertama-tama, beberapa konsep dasar Milvus:

  • Tabel: Tabel adalah sekumpulan data vektor, dengan setiap vektor memiliki ID yang unik. Setiap vektor dan ID-nya merepresentasikan sebuah baris dari tabel. Semua vektor dalam tabel harus memiliki dimensi yang sama. Di bawah ini adalah contoh tabel dengan vektor 10 dimensi:

table tabel

  • Indeks: Membangun indeks adalah proses pengelompokan vektor dengan algoritme tertentu, yang membutuhkan ruang disk tambahan. Beberapa jenis indeks membutuhkan lebih sedikit ruang karena mereka menyederhanakan dan memampatkan vektor, sementara beberapa jenis lainnya membutuhkan lebih banyak ruang daripada vektor mentah.

Dalam Milvus, pengguna dapat melakukan tugas-tugas seperti membuat tabel, menyisipkan vektor, membuat indeks, mencari vektor, mengambil informasi tabel, menghapus tabel, menghapus sebagian data dalam tabel, dan menghapus indeks, dll.

Anggaplah kita memiliki 100 juta vektor 512 dimensi, dan perlu menyisipkan dan mengelolanya di Milvus untuk pencarian vektor yang efisien.

(1) Memasukkan Vektor

Mari kita lihat bagaimana vektor dimasukkan ke dalam Milvus.

Karena setiap vektor membutuhkan ruang 2 KB, maka ruang penyimpanan minimum untuk 100 juta vektor adalah sekitar 200 GB, yang membuat penyisipan semua vektor ini menjadi tidak realistis. Harus ada beberapa file data, bukan hanya satu. Performa penyisipan adalah salah satu indikator kinerja utama. Milvus mendukung penyisipan ratusan atau bahkan puluhan ribu vektor dalam satu kali penyisipan. Sebagai contoh, satu kali penyisipan 30 ribu vektor 512 dimensi umumnya hanya membutuhkan waktu 1 detik.

insert menyisipkan

Tidak semua penyisipan vektor dimasukkan ke dalam disk. Milvus menyediakan sebuah buffer yang dapat berubah-ubah dalam memori CPU untuk setiap tabel yang dibuat, dimana data yang disisipkan dapat dengan cepat ditulis. Dan ketika data dalam buffer yang dapat berubah mencapai ukuran tertentu, ruang ini akan diberi label sebagai tidak dapat diubah. Sementara itu, buffer baru yang dapat diubah akan dicadangkan. Data dalam buffer yang tidak dapat diubah ditulis ke disk secara teratur dan memori CPU yang sesuai akan dikosongkan. Mekanisme penulisan reguler ke disk mirip dengan mekanisme yang digunakan pada Elasticsearch, yang menulis data buffer ke disk setiap 1 detik. Sebagai tambahan, pengguna yang terbiasa dengan LevelDB/RocksDB dapat melihat kemiripan dengan MemTable di sini.

Tujuan dari mekanisme Penyisipan Data adalah:

  • Penyisipan data harus efisien.
  • Data yang disisipkan dapat digunakan secara instan.
  • File data tidak boleh terlalu terfragmentasi.

(2) File Data Mentah

Ketika vektor ditulis ke disk, vektor disimpan dalam File Data Mentah yang berisi vektor mentah. Seperti yang telah disebutkan sebelumnya, vektor berskala besar perlu disimpan dan dikelola dalam beberapa file data. Ukuran data yang dimasukkan bervariasi karena pengguna dapat memasukkan 10 vektor, atau 1 juta vektor sekaligus. Namun, operasi penulisan ke disk dijalankan setiap 1 detik sekali. Dengan demikian, file data dengan ukuran yang berbeda dihasilkan.

File data yang terfragmentasi tidak nyaman untuk dikelola dan tidak mudah diakses untuk pencarian vektor. Milvus secara konstan menggabungkan file-file data kecil ini hingga ukuran file yang digabungkan mencapai ukuran tertentu, misalnya, 1GB. Ukuran tertentu ini dapat dikonfigurasi dalam parameter API index_file_size dalam pembuatan tabel. Oleh karena itu, 100 juta vektor 512 dimensi akan didistribusikan dan disimpan dalam sekitar 200 file data.

Dengan mempertimbangkan skenario komputasi tambahan, di mana vektor dimasukkan dan dicari secara bersamaan, kita perlu memastikan bahwa setelah vektor ditulis ke disk, vektor tersebut tersedia untuk pencarian. Dengan demikian, sebelum file data kecil digabungkan, file-file tersebut dapat diakses dan dicari. Setelah penggabungan selesai, file data kecil akan dihapus, dan file yang baru digabungkan akan digunakan untuk pencarian.

Berikut ini adalah tampilan file yang ditanyakan sebelum penggabungan:

rawdata1 rawdata1

File yang ditanyakan setelah penggabungan:

rawdata2 rawdata2

(3) File Indeks

Pencarian berdasarkan File Data Mentah adalah pencarian brute-force yang membandingkan jarak antara vektor kueri dan vektor asal, dan menghitung k vektor terdekat. Pencarian brute-force tidak efisien. Efisiensi pencarian dapat sangat ditingkatkan jika pencarian didasarkan pada File Indeks di mana vektor-vektor diindeks. Membangun indeks membutuhkan ruang disk tambahan dan biasanya memakan waktu.

Jadi, apa perbedaan antara File Data Mentah dan File Indeks? Sederhananya, File Data Mentah mencatat setiap vektor bersama dengan ID uniknya, sedangkan File Indeks mencatat hasil pengelompokan vektor seperti jenis indeks, pusat klaster, dan vektor di setiap klaster.

indexfile file indeks

Secara umum, File Indeks berisi lebih banyak informasi daripada File Data Mentah, namun ukuran file jauh lebih kecil karena vektor disederhanakan dan dikuantifikasi selama proses pembuatan indeks (untuk jenis indeks tertentu).

Tabel yang baru dibuat secara default dicari dengan komputasi brute. Setelah indeks dibuat dalam sistem, Milvus akan secara otomatis membangun indeks untuk berkas gabungan yang mencapai ukuran 1 GB dalam sebuah thread mandiri. Ketika pembuatan indeks selesai, sebuah File Indeks baru akan dibuat. File data mentah akan diarsipkan untuk pembangunan indeks berdasarkan jenis indeks lainnya.

Milvus secara otomatis membangun indeks untuk file yang mencapai 1 GB:

buildindex buildindex

Pembuatan indeks selesai:

indexcomplete indexcomplete

Indeks tidak akan dibangun secara otomatis untuk berkas data mentah yang tidak mencapai 1 GB, yang dapat memperlambat kecepatan pencarian. Untuk menghindari situasi ini, Anda perlu melakukan pembangunan indeks secara manual untuk tabel ini.

forcebuild forcebuild

Setelah indeks dibuat secara paksa untuk berkas, kinerja pencarian akan meningkat pesat.

indexfinal indexfinal

(4) Meta Data

Seperti yang telah disebutkan sebelumnya, 100 juta vektor 512 dimensi disimpan dalam 200 file disk. Ketika indeks dibuat untuk vektor-vektor ini, akan ada 200 berkas indeks tambahan, yang membuat jumlah total berkas menjadi 400 (termasuk berkas disk dan berkas indeks). Mekanisme yang efisien diperlukan untuk mengelola meta data (status file dan informasi lainnya) dari file-file ini untuk memeriksa status file, menghapus atau membuat file.

Menggunakan basis data OLTP untuk mengelola informasi ini adalah pilihan yang baik. Milvus yang berdiri sendiri menggunakan SQLite untuk mengelola meta data sementara dalam penyebaran terdistribusi, Milvus menggunakan MySQL. Ketika server Milvus dimulai, 2 tabel (yaitu 'Tables' dan 'TableFiles') dibuat di SQLite/MySQL. 'Tables' mencatat informasi tabel dan 'TableFiles' mencatat informasi file data dan file indeks.

Seperti yang ditunjukkan pada diagram alir di bawah ini, 'Tables' berisi informasi meta data seperti nama tabel (table_id), dimensi vektor (dimension), tanggal pembuatan tabel (created_on), status tabel (state), jenis indeks (engine_type), dan jumlah cluster vektor (nlist) serta metode penghitungan jarak (metric_type).

Dan 'TableFiles' berisi nama tabel tempat file berada (table_id), jenis indeks file (engine_type), nama file (file_id), jenis file (file_type), ukuran file (file_size), jumlah baris (row_count), dan tanggal pembuatan file (created_on).

metadata metadata

Dengan meta data ini, berbagai operasi dapat dijalankan. Berikut ini adalah beberapa contohnya:

  • Untuk membuat sebuah tabel, Meta Manager hanya perlu mengeksekusi pernyataan SQL: INSERT INTO TABLES VALUES(1, 'table_2, 512, xxx, xxx, ...).
  • Untuk mengeksekusi pencarian vektor pada tabel_2, Meta Manager akan mengeksekusi sebuah query di SQLite/MySQL, yang merupakan sebuah pernyataan SQL de facto: SELECT * FROM TableFiles WHERE table_id='table_2' untuk mengambil informasi file dari tabel_2. Kemudian file-file ini akan dimuat ke dalam memori oleh Penjadwal Kueri untuk perhitungan pencarian.
  • Tidak diperbolehkan untuk menghapus tabel secara instan karena mungkin ada kueri yang sedang dieksekusi di dalamnya. Itulah mengapa ada penghapusan lunak dan penghapusan keras untuk sebuah tabel. Ketika Anda menghapus sebuah tabel, tabel tersebut akan diberi label 'soft-delete', dan tidak ada kueri atau perubahan lebih lanjut yang diizinkan untuk dilakukan pada tabel tersebut. Namun, kueri yang sedang berjalan sebelum penghapusan masih tetap berjalan. Hanya ketika semua kueri pra-penghapusan ini selesai, tabel, bersama dengan meta data dan file terkait, akan dihapus untuk selamanya.

(5) Penjadwal Kueri

Bagan di bawah ini menunjukkan proses pencarian vektor di CPU dan GPU dengan melakukan kueri pada file (file data mentah dan file indeks) yang disalin dan disimpan di disk, memori CPU dan memori GPU untuk vektor yang paling mirip dengan topk.

topkresult topkresult

Algoritma penjadwalan kueri secara signifikan meningkatkan kinerja sistem. Filosofi desain dasar adalah untuk mencapai kinerja pencarian terbaik melalui pemanfaatan sumber daya perangkat keras secara maksimal. Di bawah ini adalah penjelasan singkat tentang penjadwal kueri dan akan ada artikel khusus tentang topik ini di masa mendatang.

Kami menyebut kueri pertama terhadap tabel yang diberikan sebagai kueri 'dingin', dan kueri berikutnya sebagai kueri 'hangat'. Ketika kueri pertama dibuat terhadap tabel yang diberikan, Milvus melakukan banyak pekerjaan untuk memuat data ke dalam memori CPU, dan beberapa data ke dalam memori GPU, yang memakan waktu. Pada kueri selanjutnya, pencarian jauh lebih cepat karena sebagian atau semua data sudah berada di memori CPU sehingga menghemat waktu untuk membaca dari disk.

Untuk mempersingkat waktu pencarian query pertama, Milvus menyediakan konfigurasi Preload Table (preload_table) yang memungkinkan pemuatan tabel secara otomatis ke dalam memori CPU pada saat server dinyalakan. Untuk tabel yang berisi 100 juta vektor 512 dimensi, yang berukuran 200 GB, kecepatan pencarian akan menjadi yang tercepat jika ada cukup memori CPU untuk menyimpan semua data ini. Namun, jika tabel berisi vektor berskala miliaran, terkadang tidak dapat dihindari untuk mengosongkan memori CPU/GPU untuk menambahkan data baru yang tidak ditanyakan. Saat ini, kami menggunakan LRU (Latest Recently Used) sebagai strategi penggantian data.

Seperti yang ditunjukkan pada bagan di bawah ini, asumsikan ada sebuah tabel yang memiliki 6 file indeks yang tersimpan di dalam disk. Memori CPU hanya dapat menyimpan 3 berkas indeks, dan memori GPU hanya 1 berkas indeks.

Ketika pencarian dimulai, 3 file indeks akan dimuat ke dalam memori CPU untuk query. File pertama akan dilepaskan dari memori CPU segera setelah query dilakukan. Sementara itu, file ke-4 dimuat ke dalam memori CPU. Dengan cara yang sama, ketika sebuah file di-query di memori GPU, file tersebut akan langsung dilepaskan dan digantikan dengan file baru.

Penjadwal kueri terutama menangani 2 set antrian tugas, satu antrian tentang pemuatan data dan satu lagi tentang eksekusi pencarian.

queryschedule jadwal kueri

(6) Pengurang Hasil

Ada 2 parameter kunci yang terkait dengan pencarian vektor: satu adalah 'n' yang berarti n jumlah vektor target; satu lagi adalah 'k' yang berarti k vektor yang paling mirip. Hasil pencarian sebenarnya adalah n set KVP (pasangan nilai-kunci), masing-masing memiliki k pasangan nilai-kunci. Karena kueri perlu dieksekusi terhadap setiap file, baik itu file data mentah maupun file indeks, maka n set dari k set hasil teratas akan diambil untuk setiap file. Semua set hasil ini digabungkan untuk mendapatkan set hasil top-k dari tabel.

Contoh di bawah ini menunjukkan bagaimana kumpulan hasil digabungkan dan dikurangi untuk pencarian vektor terhadap tabel dengan 4 file indeks (n = 2, k = 3). Perhatikan bahwa setiap set hasil memiliki 2 kolom. Kolom kiri mewakili id vektor dan kolom kanan mewakili jarak Euclidean.

result hasil

(7) Pengoptimalan di Masa Depan

Berikut ini adalah beberapa pemikiran tentang kemungkinan optimasi manajemen data.

  • Bagaimana jika data dalam buffer yang tidak dapat diubah atau bahkan buffer yang dapat diubah juga dapat langsung di-query? Saat ini, data dalam buffer yang tidak dapat diubah tidak dapat di-query, tidak sampai data tersebut ditulis ke disk. Beberapa pengguna lebih tertarik pada akses data seketika setelah penyisipan.
  • Menyediakan fungsionalitas partisi tabel yang memungkinkan pengguna untuk membagi tabel yang sangat besar menjadi partisi yang lebih kecil, dan menjalankan pencarian vektor terhadap partisi yang diberikan.
  • Menambahkan beberapa atribut yang dapat difilter pada vektor. Sebagai contoh, beberapa pengguna hanya ingin mencari di antara vektor-vektor dengan atribut tertentu. Hal ini diperlukan untuk mengambil atribut vektor dan bahkan vektor mentah. Salah satu pendekatan yang memungkinkan adalah dengan menggunakan basis data KV seperti RocksDB.
  • Menyediakan fungsionalitas migrasi data yang memungkinkan migrasi otomatis data yang sudah ketinggalan zaman ke ruang penyimpanan lain. Untuk beberapa skenario di mana data mengalir setiap saat, data mungkin akan menua. Karena beberapa pengguna hanya peduli dan melakukan pencarian terhadap data bulan terakhir, data yang lebih tua menjadi kurang berguna namun menghabiskan banyak ruang disk. Mekanisme migrasi data membantu mengosongkan ruang disk untuk data baru.

Ringkasan

Artikel ini terutama memperkenalkan strategi manajemen data di Milvus. Artikel lain tentang penyebaran terdistribusi Milvus, pemilihan metode pengindeksan vektor, dan penjadwal kueri akan segera hadir. Nantikan terus!

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