Klien Redis yang fleksibel dan berfitur lengkap untuk PHP 7.2 dan yang lebih baru.
Rincian lebih lanjut tentang proyek ini dapat ditemukan di pertanyaan umum.
EVALSHA
atau EVAL
.SCAN
, SSCAN
, ZSCAN
dan HSCAN
(Redis >= 2.8) berdasarkan iterator PHP.Pustaka ini dapat ditemukan di Packagist untuk memudahkan pengelolaan dependensi proyek menggunakan Komposer. Arsip terkompresi dari setiap rilis tersedia di GitHub.
composer require predis/predis
Predis mengandalkan fitur autoloading PHP untuk memuat file-nya bila diperlukan dan mematuhi standar PSR-4. Pemuatan otomatis ditangani secara otomatis ketika dependensi dikelola melalui Komposer, namun dimungkinkan juga untuk memanfaatkan pemuat otomatisnya sendiri dalam proyek atau skrip yang tidak memiliki fasilitas pemuatan otomatis:
// Prepend a base path if Predis is not available in your "include_path".
require ' Predis/Autoloader.php ' ;
Predis Autoloader:: register ();
Saat membuat instance klien tanpa meneruskan parameter koneksi apa pun, Predis mengasumsikan 127.0.0.1
dan 6379
sebagai host dan port default. Batas waktu default untuk operasi connect()
adalah 5 detik:
$ client = new Predis Client ();
$ client -> set ( ' foo ' , ' bar ' );
$ value = $ client -> get ( ' foo ' );
Parameter koneksi dapat diberikan dalam bentuk string URI atau array bernama. Yang terakhir adalah cara yang lebih disukai untuk menyediakan parameter, namun string URI dapat berguna ketika parameter dibaca dari sumber yang tidak terstruktur atau terstruktur sebagian:
// Parameters passed using a named array:
$ client = new Predis Client ([
' scheme ' => ' tcp ' ,
' host ' => ' 10.0.0.1 ' ,
' port ' => 6379 ,
]);
// Same set of parameters, passed using an URI string:
$ client = new Predis Client ( ' tcp://10.0.0.1:6379 ' );
Server yang dilindungi kata sandi dapat diakses dengan menambahkan password
ke parameter yang ditetapkan. Ketika ACL diaktifkan di Redis >= 6.0, username
dan password
diperlukan untuk autentikasi pengguna.
Dimungkinkan juga untuk terhubung ke instance lokal Redis menggunakan soket domain UNIX, dalam hal ini parameternya harus menggunakan skema unix
dan menentukan jalur untuk file soket:
$ client = new Predis Client ([ ' scheme ' => ' unix ' , ' path ' => ' /path/to/redis.sock ' ]);
$ client = new Predis Client ( ' unix:/path/to/redis.sock ' );
Klien dapat memanfaatkan enkripsi TLS/SSL untuk terhubung ke instance Redis jarak jauh yang aman tanpa perlu mengonfigurasi proksi SSL seperti stunnel. Ini bisa berguna saat menghubungkan ke node yang berjalan di berbagai penyedia cloud hosting. Enkripsi dapat diaktifkan dengan menggunakan skema tls
dan serangkaian opsi yang sesuai yang diteruskan melalui parameter ssl
:
// Named array of connection parameters:
$ client = new Predis Client ([
' scheme ' => ' tls ' ,
' ssl ' => [ ' cafile ' => ' private.pem ' , ' verify_peer ' => true ],
]);
// Same set of parameters, but using an URI string:
$ client = new Predis Client ( ' tls://127.0.0.1?ssl[cafile]=private.pem&ssl[verify_peer]=1 ' );
Skema koneksi redis
(alias tcp
) dan rediss
(alias tls
) juga didukung, dengan perbedaan bahwa string URI yang berisi skema ini diurai mengikuti aturan yang dijelaskan pada dokumen registrasi sementara IANA masing-masing.
Daftar sebenarnya dari parameter koneksi yang didukung dapat bervariasi tergantung pada masing-masing backend koneksi sehingga disarankan untuk merujuk pada dokumentasi atau implementasi spesifiknya untuk mengetahui detailnya.
Predis dapat menggabungkan beberapa koneksi saat menyediakan serangkaian parameter koneksi dan opsi yang sesuai untuk menginstruksikan klien tentang cara menggabungkannya (pengelompokan, replikasi, atau logika agregasi khusus). Array bernama dan string URI dapat dicampur saat menyediakan konfigurasi untuk setiap node:
$ client = new Predis Client ([
' tcp://10.0.0.1?alias=first-node ' , [ ' host ' => ' 10.0.0.2 ' , ' alias ' => ' second-node ' ],
], [
' cluster ' => ' predis ' ,
]);
Lihat bagian koneksi agregat pada dokumen ini untuk detail selengkapnya.
Koneksi ke Redis bersifat lambat, artinya klien terhubung ke server hanya jika dan ketika diperlukan. Meskipun dianjurkan untuk membiarkan klien melakukan tugasnya sendiri, mungkin ada saatnya klien masih ingin memiliki kendali kapan koneksi dibuka atau ditutup: ini dapat dengan mudah dicapai dengan memanggil $client->connect()
dan $client->disconnect()
. Harap diperhatikan bahwa pengaruh metode ini pada koneksi agregat mungkin berbeda tergantung pada penerapan spesifik masing-masing.
Banyak aspek dan perilaku klien yang dapat dikonfigurasi dengan meneruskan opsi klien tertentu ke argumen kedua PredisClient::__construct()
:
$ client = new Predis Client ( $ parameters , [ ' prefix ' => ' sample: ' ]);
Opsi dikelola menggunakan wadah mirip DI mini dan nilainya dapat diinisialisasi dengan lambat hanya jika diperlukan. Opsi klien yang didukung secara default di Predis adalah:
prefix
: string awalan diterapkan ke setiap kunci yang ditemukan dalam perintah.exceptions
: apakah klien harus memberikan atau mengembalikan respons atas kesalahan Redis.connections
: daftar backend koneksi atau contoh pabrik koneksi.cluster
: menentukan backend cluster ( predis
, redis
atau callable).replication
: menentukan backend replikasi ( predis
, sentinel
atau callable).aggregate
: mengonfigurasi klien dengan koneksi agregat khusus (dapat dipanggil).parameters
: daftar parameter koneksi default untuk koneksi agregat.commands
: menentukan instance pabrik perintah untuk digunakan melalui perpustakaan.Pengguna juga dapat memberikan opsi khusus dengan nilai atau objek yang dapat dipanggil (untuk inisialisasi lambat) yang disimpan dalam wadah opsi untuk digunakan nanti melalui perpustakaan.
Koneksi agregat adalah landasan di mana Predis mengimplementasikan pengelompokan dan replikasi dan digunakan untuk mengelompokkan beberapa koneksi ke satu node Redis dan menyembunyikan logika spesifik yang diperlukan untuk menanganinya dengan benar tergantung pada konteksnya. Koneksi agregat biasanya memerlukan serangkaian parameter koneksi bersama dengan opsi klien yang sesuai saat membuat instance klien baru.
Predis dapat dikonfigurasi untuk bekerja dalam mode pengelompokan dengan pendekatan sharding sisi klien tradisional untuk membuat kluster node independen dan mendistribusikan keyspace di antara node tersebut. Pendekatan ini memerlukan semacam pemantauan kesehatan eksternal terhadap node dan memerlukan penyeimbangan ulang keyspace secara manual saat node ditambahkan atau dihapus:
$ parameters = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' cluster ' => ' predis ' ];
$ client = new Predis Client ( $ parameters );
Bersamaan dengan Redis 3.0, jenis clustering baru yang diawasi dan dikoordinasikan diperkenalkan dalam bentuk redis-cluster. Pendekatan semacam ini menggunakan algoritme berbeda untuk mendistribusikan ruang kunci, dengan node Redis mengoordinasikan dirinya sendiri dengan berkomunikasi melalui protokol gosip untuk menangani status kesehatan, penyeimbangan ulang, penemuan node, dan pengalihan permintaan. Untuk terhubung ke klaster yang dikelola oleh redis-cluster, klien memerlukan daftar node-nya (tidak harus lengkap karena secara otomatis akan menemukan node baru jika diperlukan) dan opsi klien cluster
diatur ke redis
:
$ parameters = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' cluster ' => ' redis ' ];
$ client = new Predis Client ( $ parameters , $ options );
Klien dapat dikonfigurasi untuk beroperasi dalam satu pengaturan master / beberapa budak untuk memberikan ketersediaan layanan yang lebih baik. Saat menggunakan replikasi, Predis mengenali perintah hanya-baca dan mengirimkannya ke budak acak untuk memberikan semacam penyeimbangan beban dan beralih ke master segera setelah mendeteksi perintah yang melakukan segala jenis operasi yang pada akhirnya akan memodifikasi keyspace atau nilai kunci. Alih-alih memunculkan kesalahan koneksi ketika seorang budak gagal, klien mencoba untuk kembali ke budak yang berbeda di antara yang disediakan dalam konfigurasi.
Konfigurasi dasar yang diperlukan untuk menggunakan klien dalam mode replikasi memerlukan satu server Redis untuk diidentifikasi sebagai master (hal ini dapat dilakukan melalui parameter koneksi dengan mengatur parameter role
ke master
) dan satu atau lebih budak (dalam hal ini mengatur role
menjadi slave
untuk budak adalah opsional):
$ parameters = [ ' tcp://10.0.0.1?role=master ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' replication ' => ' predis ' ];
$ client = new Predis Client ( $ parameters , $ options );
Konfigurasi di atas memiliki daftar server statis dan bergantung sepenuhnya pada logika klien, namun redis-sentinel
dapat diandalkan untuk lingkungan HA yang lebih kuat dengan server sentinel bertindak sebagai sumber otoritas bagi klien untuk penemuan layanan. Konfigurasi minimum yang diperlukan oleh klien untuk bekerja dengan redis-sentinel adalah daftar parameter koneksi yang menunjuk ke sekumpulan instance sentinel, opsi replication
disetel ke sentinel
, dan opsi service
disetel ke nama layanan:
$ sentinels = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' replication ' => ' sentinel ' , ' service ' => ' mymaster ' ];
$ client = new Predis Client ( $ sentinels , $ options );
Jika node master dan slave dikonfigurasi untuk memerlukan otentikasi dari klien, kata sandi harus diberikan melalui opsi klien parameters
global. Opsi ini juga dapat digunakan untuk menentukan indeks database yang berbeda. Array opsi klien akan terlihat seperti ini:
$ options = [
' replication ' => ' sentinel ' ,
' service ' => ' mymaster ' ,
' parameters ' => [
' password ' => $ secretpassword ,
' database ' => 10 ,
],
];
Sementara Predis mampu membedakan perintah yang melakukan operasi tulis dan baca-saja, EVAL
dan EVALSHA
mewakili kasus sudut di mana klien beralih ke node master karena tidak dapat mengetahui kapan skrip Lua aman untuk dieksekusi pada budak. Meskipun ini merupakan perilaku default, ketika skrip Lua tertentu tidak melakukan operasi tulis, dimungkinkan untuk memberikan petunjuk untuk memberitahu klien agar tetap menggunakan budak untuk eksekusinya:
$ parameters = [ ' tcp://10.0.0.1?role=master ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' replication ' => function () {
// Set scripts that won't trigger a switch from a slave to the master node.
$ strategy = new Predis Replication ReplicationStrategy ();
$ strategy -> setScriptReadOnly ( $ LUA_SCRIPT );
return new Predis Connection Replication MasterSlaveReplication ( $ strategy );
}];
$ client = new Predis Client ( $ parameters , $ options );
$ client -> eval ( $ LUA_SCRIPT , 0 ); // Sticks to slave using `eval`...
$ client -> evalsha ( sha1 ( $ LUA_SCRIPT ), 0 ); // ... and `evalsha`, too.
Direktori examples
berisi beberapa skrip yang menunjukkan bagaimana klien dapat dikonfigurasi dan digunakan untuk memanfaatkan replikasi dalam skenario dasar dan kompleks.
Pipelining dapat membantu kinerja ketika banyak perintah perlu dikirim ke server dengan mengurangi latensi yang ditimbulkan oleh pengaturan waktu bolak-balik jaringan. Pipelining juga berfungsi dengan koneksi agregat. Klien dapat mengeksekusi pipeline di dalam blok yang dapat dipanggil atau mengembalikan instance pipeline dengan kemampuan untuk merangkai perintah berkat antarmuka yang lancar:
// Executes a pipeline inside the given callable block:
$ responses = $ client -> pipeline ( function ( $ pipe ) {
for ( $ i = 0 ; $ i < 1000 ; $ i ++) {
$ pipe -> set ( " key: $ i " , str_pad ( $ i , 4 , ' 0 ' , 0 ));
$ pipe -> get ( " key: $ i " );
}
});
// Returns a pipeline that can be chained thanks to its fluent interface:
$ responses = $ client -> pipeline ()-> set ( ' foo ' , ' bar ' )-> get ( ' foo ' )-> execute ();
Klien menyediakan abstraksi untuk transaksi Redis berdasarkan MULTI
dan EXEC
dengan antarmuka yang mirip dengan alur perintah:
// Executes a transaction inside the given callable block:
$ responses = $ client -> transaction ( function ( $ tx ) {
$ tx -> set ( ' foo ' , ' bar ' );
$ tx -> get ( ' foo ' );
});
// Returns a transaction that can be chained thanks to its fluent interface:
$ responses = $ client -> transaction ()-> set ( ' foo ' , ' bar ' )-> get ( ' foo ' )-> execute ();
Abstraksi ini dapat melakukan operasi check-and-set berkat WATCH
dan UNWATCH
dan menyediakan percobaan ulang otomatis atas transaksi yang dibatalkan oleh Redis ketika tombol WATCH
disentuh. Untuk contoh transaksi menggunakan CAS dapat dilihat pada contoh berikut.
Meskipun kami mencoba memperbarui Predis agar selalu mengetahui semua perintah yang tersedia di Redis, Anda mungkin lebih memilih untuk tetap menggunakan pustaka versi lama atau memberikan cara berbeda untuk memfilter argumen atau mengurai respons untuk perintah tertentu. Untuk mencapai hal tersebut, Predis menyediakan kemampuan untuk mengimplementasikan kelas perintah baru untuk mendefinisikan atau mengganti perintah di pabrik perintah default yang digunakan oleh klien:
// Define a new command by extending PredisCommandCommand:
class BrandNewRedisCommand extends Predis Command Command
{
public function getId ()
{
return ' NEWCMD ' ;
}
}
// Inject your command in the current command factory:
$ client = new Predis Client ( $ parameters , [
' commands ' => [
' newcmd ' => ' BrandNewRedisCommand ' ,
],
]);
$ response = $ client -> newcmd ();
Ada juga metode untuk mengirim perintah mentah tanpa memfilter argumennya atau menguraikan respons. Pengguna harus memberikan daftar argumen untuk perintah sebagai array, mengikuti tanda tangan seperti yang ditentukan oleh dokumentasi Redis untuk perintah:
$ response = $ client -> executeRaw ([ ' SET ' , ' foo ' , ' bar ' ]);
Meskipun dimungkinkan untuk memanfaatkan skrip Lua di Redis 2.6+ menggunakan EVAL
dan EVALSHA
secara langsung, Predis menawarkan perintah skrip sebagai abstraksi tingkat lebih tinggi yang dibangun di atasnya untuk menyederhanakan segalanya. Perintah skrip dapat didaftarkan di pabrik perintah yang digunakan oleh klien dan dapat diakses seolah-olah perintah tersebut adalah perintah Redis biasa, namun perintah tersebut mendefinisikan skrip Lua yang dikirimkan ke server untuk eksekusi jarak jauh. Secara internal mereka menggunakan EVALSHA
secara default dan mengidentifikasi skrip dengan hash SHA1-nya untuk menghemat bandwidth, namun EVAL
digunakan sebagai cadangan bila diperlukan:
// Define a new script command by extending PredisCommandScriptCommand:
class ListPushRandomValue extends Predis Command ScriptCommand
{
public function getKeysCount ()
{
return 1 ;
}
public function getScript ()
{
return <<<LUA
math.randomseed(ARGV[1])
local rnd = tostring(math.random())
redis.call('lpush', KEYS[1], rnd)
return rnd
LUA ;
}
}
// Inject the script command in the current command factory:
$ client = new Predis Client ( $ parameters , [
' commands ' => [
' lpushrand ' => ' ListPushRandomValue ' ,
],
]);
$ response = $ client -> lpushrand ( ' random_values ' , $ seed = mt_rand ());
Predis dapat menggunakan backend koneksi yang berbeda untuk terhubung ke Redis. Integrasi Relay bawaan memanfaatkan ekstensi Relay untuk PHP untuk peningkatan kinerja yang besar, dengan menyimpan sebagian replika kumpulan data Redis dalam memori runtime bersama PHP.
$ client = new Predis Client ( ' tcp://127.0.0.1 ' , [
' connections ' => ' relay ' ,
]);
Pengembang dapat membuat kelas koneksi mereka sendiri untuk mendukung backend jaringan baru, memperluas kelas yang sudah ada, atau menyediakan implementasi yang benar-benar berbeda. Kelas koneksi harus mengimplementasikan PredisConnectionNodeConnectionInterface
atau memperluas PredisConnectionAbstractConnection
:
class MyConnectionClass implements Predis Connection NodeConnectionInterface
{
// Implementation goes here...
}
// Use MyConnectionClass to handle connections for the `tcp` scheme:
$ client = new Predis Client ( ' tcp://127.0.0.1 ' , [
' connections ' => [ ' tcp ' => ' MyConnectionClass ' ],
]);
Untuk wawasan yang lebih mendalam tentang cara membuat backend koneksi baru, Anda dapat merujuk pada implementasi sebenarnya dari kelas koneksi standar yang tersedia di namespace PredisConnection
.
Kontribusi pada Predis sangat dihargai baik dalam bentuk permintaan penarikan untuk fitur baru, perbaikan bug, atau sekadar laporan bug. Kami hanya meminta Anda untuk mematuhi templat permintaan penerbitan dan penarikan.
PERHATIAN : Jangan pernah menjalankan rangkaian pengujian yang dikirimkan bersama Predis terhadap instance Redis yang berjalan di lingkungan produksi atau berisi data yang Anda minati!
Predis memiliki rangkaian pengujian komprehensif yang mencakup setiap aspek perpustakaan dan secara opsional dapat melakukan pengujian integrasi terhadap instance Redis yang sedang berjalan (diperlukan >= 2.4.0 untuk memverifikasi perilaku implementasi setiap perintah yang benar. Pengujian integrasi untuk tidak didukung Perintah Redis dilewati secara otomatis. Jika Anda tidak menjalankan dan menjalankan Redis, pengujian integrasi dapat dinonaktifkan. Lihat pengujian README untuk detail lebih lanjut tentang pengujian pustaka ini.
Predis menggunakan GitHub Actions untuk integrasi berkelanjutan dan riwayat build sebelumnya dan saat ini dapat ditemukan di halaman tindakannya.
Kode untuk Predis didistribusikan berdasarkan ketentuan lisensi MIT (lihat LISENSI).