Cara menggunakan Redis untuk aplikasi pengukuran waktu nyata

Roshan Kumar adalah manajer produk senior di Redis Labs .

Pengukuran bukan hanya masalah penghitungan sederhana. Pengukuran sering kali disalahartikan sebagai pengukuran, tetapi biasanya lebih dari itu. Pengukuran memang melibatkan pengukuran, tetapi sebagai proses yang berkelanjutan, biasanya dengan tujuan mengatur penggunaan atau aliran sumber daya dari waktu ke waktu. Aplikasi modern menggabungkan pengukuran dalam berbagai cara, mulai dari menghitung orang, objek, atau peristiwa hingga mengatur penggunaan, mengontrol akses, dan mengalokasikan kapasitas.

Solusi pengukuran umumnya harus memproses data dalam jumlah besar sambil memenuhi persyaratan kinerja yang ketat. Bergantung pada skala solusi, penghitungan dan pengukuran mungkin melibatkan ribuan jika tidak jutaan pembaruan ke database setiap detik. Persyaratan utama database untuk mendukung solusi tersebut adalah throughput yang tinggi untuk operasi tulis dan latensi rendah (sub-milidetik) untuk respons.

Redis, platform database dalam memori open source, memberikan kedua manfaat ini sekaligus hemat biaya dalam hal penggunaan sumber daya perangkat keras minimal. Dalam artikel ini, kami akan memeriksa fitur-fitur tertentu dari Redis yang menjadikannya pilihan yang baik untuk solusi pengukuran, dan bagaimana kami dapat menggunakan Redis untuk tujuan tersebut. Tapi pertama-tama, mari kita lihat beberapa penggunaan pengukuran yang lebih umum.

Aplikasi pengukuran umum

Pengukuran diperlukan dalam aplikasi apa pun yang harus mengukur penggunaan sumber daya dari waktu ke waktu. Berikut empat skenario umum:

  1. Model penetapan harga berbasis konsumsi . Tidak seperti model pembayaran satu kali atau berbasis langganan, model penetapan harga berbasis konsumsi memungkinkan konsumen membayar hanya untuk penggunaan sebenarnya. Konsumen menikmati fleksibilitas, kebebasan, dan penghematan biaya yang lebih besar sementara penyedia mendapatkan retensi konsumen yang lebih besar.

    Menerapkan model seperti itu bisa jadi rumit. Terkadang sistem pengukuran harus melacak banyak item penggunaan dan banyak metrik dalam satu rencana. Misalnya, penyedia cloud dapat menetapkan tingkat harga yang berbeda untuk siklus CPU, penyimpanan, throughput, jumlah node, atau lamanya layanan digunakan. Perusahaan telekomunikasi dapat menetapkan tingkat konsumsi yang dibolehkan untuk menit, data, atau teks. Solusi pengukuran harus memberlakukan pembatasan, penagihan, atau perluasan layanan bergantung pada jenis harga berbasis konsumsi.

  2. Membatasi pemanfaatan sumber daya . Setiap layanan di Internet dapat disalahgunakan melalui penggunaan yang berlebihan kecuali jika layanan tersebut dibatasi tarifnya. Layanan populer seperti Google AdWords API dan Twitter Stream API memasukkan batas tarif untuk alasan ini. Beberapa kasus penyalahgunaan yang ekstrem menyebabkan penolakan layanan (DoS). Untuk mencegah penyalahgunaan, layanan dan solusi yang dapat diakses di Internet harus dirancang dengan aturan pembatasan tarif yang tepat. Bahkan otentikasi sederhana dan halaman login harus membatasi jumlah percobaan ulang untuk interval waktu tertentu.

    Contoh lain di mana membatasi pemanfaatan sumber daya menjadi perlu adalah ketika mengubah persyaratan bisnis memberi beban lebih besar pada sistem lama daripada yang dapat mereka dukung. Tarif yang membatasi panggilan ke sistem lama memungkinkan bisnis untuk beradaptasi dengan permintaan yang terus meningkat tanpa perlu mengganti sistem lama mereka.

    Selain mencegah penyalahgunaan dan mengurangi beban, pembatasan kecepatan yang baik juga membantu pengelolaan skenario lalu lintas yang cepat. Misalnya, API yang menerapkan metode pembatasan kecepatan brute force dapat mengizinkan 1000 panggilan setiap jam. Tanpa kebijakan pembentukan lalu lintas, klien dapat memanggil API 1000 kali dalam beberapa detik pertama setiap jam, mungkin melebihi apa yang dapat didukung oleh infrastruktur. Algoritme pembatasan kecepatan yang populer seperti Token Bucket dan Leaky Bucket mencegah semburan dengan tidak hanya membatasi panggilan, tetapi juga mendistribusikannya dari waktu ke waktu.

  3. Distribusi sumber daya . Kemacetan dan penundaan adalah skenario umum dalam aplikasi yang menangani perutean paket, manajemen pekerjaan, kemacetan lalu lintas, kontrol kerumunan, olahpesan media sosial, pengumpulan data, dan sebagainya. Model antrian menawarkan beberapa opsi untuk mengelola ukuran antrian berdasarkan tingkat kedatangan dan keberangkatan, tetapi menerapkan model ini dalam skala besar tidaklah mudah.

    Backlog dan kemacetan adalah kekhawatiran konstan saat menangani aliran data yang cepat. Desainer yang cerdas perlu menentukan batas panjang antrian yang dapat diterima, sambil menggabungkan baik pemantauan kinerja antrian dan perutean dinamis berdasarkan ukuran antrian.

  4. Menghitung dalam skala besar untuk pengambilan keputusan waktu nyata . Situs e-niaga, aplikasi game, media sosial, dan aplikasi seluler menarik jutaan pengguna setiap hari. Karena lebih banyak bola mata menghasilkan pendapatan yang lebih besar, menghitung pengunjung dan tindakan mereka secara akurat sangat penting untuk bisnis. Penghitungan juga berguna untuk kasus penggunaan seperti percobaan ulang kesalahan, eskalasi masalah, pencegahan serangan DDoS, pembuatan profil lalu lintas, alokasi sumber daya sesuai permintaan, dan mitigasi penipuan.

