Penulisan data

Line protocol dan jalur penulisan, disertai disiplin batching.

Daftar isi

Penulisan data pada InfluxDB 3.x tetap menggunakan line protocol sebagai format bawaan, sehingga jalur ingestion yang sudah dibangun pada era 1.x dan 2.x dapat dipertahankan, meskipun mesin di belakangnya berubah. Topik ini membahas anatomi line protocol, jalur penulisan HTTP API pada 3.x, serta disiplin batching yang menentukan apakah throughput ingestion tinggi dapat dicapai atau justru terjebak pada overhead per request. Setelah membaca topik ini, sebuah client penulisan sederhana dapat dirancang dengan ukuran batch dan presisi cap waktu yang tepat.

Anatomi line protocol#

Line protocol adalah format tekstual satu baris per titik data, dengan tiga bagian yang dipisahkan oleh spasi. Bagian pertama adalah measurement dan tag yang dipisahkan koma, bagian kedua adalah pasangan field yang dipisahkan koma, dan bagian ketiga adalah cap waktu dalam presisi nanodetik sebagai bilangan bulat. Spasi adalah pemisah yang signifikan, sehingga tidak boleh ada spasi di sekitar tanda sama dengan atau di dalam pasangan tag. Sebuah baris suhu,sensor_id=S01 nilai=24.06 1735689600000000000 memuat measurement suhu, satu tag sensor_id dengan nilai S01, satu field nilai dengan nilai 24.06, serta cap waktu nanodetik.

Tipe data field ditandai oleh sufiks. Bilangan bulat diberi sufiks i, misalnya jumlah=5i, sedangkan bilangan desimal ditulis apa adanya. String diberi tanda kutip ganda, misalnya status="ok", dan boolean ditulis sebagai t atau f. Tipe yang tidak ditandai dengan benar diterjemahkan menjadi float secara default, sehingga bilangan bulat yang seharusnya tetap bulat dapat tersimpan sebagai float apabila sufiks i dilupakan. Diagram berikut memperlihatkan bagian-bagian line protocol dalam satu pandangan.

Satu baris line protocolsuhu,sensor_id=S01 nilai=24.06 1735689600000000000measurement + tagmeasurement: suhutag sensor_id=S01dipisahkan komafieldnilai=24.06float (default)5i → integertimestamp1735689600000000000nanodetik (default)presisi diatur di endpoint (?precision=ns|us|ms|s)
Tiga bagian line protocol: measurement+tag, field, dan timestamp, dipisahkan oleh spasi

Jalur penulisan HTTP API#

InfluxDB 3.x menerima penulisan melalui HTTP API pada endpoint /api/v3/write_lp. Nama database diberikan sebagai parameter kueri db, presisi cap waktu sebagai precision dengan nilai ns, us, ms, atau s, dan autentikasi melalui header Authorization: Bearer <token>. Body permintaan adalah line protocol mentah dengan Content-Type: text/plain; charset=utf-8, sehingga client tidak perlu membangun JSON apa pun. Endpoint ini menggantikan /api/v2/write dari era 2.x, walaupun sebagian besar client library lama masih dapat diarahkan ke endpoint baru dengan perubahan konfigurasi kecil. Contoh perintah berikut tidak dijalankan di sandbox karena tidak ada server influx yang berjalan.

bash Penulisan satu titik ke InfluxDB 3.x dengan curl
# tidak-dijalankan
# set token (dilewati bila server berjalan dengan --without-auth)
INFLUX_TOKEN=${INFLUX_TOKEN:-devtoken}

# tulis satu baris line protocol ke database 'telemetri'
curl --silent --show-error --request POST \
  "http://localhost:8181/api/v3/write_lp?db=telemetri&precision=ns" \
  --header "Authorization: Bearer $INFLUX_TOKEN" \
  --header "Content-Type: text/plain; charset=utf-8" \
  --data-binary "suhu,sensor_id=S01 nilai=24.06 1735689600000000000"

Respons sukses berisi kode HTTP 204 tanpa body, sehingga client dapat segera mengirim batch berikutnya. Respons yang bukan 204 biasanya memuat pesan yang menjelaskan baris mana yang gagal diparsing, sehingga debugging tetap dapat dilakukan walaupun batch berisi ribuan baris. Karena endpoint menerima banyak baris dalam satu permintaan, throughput tertinggi tidak dicapai dengan menulis satu baris per request, melainkan dengan mengumpulkan banyak baris menjadi satu batch.

Disiplin batching#

Batching adalah keputusan operasional yang menentukan apakah penulisan cepat atau lambat. Setiap permintaan HTTP membawa overhead, yaitu pembentukan koneksi, pengiriman header, parsing di sisi server, dan respons kembali, sehingga menulis satu baris per permintaan membuat sebagian besar waktu habis pada overhead, bukan pada data. Sebaliknya, batch yang terlalu besar membebani memori client dan server, serta memperlambat pemulihan bila satu batch gagal. Skrip berikut menghitung overhead sebagai fungsi dari ukuran batch dengan model sederhana, agar pembaca dapat melihat mengapa batch berukuran ribuan baris menjadi praktik lazim.

