Klien TairJedis memungkinkan Anda mengimplementasikan papan peringkat terdistribusi menggunakan struktur data exZset. Anda hanya perlu bekerja dengan satu kunci. Tair secara otomatis mendistribusikan data dan tugas komputasi di beberapa sub-kunci. Secara default, 10 sub-kunci digunakan, dan Anda tidak perlu mengelola detailnya. Solusi ini membantu Anda dengan mudah membuat papan peringkat dengan lebih dari 100.000 anggota serta menghindari kunci besar dan kunci panas.
Informasi latar belakang
Dua solusi tersedia untuk mengimplementasikan papan peringkat terdistribusi: metode peringkat presisi dan metode peringkat tidak presisi (interpolasi linear).
Tabel 1. Solusi untuk Mengimplementasikan Papan Peringkat Terdistribusi
Solusi | Deskripsi |
Peringkat presisi (direkomendasikan) | Distribusikan data ke berbagai kunci untuk komputasi. Saat Anda melakukan kueri, temukan peringkat data target di setiap kunci dan kemudian jumlahkan peringkat tersebut. Sebagai contoh, asumsikan Anda menggunakan tiga kunci dasar. Jika Anda membuat papan peringkat dan menyisipkan 3.000 anggota, Tair mendistribusikan anggota-anggota ini di tiga sub-papan peringkat. Untuk menemukan peringkat anggota x, operasi FindRank(x) menanyai tiga sub-papan peringkat. Jika peringkat yang dikembalikan adalah 124, 183, dan 156, peringkat sebenarnya dari anggota x adalah 463 (124 + 183 + 156).
|
Interpolasi linear (belum diimplementasikan dalam exZset) | Metode ini membagi data menjadi segmen-segmen. Ini mencatat jumlah anggota dan peringkat tertinggi untuk setiap segmen. Untuk skor yang berada di antara nilai terendah dan tertinggi dalam sebuah segmen, interpolasi linear digunakan untuk memperkirakan peringkat.
|
Solusi ini mengimplementasikan papan peringkat terdistribusi menggunakan metode peringkat presisi. Untuk informasi lebih lanjut tentang perintah exZset yang digunakan dalam solusi ini, lihat exZset.
Contoh kode
Solusi ini memerlukan klien TairJedis, yang dikembangkan oleh Tair.
Tambahkan konfigurasi pom.xml.
<dependency> <groupId>com.aliyun.tair</groupId> <artifactId>alibabacloud-tairjedis-sdk</artifactId> <version>5.3.1</version> </dependency>Contoh kode.
import io.valkey.JedisPool; import io.valkey.JedisPoolConfig; import com.aliyun.tair.tairzset.*; public class DistributedLeaderBoardExample { // Konfigurasikan endpoint instans, port, kata sandi, dan informasi lainnya. private static final int DEFAULT_CONNECTION_TIMEOUT = 5000; private static final int DEFAULT_SO_TIMEOUT = 2000; private static final String HOST = "<r-bp1mx0ydsivrbp****.redis.rds.aliyuncs.com>"; private static final int PORT = 6379; private static final String PASSWORD = "<Pass****word>"; private static final JedisPoolConfig config = new JedisPoolConfig(); // Konfigurasikan papan peringkat terdistribusi. private static final int shardKeySize = 10; // Jumlah sub-papan peringkat dasar. private static final int pageSize = 10; // Jumlah anggota di setiap halaman papan peringkat. private static final boolean reverse = true; // Dalam contoh ini, anggota diurutkan secara menurun. private static final boolean useZeroIndexForRank = false; // Dalam contoh ini, peringkat dimulai dari 1. public static void main(String[] args) { JedisPool jedisPool = new JedisPool(config, HOST, PORT, DEFAULT_CONNECTION_TIMEOUT, DEFAULT_SO_TIMEOUT, PASSWORD, 0, null); // Buat papan peringkat terdistribusi. Dalam contoh ini, kunci diberi nama distributed_leaderboard. DistributedLeaderBoard dlb = new DistributedLeaderBoard("distributed_leaderboard", jedisPool, shardKeySize, pageSize, reverse, useZeroIndexForRank); // Jika jumlah medali emas sama, urutkan berdasarkan jumlah medali perak. Jika jumlah medali perak juga sama, urutkan berdasarkan jumlah medali perunggu. // Emas Perak Perunggu dlb.addMember("A", 32, 21, 16); dlb.addMember("D", 14, 4, 16); dlb.addMember("C", 20, 7, 12); dlb.addMember("B", 25, 29, 21); dlb.addMember("E", 13, 21, 18); dlb.addMember("F", 13, 17, 14); // Dapatkan peringkat A. dlb.rankFor("A"); // 1 System.out.println(dlb.rankFor("A")); // Dapatkan 3 teratas. dlb.top(3); System.out.println(dlb.top(3)); // [{"member":"A","score":"32#21#16","rank":1}, // {"member":"B","score":"25#29#21","rank":2}, // {"member":"C","score":"20#7#12","rank":3}] } }Parameter:
Parameter
Tipe
Deskripsi
shardKeySize
int
Jumlah sub-papan peringkat dasar. Nilai default adalah 10. Angka ini tidak dapat diskalakan secara dinamis. Rencanakan angka ini pada fase awal layanan Anda.
pageSize
int
Jumlah anggota di setiap halaman papan peringkat. Nilai default adalah 10.
reverse
boolean
Nilai valid:
false (default): Mengurutkan secara menaik.
true: Mengurutkan secara menurun.
useZeroIndexForRank
boolean
Nilai valid:
true (default): Peringkat dimulai dari 0.
false: Peringkat dimulai dari 1.
Untuk operasi lebih lanjut, lihat kelas com.aliyun.tair.tairzset.DistributedLeaderBoard di alibabacloud-tairjedis-sdk.
Lampiran: Perbandingan antara papan peringkat konvensional dan terdistribusi
Tabel berikut membandingkan implementasi fitur dasar untuk papan peringkat konvensional dan terdistribusi.
Fitur dasar | Papan peringkat konvensional | Papan peringkat terdistribusi | ||
Implementasi | Kompleksitas waktu | Implementasi | Kompleksitas waktu | |
Masukkan anggota | Gunakan EXZADD untuk menyisipkan elemen. | O(log(N)) | Hitung kunci target menggunakan | O(log(N)) |
Perbarui skor anggota | Gunakan EXZINCRBY untuk memperbarui skor. | O(log(N)) | Hitung kunci target menggunakan | O(log(N)) |
Hapus anggota | Gunakan EXZREM untuk menghapus anggota. | O(M*log(N)) | Hitung kunci target menggunakan | O(log(N)) |
Kueri jumlah anggota | Gunakan EXZCARD untuk menanyakan jumlah anggota. | O(1) | Gunakan EXZCARD untuk menanyakan jumlah anggota di setiap sub-kunci, dan kemudian jumlahkan hasilnya. | O(m) Catatan Dalam kolom ini, m menunjukkan jumlah shard. |
Kueri jumlah total halaman | Gunakan EXZCARD untuk menanyakan jumlah anggota, dan kemudian bagi hasilnya dengan PAGE_SIZE (jumlah rekaman per halaman). | O(1) | Gunakan EXZCARD untuk menanyakan jumlah anggota di setiap sub-kunci, jumlahkan hasilnya, dan kemudian bagi totalnya dengan PAGE_SIZE (jumlah rekaman per halaman). | O(m) |
Jumlah total anggota dalam rentang skor | Gunakan EXZCOUNT untuk menanyakan. | O(log(N)) | Jalankan EXZCOUNT pada setiap sub-kunci, dan kemudian gabungkan hasilnya. | m × O(log(N)) |
Hapus anggota dalam rentang skor | Gunakan EXZREMRANGEBYSCORE untuk menghapus anggota. | O(log(N)+M) | Jalankan EXZREMRANGEBYSCORE pada setiap sub-kunci. | m × O(log(N)) |
Dapatkan skor anggota | Gunakan EXZSCORE untuk menanyakan. | O(1) | Hitung kunci target menggunakan | O(1) |
Dapatkan peringkat anggota | Gunakan EXZRANK untuk menanyakan. | O(log(N)) | Panggil EXZRANKBYSCORE pada setiap sub-kunci, dan kemudian jumlahkan hasilnya. | m × O(log(N)) |
Dapatkan skor dan peringkat anggota secara bersamaan | Gunakan EXZSCORE dan EXZRANK untuk menanyakan. | O(log(N)) |
| m × O(log(N)) |
Kueri anggota teratas ke-i | Gunakan EXZRANGE untuk menanyakan. | O(log(N)+M) | Gunakan EXZRANGE untuk menanyakan anggota teratas ke-i dari setiap sub-kunci, dan kemudian gabungkan hasilnya untuk menemukan anggota teratas ke-i akhir. | m × O(log(N)) |
Dapatkan halaman i dari papan peringkat | Gunakan EXZRANGE untuk menanyakan. | O(log(N)) | Ambil semua anggota sebelum halaman target dari setiap sub-kunci, dan kemudian urutkan mereka untuk mendapatkan halaman akhir. | m × O(log(N)) |
Setel waktu kedaluwarsa | Gunakan EXPIRE untuk menyetel waktu. | O(1) | Setel waktu kedaluwarsa untuk setiap sub-kunci. | O(m) |
Hapus papan peringkat | Gunakan DEL untuk menghapus. | O(N) | Hapus masing-masing sub-kunci. | m × O(N) |