Mengukur tantangan desain

Arsitek solusi harus mempertimbangkan banyak parameter saat membangun aplikasi pengukuran, dimulai dengan empat parameter berikut:

  1. Kompleksitas desain. Menghitung, melacak, dan mengatur volume data — terutama saat data tiba dengan kecepatan tinggi — adalah tugas yang menakutkan. Arsitek solusi dapat menangani pengukuran pada lapisan aplikasi dengan menggunakan struktur bahasa pemrograman. Namun, desain seperti itu tidak tahan terhadap kegagalan atau kehilangan data. Basis data berbasis disk tradisional kuat, dan menjanjikan tingkat ketahanan data yang tinggi selama kegagalan. Namun, mereka tidak hanya gagal dalam menyediakan kinerja yang diperlukan, mereka juga meningkatkan kompleksitas tanpa struktur data dan alat yang tepat untuk mengimplementasikan pengukuran.
  2. Latensi. Pengukuran biasanya melibatkan banyak pembaruan konstan pada hitungan. Latensi baca / tulis jaringan dan disk bertambah saat menangani jumlah besar. Ini bisa menjadi bola salju untuk membangun banyak sekali data yang menyebabkan lebih banyak penundaan. Sumber latensi lainnya adalah desain program yang memuat data pengukuran dari database ke memori utama program, dan menulis kembali ke database saat selesai memperbarui penghitung.
  3. Konkurensi dan konsistensi. Merancang solusi untuk menghitung jutaan dan miliaran item dapat menjadi rumit saat peristiwa ditangkap di berbagai wilayah, dan semuanya harus berkumpul di satu tempat. Konsistensi data menjadi masalah jika banyak proses atau utas memperbarui jumlah yang sama secara bersamaan. Teknik penguncian menghindari masalah konsistensi dan memberikan konsistensi tingkat transaksional, tetapi memperlambat solusi.
  4. Daya tahan. Pengukuran memengaruhi jumlah pendapatan, yang menyiratkan bahwa database singkat tidak ideal dalam hal daya tahan. Penyimpanan data dalam memori dengan opsi daya tahan adalah pilihan yang sempurna.

Menggunakan Redis untuk aplikasi pengukuran

Di bagian berikut, kita akan memeriksa cara menggunakan Redis untuk solusi penghitungan dan pengukuran. Redis memiliki struktur data bawaan, perintah atom, dan kapabilitas time-to-live (TTL) yang dapat digunakan untuk mendukung kasus penggunaan pengukuran. Redis berjalan di satu utas. Oleh karena itu, semua pembaruan basis data dibuat berseri, memungkinkan Redis berfungsi sebagai penyimpanan data tanpa kunci. Ini menyederhanakan desain aplikasi karena pengembang tidak perlu melakukan upaya apa pun untuk menyinkronkan utas atau menerapkan mekanisme penguncian untuk konsistensi data.  

