Bagikan melalui


Pilih kunci partisi untuk beban kerja IoT

BERLAKU UNTUK: NoSQL

Dalam panduan ini, kita menelusuri skenario dunia nyata yang menunjukkan cara memilih kunci partisi untuk aplikasi IoT menggunakan Azure Cosmos DB. Melalui kasus penggunaan ini, kita melihat bagaimana pilihan kunci partisi memengaruhi distribusi data, performa kueri, dan efisiensi aplikasi secara keseluruhan. Kami mengeksplorasi cara mengevaluasi strategi partisi yang berbeda berdasarkan persyaratan unik sistem IoT dan menerapkan praktik terbaik untuk mengoptimalkan performa Azure Cosmos DB.

Gambaran umum skenario

Bayangkan aplikasi IoT yang mengumpulkan data lingkungan dari ribuan perangkat IoT yang ditempatkan di berbagai zona perkotaan. Setiap perangkat mengukur parameter seperti suhu, kelembaban, kualitas udara, dan tingkat kebisingan setiap menit. Data yang dikumpulkan digunakan untuk pemantauan real time dan analisis historis untuk meningkatkan perencanaan kota dan kualitas hidup.

Detail Beban Kerja:

  • Perangkat: 50.000 sensor di 10 distrik
  • Data yang dikumpulkan: Setiap perangkat mencatat data setiap menit, menghasilkan sekitar 72 juta rekaman per hari.
  • Kueri umum:
    • Bacaan waktu nyata untuk perangkat tertentu

Contoh Dokumen:

{
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",      
    "districtId": "d12345",                           
    "deviceId": "s67890",
    "day": "2024-01-01"                             
    "timestamp": "2024-01-01T08:30",              
    "temperature": 22.5,                              
    "humidity": 55.2,                                 
    "airQualityIndex": 42,                            
    "noiseLevel": 35,                                 
    "location": {
        "latitude": 37.7749,                          
        "longitude": -122.4194                        
    },
    "batteryLevel": 88,                              
    "status": "active"                              
}

Pola Akses: Dalam skenario ini, kami mencatat data setiap detik, menjadikan aplikasi ini berat pada penulisan. Kami ingin mengoptimalkan strategi partisi kami untuk menyerap data pada throughput tinggi.

Untuk analitik real time (misalnya, menggabungkan data perangkat di seluruh distrik), kita dapat menjelajahi Azure Synapse Link.

Kunci partisi hierarkis

Penting untuk dicatat bahwa Azure Cosmos DB membatasi data per partisi logis hingga 20 GB. Dalam skenario kami, setiap perangkat mencatat data per detik. Rata-rata, ukuran dokumen kami sekitar 1 KB, jadi kami dijamin mencapai batas data 20 GB per ID perangkat selama setahun dengan mempartisi berdasarkan ID perangkat saja.

Untuk memastikan bahwa kami tidak pernah mengalami batas data 20 GB untuk SALAH SATU ID perangkat kami, kami dapat menggunakan kunci partisi hierarkis. Kita dapat mengatur dua tingkat berikut:

  • Tingkat Pertama: DeviceId (misalnya "s67890")
  • Tingkat Kedua: Tanda waktu (misalnya "2024-01-01T08:30")

Dengan menggunakan kunci partisi hierarkis, kita dapat melampaui batas data 20 GB per ID perangkat karena setiap partisi logis didefinisikan secara unik oleh kombinasi DeviceId dan Timestamp (tanggal/jam/menit, dalam hal ini). Dokumen dengan DeviceId yang sama (kunci tingkat pertama) ditempatkan pada partisi fisik yang sama, meminimalkan biaya fan-out untuk kueri berdasarkan DeviceId yang akan terjadi dengan kunci sintetis yang menggabungkan kedua properti ini.

Nota

Kami menggunakan tanda waktu sebagai kunci partisi tingkat kedua karena setiap perangkat akan selalu menghasilkan data kurang dari 20 GB per menit. Namun, jika beban kerja Anda berpotensi melebihi data 20 GB per menit, menggunakan Id properti (atau properti lain yang merupakan GUID) sebagai kunci tingkat kedua memastikan bahwa beban kerja Anda tetap dalam batas 20 GB per ID perangkat. Pendekatan ini menjamin bahwa penulisan tidak akan diblokir karena batas ukuran partisi.

Penting

Dalam skenario ini, ID perangkat memiliki 50.000 nilai unik. Kunci partisi hierarkis dengan tingkat pertama kardinalitas rendah tidak disarankan karena membatasi penyerapan data ke sejumlah partisi fisik yang terbatas. Kemacetan ini secara signifikan mengurangi throughput keseluruhan yang dapat dimanfaatkan oleh beban kerja Anda, yang mengarah ke kinerja yang tidak maksimal dan kemungkinan partisi panas di bawah beban tulis yang berat.