python bandingkan_batch.py
"""Bandingkan overhead penulisan line protocol pada berbagai ukuran batch.

Skrip ini tidak mengirim HTTP apa pun dan tidak menjalankan influx. Tujuannya
memperlihatkan secara mekanis mengapa ukuran batch berpengaruh pada throughput:
setiap permintaan HTTP membawa overhead tetap (header, koneksi, parsing respons),
sehingga batch kecil membuat sebagian besar byte yang dikirim adalah overhead.
"""

# Satu baris line protocol contoh, sekitar 51 byte termasuk newline.
BARIS = "suhu,sensor_id=S01 nilai=24.06 1735689600000000000\n"

# Perkiraan overhead per permintaan HTTP pada InfluxDB 3.x:
# baris permintaan, header Host, Authorization, Content-Type, Accept, dan
# baris kosong -- total sekitar 220 byte (angka kasar untuk ilustrasi).
OVERHEAD_PER_REQUEST = 220


def total_byte(n_titik: int, ukuran_batch: int) -> int:
    if ukuran_batch < 1:
        ukuran_batch = 1
    n_request = (n_titik + ukuran_batch - 1) // ukuran_batch
    payload = n_titik * len(BARIS)
    overhead = n_request * OVERHEAD_PER_REQUEST
    return payload + overhead


def main() -> None:
    N = 100_000  # seratus ribu titik
    print(f"skenario: {N:,} titik line protocol ({len(BARIS)} byte per baris)")
    print(f"overhead per request: ~{OVERHEAD_PER_REQUEST} byte (header + parsing)")
    print()
    print(f"{'ukuran batch':>14} | {'# request':>10} | {'payload':>10} | {'overhead':>10} | {'total':>10} | {'% overhead':>10}")
    print("-" * 78)
    for ukuran in (1, 10, 100, 1000, 10_000):
        n_req = (N + ukuran - 1) // ukuran
        payload = N * len(BARIS)
        overhead = n_req * OVERHEAD_PER_REQUEST
        total = payload + overhead
        pct = overhead / total * 100
        print(f"{ukuran:>14,} | {n_req:>10,} | {payload:>10,} | {overhead:>10,} | {total:>10,} | {pct:>9.1f}%")


if __name__ == "__main__":
    main()
text Keluaran
skenario: 100,000 titik line protocol (51 byte per baris)
overhead per request: ~220 byte (header + parsing)

  ukuran batch |  # request |    payload |   overhead |      total | % overhead
------------------------------------------------------------------------------
             1 |    100,000 |  5,100,000 | 22,000,000 | 27,100,000 |      81.2%
            10 |     10,000 |  5,100,000 |  2,200,000 |  7,300,000 |      30.1%
           100 |      1,000 |  5,100,000 |    220,000 |  5,320,000 |       4.1%
         1,000 |        100 |  5,100,000 |     22,000 |  5,122,000 |       0.4%
        10,000 |         10 |  5,100,000 |      2,200 |  5,102,200 |       0.0%

Keluaran di atas memperlihatkan bahwa pada ukuran batch 1, overhead mencapai 81 persen dari total byte yang dikirim, sehingga sebagian besar bandwidth habis pada header HTTP dan bukan pada data. Pada ukuran batch 1000, overhead turun menjadi 0,4 persen, sehingga payload menjadi hampir seluruh byte yang dikirim. Pada ukuran batch 10.000, overhead praktis hilang, tetapi ukuran batch sebesar ini membebani memori client dan memperlambat pemulihan bila satu batch gagal, sehingga batch ribuan baris menjadi praktik lazim, bukan batch puluhan ribu.

Kesalahan umum#

  • Menulis satu baris per permintaan dengan harapan mendapatkan latensi rendah. Hasilnya justru sebaliknya, sebab overhead HTTP per request mendominasi, sehingga throughput jatuh beberapa kali lipat dibanding batch 1000 baris.
  • Lupa memberi sufiks i pada field bilangan bulat. Akibatnya nilai disimpan sebagai float, sehingga jumlah=5 menjadi 5.0, dan perbandingan tipe serta agregasi menjadi berbeda dari yang diharapkan.
  • Mencampur presisi cap waktu dalam satu batch, misalnya sebagian baris menggunakan nanodetik dan sebagian milidetik, tanpa mengatur precision di endpoint. Server menganggap seluruh baris menggunakan presisi yang sama, sehingga sebagian cap waktu salah beberapa ordo magnitudo.

Ringkasan#

  • Line protocol tetap menjadi format penulisan bawaan InfluxDB 3.x, dengan tiga bagian yang dipisahkan spasi: measurement+tag, field, dan cap waktu.
  • Endpoint HTTP /api/v3/write_lp menerima line protocol mentah dengan parameter db dan precision, serta autentikasi melalui bearer token.
  • Batching menentukan throughput, sebab overhead per request HTTP tetap, sehingga batch 1000 baris membuat overhead turun ke under satu persen, sedangkan batch 1 baris membuat overhead mencapai 80 persen.

Referensi#