Perintah Atomic Redis untuk menghitung

Redis menyediakan perintah untuk menambah nilai tanpa perlu membacanya ke memori utama aplikasi.

Perintah Deskripsi
INCR kunci Tingkatkan nilai integer kunci satu per satu
INCRBY kenaikan kunci Tingkatkan nilai integer kunci dengan angka yang diberikan
INCRBYFLOAT kenaikan kunci Naikkan nilai float dari sebuah kunci dengan jumlah yang diberikan
DECR kunci Mengurangi nilai integer kunci satu per satu
DECRBY penurunan kunci Mengurangi nilai integer dari sebuah kunci dengan angka yang diberikan
HINCRBY kenaikan bidang kunci Tingkatkan nilai integer dari bidang hash dengan angka yang ditentukan
HINCRBYFLOAT kenaikan bidang kunci Tingkatkan nilai float dari bidang hash dengan jumlah yang ditentukan

Redis menyimpan bilangan bulat sebagai bilangan bulat bertanda tangan 64-bit basis 10. Oleh karena itu batas maksimum untuk bilangan bulat adalah angka yang sangat besar: 263 - 1 = 9.223.372.036.854.775.807.

Time-to-live (TTL) bawaan pada kunci Redis

Salah satu kasus penggunaan umum dalam pengukuran adalah untuk melacak penggunaan terhadap waktu dan untuk membatasi sumber daya setelah waktu habis. Di Redis, seseorang dapat mengatur nilai time-to-live untuk kunci. Redis secara otomatis akan menonaktifkan kunci setelah batas waktu yang ditentukan. Tabel berikut mencantumkan beberapa metode kunci yang kedaluwarsa.

Perintah Deskripsi
EXPIRE detik-detik penting Tetapkan waktu kunci untuk hidup dalam hitungan detik
EXPIREAT cap waktu kunci Tetapkan kedaluwarsa untuk kunci sebagai stempel waktu Unix
PEXPIRE milidetik kunci Setel waktu kunci untuk hidup dalam milidetik
PEXPIREAT cap waktu kunci Setel kedaluwarsa untuk kunci sebagai stempel waktu UNIX dalam milidetik
SET nilai kunci [EX detik] [PX milidetik] Tetapkan nilai string ke kunci bersama dengan waktu opsional untuk hidup

Pesan di bawah ini memberi Anda waktu untuk mengaktifkan tombol dalam hitungan detik dan milidetik.

Perintah Deskripsi
TTL kunci Dapatkan waktu untuk hidup demi sebuah kunci
PTTL kunci Dapatkan waktu untuk hidup untuk kunci dalam milidetik

Redis struktur data dan perintah untuk penghitungan yang efisien

Redis disukai karena struktur datanya seperti List, Sets, Sorted Sets, Hashes, dan Hyperloglogs. Lebih banyak lagi yang dapat ditambahkan melalui API modul Redis.

Redis Labs

Struktur data Redis hadir dengan perintah bawaan yang dioptimalkan untuk dieksekusi dengan efisiensi maksimum dalam memori (tepat di tempat data disimpan). Beberapa struktur data membantu Anda mencapai lebih dari sekadar penghitungan objek. Misalnya, struktur data Set menjamin keunikan untuk semua elemen.

Set yang Disortir melangkah lebih jauh dengan memastikan bahwa hanya elemen unik yang ditambahkan ke set, dan memungkinkan Anda untuk memesan elemen berdasarkan skor. Mengurutkan elemen Anda berdasarkan waktu dalam struktur data Kumpulan yang Diurutkan, misalnya, akan menawarkan database deret waktu. Dengan bantuan perintah Redis Anda bisa mendapatkan elemen Anda dalam urutan tertentu, atau menghapus item yang tidak Anda perlukan lagi.

Hyperloglog adalah struktur data khusus lainnya yang memperkirakan jumlah jutaan item unik tanpa perlu menyimpan objek itu sendiri atau memengaruhi memori.

Struktur data Perintah Deskripsi
Daftar LLEN kunci Dapatkan panjang daftar
Set SCARD kunci Dapatkan jumlah anggota dalam satu set (kardinalitas)
Set yang Diurutkan ZCARD kunci Dapatkan jumlah anggota dalam set yang diurutkan
Set yang Diurutkan ZLEXCOUNT kunci min maks Hitung jumlah anggota dalam kumpulan yang diurutkan antara rentang leksikografis tertentu
Hash HLEN kunci Dapatkan jumlah bidang dalam hash
Hyperloglog PFCOUNT kunci Dapatkan perkiraan kardinalitas himpunan yang diamati oleh struktur data Hyperloglog
Bitmap BITCOUNT kunci [mulai akhir] Hitungan mengatur bit dalam sebuah string

