Redis
 sql >> Teknologi Basis Data >  >> NoSQL >> Redis

Bagaimana cara kerja PubSub di BookSleeve/ Redis?

1:hanya ada satu saluran dalam contoh Anda (Test ); saluran hanyalah nama yang digunakan untuk pertukaran pub/sub tertentu. Namun, perlu menggunakan 2 koneksi karena spesifik tentang cara kerja redis API. Sambungan yang memiliki apa saja langganan tidak dapat melakukan hal lain kecuali:

  • mendengarkan pesan
  • kelola langganannya sendiri (subscribe , subscribe , unsubscribe , punsubscribe )

Namun, saya tidak mengerti ini:

private static Dictionary<string, RedisSubscriberConnection>

Anda tidak perlu lebih dari satu koneksi pelanggan kecuali jika Anda melayani sesuatu yang spesifik untuk Anda. Koneksi pelanggan tunggal dapat menangani jumlah langganan yang berubah-ubah. Pemeriksaan cepat pada client list di salah satu server saya, dan saya memiliki satu koneksi dengan (pada saat penulisan) 23.002 langganan. Yang mungkin bisa dikurangi, tapi:berhasil.

2:langganan pola mendukung wildcard; jadi daripada berlangganan /topic/1 , /topic/2/ dll Anda dapat berlangganan /topic/* . Nama sebenarnya saluran yang digunakan oleh publish diberikan kepada penerima sebagai bagian dari tanda tangan panggilan balik.

Bisa bekerja. Perlu dicatat bahwa kinerja publish dipengaruhi oleh jumlah total langganan unik - tetapi sejujurnya itu masih sangat cepat (seperti dalam:0 md) bahkan jika Anda memiliki puluhan ribu saluran berlangganan menggunakan subscribe daripada psubscribe .

Tapi dari publish

Kompleksitas waktu:O(N+M) di mana N adalah jumlah klien yang berlangganan saluran penerima dan M adalah jumlah total pola berlangganan (oleh klien mana pun).

Saya sarankan membaca dokumentasi redis pub/sub.

Edit untuk mengikuti pertanyaan:

a) Saya berasumsi saya harus "memublikasikan" secara serempak (menggunakan Hasil atau Tunggu()) jika saya ingin menjamin urutan pengiriman item dari penerbit yang sama dipertahankan saat menerima item, benar?

itu tidak akan membuat perbedaan sama sekali; sejak Anda menyebutkan Result / Wait() , Saya berasumsi Anda sedang berbicara tentang BookSleeve - dalam hal ini multiplexer sudah mempertahankan urutan perintah. Redis sendiri adalah utas tunggal, dan akan selalu memproses perintah pada satu koneksi secara berurutan. Namun:panggilan balik pada pelanggan dapat dieksekusi secara asinkron dan dapat diserahkan (secara terpisah) ke utas pekerja. Saat ini saya sedang menyelidiki apakah saya dapat memaksa ini untuk diurutkan dari RedisSubscriberConnection .

Pembaruan:dari 1.3.22 dan seterusnya Anda dapat mengatur CompletionMode ke PreserveOrder - maka semua panggilan balik akan diselesaikan secara berurutan, bukan secara bersamaan.

b) setelah melakukan penyesuaian sesuai dengan saran Anda, saya mendapatkan kinerja yang luar biasa saat menerbitkan beberapa item terlepas dari ukuran muatannya. Namun, saat mengirim 100.000 item atau lebih oleh penerbit yang sama, kinerja turun dengan cepat (menjadi 7-8 detik hanya untuk mengirim dari mesin saya).

Pertama, waktu itu terdengar tinggi - pengujian secara lokal saya dapatkan (untuk 100.000 publikasi, termasuk menunggu tanggapan untuk semuanya) 1766ms (lokal) atau 1219ms (jarak jauh) (yang mungkin terdengar kontra-intuitif, tetapi "lokal" saya tidak' t menjalankan versi redis yang sama; "jarak jauh" saya adalah 2.6.12 di Centos; "lokal" saya adalah 2.6.8-pre2 di Windows).

Saya tidak dapat membuat server Anda yang sebenarnya lebih cepat atau mempercepat jaringan, tetapi:jika ini adalah fragmentasi paket, saya telah menambahkan (hanya untuk Anda) SuspendFlush() / ResumeFlush() pasangan. Ini menonaktifkan pembilasan bersemangat (yaitu ketika antrian kirim kosong; jenis pembilasan lain masih terjadi); Anda mungkin menemukan ini membantu:

conn.SuspendFlush();
try {
    // start lots of operations...
} finally {
    conn.ResumeFlush();
}

Perhatikan bahwa Anda tidak boleh Wait sampai Anda melanjutkan, karena sampai Anda memanggil ResumeFlush() mungkin ada beberapa operasi yang masih dalam buffer-kirim. Dengan semua itu, saya mendapatkan (untuk 100.000 operasi):

local: 1766ms (eager-flush) vs 1554ms (suspend-flush)
remote: 1219ms (eager-flush) vs 796ms (suspend-flush)

Seperti yang Anda lihat, ini membantu lebih banyak dengan server jarak jauh, karena akan menempatkan lebih sedikit paket melalui jaringan.

Saya tidak bisa menggunakan transaksi karena nanti barang yang akan diterbitkan tidak semuanya tersedia sekaligus. Apakah ada cara untuk mengoptimalkan dengan mempertimbangkan pengetahuan tersebut?

Saya berpikir yang ditangani oleh yang di atas - tetapi perhatikan bahwa baru-baru ini CreateBatch telah ditambahkan juga. Batch sangat mirip dengan transaksi - hanya:tanpa transaksi. Sekali lagi, ini adalah mekanisme lain untuk mengurangi fragmentasi paket. Dalam kasus khusus Anda, saya menduga menangguhkan/melanjutkan (saat flush) adalah pilihan terbaik Anda.

Apakah Anda merekomendasikan memiliki satu RedisConnection umum dan satu RedisSubscriberConnection atau konfigurasi lain agar pembungkus tersebut menjalankan fungsi yang diinginkan?

Selama Anda tidak melakukan operasi pemblokiran (blpop , brpop , brpoplpush dll), atau meletakkan Gumpalan besar di kabel (berpotensi menunda operasi lain saat dibersihkan), maka satu koneksi dari setiap jenis biasanya bekerja dengan cukup baik. Tapi YMMV tergantung pada kebutuhan penggunaan Anda.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Tidak dapat terhubung ke Redis di 127.0.0.1:6379:Koneksi ditolak

  2. Bagaimana saya bisa mendapatkan semua set di redis?

  3. Redis:Bagaimana cara memotong himpunan normal dengan himpunan yang diurutkan?

  4. Laravel Socket.io Terhubung tetapi tidak menerima data

  5. Redis / Dapatkan semua kunci &nilai dari redis dengan awalan