Meskipun strategi ini direkomendasikan, mari kita lihat juga opsi potensial lain yang sering dipertimbangkan pelanggan dan trade-off mereka.

Kunci partisi potensial lainnya dan kompromi

ID Perangkat

  • Pro: Pilihan ini mungkin berfungsi karena mengklusterkan data untuk setiap perangkat ke partisi logis yang sama dan akan mendistribusikan tulisan di banyak partisi fisik karena kami memiliki lebih dari 50.000 perangkat. Setiap kueri untuk data dari ID perangkat tertentu dioptimalkan. Sekarang, mereka dapat dilingkup ke partisi logis/fisik tertentu yang dirujuknya, menghindari kueri lintas partisi.

  • Kontra: Karena kami mencatat data perangkat setiap detik, satu perangkat menghasilkan ~ 31.536.000 rekaman per tahun. Mari kita asumsikan bahwa ukuran dokumen kita sekitar 1 KB. Total ukuran data selama satu tahun untuk satu perangkat adalah sekitar 30 GB. Dengan mempartisi berdasarkan ID perangkat, beban kerja kami dijamin akan mengalami batas kunci partisi logis ukuran data 20 GB untuk perangkat tertentu dalam waktu sekitar lima bulan. Setelah ini terjadi di Azure Cosmos DB, setiap operasi tulis di masa mendatang diblokir. Banyak kueri kami juga akan untuk distrik spesifik, dan pemartisian berdasarkan hanya ID perangkat akan menyebabkan penambahan 2-3 RU per detik untuk setiap partisi fisik yang kami kunjungi. 

Karena kami tidak ingin menghentikan operasi tulis untuk ID perangkat setelah mencapai data 20 GB, kami tidak boleh menggunakan ID perangkat sebagai kunci akhir. Dalam kasus di mana kami 100% yakin bahwa kami tidak akan pernah mengalami batas 20 GB, menggunakan ID perangkat sebagai kunci partisi adalah pilihan yang tepat. Namun, lebih aman untuk menggunakan kunci partisi hierarkis dengan kunci tingkat kedua adalah GUID atau nilai kardinalitas tinggi lainnya karena itu adalah jaminan 100% bahwa kita tidak akan pernah mencapai batas 20 GB.

Kunci berbasis waktu (bulan, tanggal, jam, dll.)

Granularitas kunci berbasis waktu berdampak langsung pada kardinalitas, dan hal ini memiliki kompromi. Misalnya, menggunakan granularitas tingkat bulan (misalnya, 2024-12) membatasi jumlah nilai kunci partisi hingga 12 per tahun. Pendekatan ini tidak disarankan, karena akan menyebabkan partisi panas, berdampak pada performa beban kerja.

Misalnya, beban kerja kami dikonfigurasi dengan 100.000 RU/dtk dan kami memiliki 10 partisi fisik yang masing-masing dapat menggunakan hingga 10K RU/dtk. Dengan mempartisi beban kerja kami dengan kunci berbasis waktu yang hanya mencakup bulan, semua penulisan selama bulan itu akan disalurkan ke dalam partisi logis dan fisik yang sama, membatasi throughput keseluruhan kami menjadi hanya 10K RU per detik, bukan 100K yang telah kami alokasikan.

Meningkatkan granularitas ke kunci tingkat hari (misalnya, 2024-12-18) menyebabkan penyebaran data kami ke banyak partisi fisik, tetapi penulisan untuk hari tertentu tetap disalurkan ke satu partisi logis, mengarah ke terjadinya partisi panas saat beban tulis berat. Selain partisi panas, beban kerja dijamin mencapai batas partisi logis 20 GB dengan menggunakan kunci ini karena semua data perangkat akan disalurkan ke dalam partisi logis yang sama, dan setiap ID perangkat saja dijamin mencapai batas 20 GB.

Untuk granularitas yang lebih halus, kunci berbasis stempel waktu (misalnya, 2024-12-18T10:00) mencakup bulan, hari, dan waktu (hingga jam atau menit). Pendekatan ini mengurangi kemungkinan partisi panas dan membantu Anda tetap berada dalam batas data 20 GB per nilai kunci partisi. Namun, semakin terperinci kunci partisi berbasis waktu, semakin tinggi kemungkinan kueri lintas partisi saat mengakses data melalui rentang waktu yang lebih luas.

Misalnya, mengkueri semua data perangkat untuk hari atau bulan tertentu akan menghasilkan kueri lintas partisi karena data didistribusikan di beberapa partisi logis. Karena kunci partisi mencakup jalur lengkap (misalnya, bulan, tanggal, jam, dan menit), data untuk satu hari tersebar di berbagai partisi logis dan beberapa fisik. Jadi, mengkueri semua data dalam hari tertentu memerlukan akses beberapa partisi fisik untuk mengambil himpunan data lengkap.