Redis persistensi dan replikasi dalam memori

Kasus penggunaan pengukuran seperti pembayaran melibatkan penyimpanan dan pembaruan informasi yang penting bagi bisnis. Kehilangan data berdampak langsung pada pendapatan. Ini juga dapat merusak catatan penagihan, yang sering kali merupakan persyaratan kepatuhan atau tata kelola.

Anda dapat menyesuaikan konsistensi dan ketahanan di Redis berdasarkan kebutuhan data Anda. Jika Anda memerlukan bukti catatan permanen untuk data pengukuran Anda, Anda dapat mencapai ketahanan melalui kemampuan persistensi Redis. Redis mendukung AOF (append-only file), yang menyalin perintah tulis ke disk saat terjadi, dan snapshot, yang mengambil data sebagaimana adanya pada satu waktu dan menulisnya ke disk.

Arsitektur Redis built-in tanpa kunci

Pemrosesan Redis adalah single threaded; ini memastikan integritas data, karena semua perintah tulis secara otomatis dibuat berseri. Arsitektur ini membebaskan pengembang dan arsitek dari beban sinkronisasi utas dalam lingkungan multithread.

Dalam kasus aplikasi seluler konsumen yang populer, ribuan dan terkadang jutaan pengguna mungkin mengakses aplikasi secara bersamaan. Katakanlah aplikasi mengukur waktu yang digunakan, dan dua atau lebih pengguna dapat berbagi menit secara bersamaan. Utas paralel dapat memperbarui objek yang sama tanpa membebankan beban tambahan untuk memastikan integritas data. Ini mengurangi kerumitan desain aplikasi sekaligus memastikan kecepatan dan efisiensi.

Redis implementasi sampel pengukuran

Mari kita lihat kode contoh. Beberapa skenario di bawah ini akan memerlukan implementasi yang sangat kompleks jika database yang digunakan bukan Redis.

Memblokir beberapa upaya login

Untuk mencegah akses tidak sah ke akun, situs web terkadang memblokir pengguna dari melakukan beberapa upaya login dalam jangka waktu yang ditentukan. Dalam contoh ini, kami membatasi pengguna untuk melakukan lebih dari tiga upaya login dalam satu jam menggunakan fungsionalitas kunci waktu-ke-langsung yang sederhana.

Kunci untuk menahan jumlah upaya login:

upaya_login_pengguna:

Langkah:

Dapatkan jumlah upaya saat ini:

DAPATKAN upaya_login_pengguna:

Jika null, maka atur kunci dengan waktu kedaluwarsa dalam detik (1 jam = 3600 detik):

ATUR upaya_login_pengguna: 1 3600

Jika tidak nol dan jika hitungannya lebih besar dari 3, maka lemparkan kesalahan:

Jika tidak nol, dan jika hitungan kurang dari atau sama dengan 3, tambah hitungan:

Upaya_login_ pengguna INCR:

Setelah upaya login berhasil, kunci tersebut dapat dihapus sebagai berikut:

DEL upaya_login_pengguna:

Bayar sesuai yang anda pakai

Struktur data Redis Hash menyediakan perintah mudah untuk melacak penggunaan dan penagihan. Dalam contoh ini, anggap saja setiap pelanggan menyimpan data penagihan mereka dalam Hash, seperti yang ditunjukkan di bawah ini:

customer_billing:

     pemakaian

     biaya

     .

     .

Misalkan setiap unit berharga dua sen, dan pengguna mengonsumsi 20 unit. Perintah untuk memperbarui penggunaan dan penagihan adalah:

hincrby customer: penggunaan 20

hincrbyfloat customer: cost .40

Seperti yang mungkin telah Anda ketahui, aplikasi Anda dapat mengupdate informasi dalam database tanpa mengharuskannya memuat data dari database ke memorinya sendiri. Selain itu, Anda dapat memodifikasi bidang individual dari objek Hash tanpa membaca keseluruhan objek.

Harap diperhatikan: Tujuan dari contoh ini adalah untuk menunjukkan bagaimana menggunakan perintah hincrbydan hincrbyfloat. Dalam desain yang baik, Anda menghindari penyimpanan informasi yang berlebihan seperti penggunaan dan biaya.