Penting

Kunci partisi berbasis waktu tidak disarankan:

  • Kunci berbasis waktu yang lebih terperinci menghindari mencapai batas partisi 20 GB tetapi dapat mengakibatkan peningkatan kueri lintas partisi jika kita meminta rentang waktu yang lebih luas (seperti data perangkat untuk tanggal tertentu).
  • Kunci yang kurang terperinci mengurangi kueri yang melintasi partisi berdasarkan tanggal, tetapi berisiko pada partisi yang kepanasan dan mencapai batas penyimpanan 20 GB.

Pilihan Anda harus selaras dengan pola akses aplikasi dan kebutuhan distribusi data Anda. Kami tidak ingin mengalami partisi panas, dan dengan mempartisi hanya pada kunci berbasis waktu, kami pasti akan mengalami hal ini karena beban kerja kami akan menulis ke satu partisi logis selama semua operasi tulis kami.

Kunci Sintetis: DeviceId + Kunci berbasis waktu (Tanggal + Jam + Menit)

  • Pro: Dengan menggunakan kunci sintetis yang menggabungkan ID perangkat dan kunci berbasis waktu dengan granularitas tanggal/jam/menit, penulisan didistribusikan di beberapa partisi logis. Pendekatan ini mencegah semua data perangkat terkonsentrasi dalam satu partisi logis dan fisik, seperti yang terjadi ketika partisi hanya oleh kunci berbasis waktu. Sebaliknya, penyertaan ID perangkat memastikan penulisan tersebar di banyak partisi logis, yang kemudian dipetakan ke beberapa partisi fisik, meningkatkan skalabilitas dan mengurangi risiko partisi panas. Kami juga kemungkinan besar tidak akan menghadapi batas partisi logis 20 GB karena kami menambahkan kunci yang berbasis waktu sebagai properti kedua pada kunci tersebut.

  • Kontra: Banyak kueri kami hanya difilter menurut DeviceId. Dengan kunci sintetis, ini akan menghasilkan kueri lintas partisi, yang mengarah ke biaya RU yang lebih tinggi (tambahan 2-3 RU per partisi fisik yang dipindai). Karena kunci partisi adalah kombinasi DeviceId dan Date/Hour/Minute, Azure Cosmos DB tidak dapat merutekan kueri ke satu partisi berdasarkan menentukan DeviceId saja.

Meskipun kunci partisi ini membantu kami melampaui batas 20 GB, kueri kami yang sering untuk data ID Perangkat tertentu membuat kunci partisi hierarkis lebih cocok. Kunci partisi hierarkis tidak hanya melewati batas 20 GB, tetapi juga menambahkan tingkat granularitas kedua dan ketiga, memungkinkan kueri hanya menargetkan partisi fisik yang relevan. Ini menghindari biaya fan-out yang terkait dengan kunci sintetis dan meningkatkan efisiensi query.

Pilihan kunci partisi akhir

Setelah mempertimbangkan beberapa opsi kunci partisi untuk sistem IoT kami, menggunakan kunci partisi hierarkis dengan DeviceId sebagai kunci tingkat pertama dan kunci berbasis Waktu karena kunci tingkat kedua tampaknya seperti pilihan terbaik. Pendekatan ini menawarkan keseimbangan terbaik antara distribusi data genap dan efisiensi kueri untuk kasus penggunaan kami.

Kami mengesampingkan DeviceId sebagai kunci partisi mandiri karena risiko tinggi melebihi batas 20 GB per partisi logis, mengingat seringnya penyerapan data dari lebih dari perangkat 50K. Demikian pula, partisi berbasis waktu akan memusatkan semua penulisan untuk periode waktu saat ini ke dalam satu partisi, menciptakan hambatan performa.

Dengan menggunakan DeviceId +Time-based-key (Date + Hour + Minute) sebagai kunci partisi hierarkis, kita dapat:

  • Distribusikan penulisan secara efisien di seluruh partisi fisik, mengurangi kemungkinan partisi panas.
  • Hindari batas ukuran data 20 GB per partisi logis dengan menggunakan beberapa tingkat partisi, memungkinkan kami untuk menskalakan sesuai kebutuhan.

Petunjuk / Saran

  • Sebaiknya tambahkan ID sebagai tingkat terakhir kunci partisi hierarkis Anda untuk memastikan Anda tidak pernah mencapai batas 20 GB untuk kunci partisi logis.
  • Optimalkan pola kueri kami yang paling umum yang sering difilter menurut DeviceId dan Tanggal/Jam/Menit, meminimalkan kueri lintas partisi dan mengurangi biaya RU.

Untuk informasi selengkapnya tentang cara kerja partisi di Azure Cosmos DB, Anda dapat mempelajari selengkapnya di sini.