عميل Redis مرن ومتكامل الميزات لـ PHP 7.2 والأحدث.
يمكن العثور على مزيد من التفاصيل حول هذا المشروع على الأسئلة المتداولة.
EVALSHA
أو EVAL
.SCAN
و SSCAN
و ZSCAN
و HSCAN
(Redis >= 2.8) استنادًا إلى مكررات PHP.يمكن العثور على هذه المكتبة على Packagist لتسهيل إدارة تبعيات المشاريع باستخدام Composer. تتوفر الأرشيفات المضغوطة لكل إصدار على GitHub.
composer require predis/predis
يعتمد Predis على ميزات التحميل التلقائي لـ PHP لتحميل ملفاته عند الحاجة ويتوافق مع معيار PSR-4. تتم معالجة التحميل التلقائي تلقائيًا عندما تتم إدارة التبعيات من خلال Composer، ولكن من الممكن أيضًا الاستفادة من أداة التحميل التلقائي الخاصة به في المشاريع أو البرامج النصية التي تفتقر إلى أي أداة تحميل تلقائي:
// Prepend a base path if Predis is not available in your "include_path".
require ' Predis/Autoloader.php ' ;
Predis Autoloader:: register ();
عند إنشاء نسخة عميل دون تمرير أي معلمة اتصال، يفترض Predis أن 127.0.0.1
و 6379
هما المضيف والمنفذ الافتراضيان. المهلة الافتراضية لعملية connect()
هي 5 ثوانٍ:
$ client = new Predis Client ();
$ client -> set ( ' foo ' , ' bar ' );
$ value = $ client -> get ( ' foo ' );
يمكن توفير معلمات الاتصال إما في شكل سلاسل URI أو صفائف مسماة. الطريقة الأخيرة هي الطريقة المفضلة لتوفير المعلمات، ولكن يمكن أن تكون سلاسل URI مفيدة عند قراءة المعلمات من مصادر غير منظمة أو منظمة جزئيًا:
// 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 ' );
يمكن الوصول إلى الخوادم المحمية بكلمة مرور عن طريق إضافة password
إلى مجموعة المعلمات. عندما يتم تمكين قوائم ACL على Redis >= 6.0، يكون username
وكلمة password
مطلوبين لمصادقة المستخدم.
من الممكن أيضًا الاتصال بمثيلات Redis المحلية باستخدام مآخذ توصيل مجال UNIX، وفي هذه الحالة يجب أن تستخدم المعلمات نظام unix
وتحدد مسارًا لملف المقبس:
$ client = new Predis Client ([ ' scheme ' => ' unix ' , ' path ' => ' /path/to/redis.sock ' ]);
$ client = new Predis Client ( ' unix:/path/to/redis.sock ' );
يمكن للعميل الاستفادة من تشفير TLS/SSL للاتصال بمثيلات Redis البعيدة الآمنة دون الحاجة إلى تكوين وكيل SSL مثل Stunnel. يمكن أن يكون هذا مفيدًا عند الاتصال بالعقد التي تعمل على موفري الاستضافة السحابية المختلفين. يمكن تمكين التشفير باستخدام نظام tls
ومجموعة من الخيارات المناسبة التي يتم تمريرها عبر معلمة 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 ' );
يتم أيضًا دعم أنظمة الاتصال redis
(الاسم المستعار لـ tcp
) و rediss
(الاسم المستعار لـ tls
) مع الفارق المتمثل في تحليل سلاسل URI التي تحتوي على هذه المخططات باتباع القواعد الموضحة في وثائق التسجيل المؤقتة لـ IANA الخاصة بها.
يمكن أن تختلف القائمة الفعلية لمعلمات الاتصال المدعومة اعتمادًا على كل واجهة خلفية للاتصال، لذا يوصى بالرجوع إلى وثائقها المحددة أو تنفيذها للحصول على التفاصيل.
يمكن لـ Predis تجميع اتصالات متعددة عند توفير مجموعة من معلمات الاتصال والخيار المناسب لإرشاد العميل حول كيفية تجميعها (التجميع أو النسخ المتماثل أو منطق التجميع المخصص). يمكن خلط المصفوفات المُسمّاة وسلاسل URI عند توفير التكوينات لكل عقدة:
$ client = new Predis Client ([
' tcp://10.0.0.1?alias=first-node ' , [ ' host ' => ' 10.0.0.2 ' , ' alias ' => ' second-node ' ],
], [
' cluster ' => ' predis ' ,
]);
راجع قسم الاتصالات المجمعة في هذا المستند لمزيد من التفاصيل.
الاتصالات بـ Redis كسولة مما يعني أن العميل يتصل بالخادم فقط عند الحاجة. على الرغم من أنه يوصى بالسماح للعميل بالقيام بأشياءه الخاصة تحت الغطاء، فقد تكون هناك أوقات لا يزال فيها من المرغوب فيه التحكم في وقت فتح الاتصال أو إغلاقه: يمكن تحقيق ذلك بسهولة عن طريق استدعاء $client->connect()
و $client->disconnect()
. يرجى ملاحظة أن تأثير هذه الطرق على الاتصالات المجمعة قد يختلف اعتمادًا على كل تطبيق محدد.
يمكن تكوين العديد من جوانب وسلوكيات العميل عن طريق تمرير خيارات عميل محددة إلى الوسيطة الثانية لـ PredisClient::__construct()
:
$ client = new Predis Client ( $ parameters , [ ' prefix ' => ' sample: ' ]);
تتم إدارة الخيارات باستخدام حاوية صغيرة تشبه DI ويمكن تهيئة قيمها بتكاسل فقط عند الحاجة. خيارات العميل المدعومة افتراضيًا في Predis هي:
prefix
: سلسلة البادئة المطبقة على كل مفتاح موجود في الأوامر.exceptions
: ما إذا كان يجب على العميل طرح الاستجابات أو إرجاعها عند حدوث أخطاء Redis.connections
: قائمة واجهات الاتصال الخلفية أو مثيل مصنع الاتصال.cluster
: تحدد الواجهة الخلفية للكتلة ( predis
أو redis
أو القابلة للاستدعاء).replication
: يحدد الواجهة الخلفية للنسخ المتماثل ( predis
أو sentinel
أو القابل للاستدعاء).aggregate
: يقوم بتكوين العميل باتصال تجميعي مخصص (قابل للاستدعاء).parameters
: قائمة معلمات الاتصال الافتراضية للاتصالات المجمعة.commands
: تحدد مثيل مصنع الأوامر لاستخدامه من خلال المكتبة.يمكن للمستخدمين أيضًا توفير خيارات مخصصة بقيم أو كائنات قابلة للاستدعاء (للتهيئة البطيئة) المخزنة في حاوية الخيارات لاستخدامها لاحقًا من خلال المكتبة.
الاتصالات المجمعة هي الأساس الذي يقوم عليه Predis بتنفيذ التجميع والنسخ، ويتم استخدامها لتجميع اتصالات متعددة إلى عقد Redis واحدة وإخفاء المنطق المحدد المطلوب للتعامل معها بشكل صحيح اعتمادًا على السياق. تتطلب الاتصالات المجمعة عادةً مجموعة من معلمات الاتصال بالإضافة إلى خيار العميل المناسب عند إنشاء مثيل عميل جديد.
يمكن تكوين Predis للعمل في وضع التجميع باستخدام أسلوب المشاركة التقليدي من جانب العميل لإنشاء مجموعة من العقد المستقلة وتوزيع مساحة المفاتيح فيما بينها. يحتاج هذا الأسلوب إلى نوع من مراقبة الصحة الخارجية للعقد ويتطلب إعادة توازن مساحة المفاتيح يدويًا عند إضافة العقد أو إزالتها:
$ parameters = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' cluster ' => ' predis ' ];
$ client = new Predis Client ( $ parameters );
جنبًا إلى جنب مع Redis 3.0، تم تقديم نوع جديد من التجميعات الخاضعة للإشراف والمنسق في شكل مجموعة redis. يستخدم هذا النوع من النهج خوارزمية مختلفة لتوزيع مساحات المفاتيح، حيث تقوم عقد Redis بتنسيق نفسها من خلال التواصل عبر بروتوكول القيل والقال للتعامل مع الحالة الصحية وإعادة التوازن واكتشاف العقد وطلب إعادة التوجيه. من أجل الاتصال بمجموعة تُدار بواسطة redis-cluster، يحتاج العميل إلى قائمة بعقده (ليست بالضرورة كاملة لأنه سيكتشف العقد الجديدة تلقائيًا إذا لزم الأمر) وتعيين خيارات عميل cluster
على 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 );
يمكن تكوين العميل للعمل في إعداد رئيسي واحد/عبيد متعددين لتوفير توفر أفضل للخدمة. عند استخدام النسخ المتماثل، يتعرف Predis على أوامر القراءة فقط ويرسلها إلى تابع عشوائي من أجل توفير نوع من موازنة التحميل والتبديل إلى الرئيسي بمجرد اكتشاف أمر ينفذ أي نوع من العمليات التي قد تؤدي في النهاية إلى التعديل مساحة المفتاح أو قيمة المفتاح. بدلاً من ظهور خطأ في الاتصال عند فشل أحد التابعين، يحاول العميل الرجوع إلى تابع آخر من بين تلك المتوفرة في التكوين.
يتطلب التكوين الأساسي المطلوب لاستخدام العميل في وضع النسخ المتماثل تحديد خادم Redis واحدًا على أنه الخادم الرئيسي (يمكن القيام بذلك عبر معلمات الاتصال عن طريق تعيين معلمة role
على master
) وواحد أو أكثر من العبيد (في هذه الحالة تعيين role
على slave
للعبيد اختياري):
$ 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 );
يحتوي التكوين أعلاه على قائمة ثابتة من الخوادم ويعتمد بالكامل على منطق العميل، ولكن من الممكن الاعتماد على redis-sentinel
لبيئة HA أكثر قوة مع خوادم الحارس التي تعمل كمصدر للسلطة للعملاء لاكتشاف الخدمة. الحد الأدنى من التكوين المطلوب من قبل العميل للعمل مع redis-sentinel هو قائمة من معلمات الاتصال التي تشير إلى مجموعة من مثيلات الحارس، وتم تعيين خيار replication
على sentinel
وخيار service
المعين على اسم الخدمة:
$ 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 );
إذا تم تكوين العقد الرئيسية والتابعة لطلب مصادقة من العملاء، فيجب توفير كلمة مرور عبر خيار عميل parameters
العامة. يمكن أيضًا استخدام هذا الخيار لتحديد فهرس قاعدة بيانات مختلف. ستبدو مصفوفة خيارات العميل بالشكل التالي:
$ options = [
' replication ' => ' sentinel ' ,
' service ' => ' mymaster ' ,
' parameters ' => [
' password ' => $ secretpassword ,
' database ' => 10 ,
],
];
في حين أن Predis قادر على التمييز بين الأوامر التي تؤدي عمليات الكتابة والقراءة فقط، فإن EVAL
و EVALSHA
يمثلان حالة زاوية يتحول فيها العميل إلى العقدة الرئيسية لأنه لا يستطيع معرفة متى يكون برنامج Lua النصي آمنًا للتنفيذ على العبيد. على الرغم من أن هذا هو السلوك الافتراضي بالفعل، إلا أنه عندما لا تقوم بعض نصوص Lua بتنفيذ عمليات الكتابة، فمن الممكن تقديم تلميح لإخبار العميل بالالتزام بالعبيد لتنفيذها:
$ 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.
يحتوي دليل examples
على عدد قليل من البرامج النصية التي توضح كيفية تكوين العميل واستخدامه للاستفادة من النسخ المتماثل في كل من السيناريوهات الأساسية والمعقدة.
يمكن أن يساعد خط الأنابيب في الأداء عندما يلزم إرسال العديد من الأوامر إلى الخادم عن طريق تقليل زمن الوصول الذي توفره توقيتات الشبكة ذهابًا وإيابًا. تعمل خطوط الأنابيب أيضًا مع التوصيلات المجمعة. يمكن للعميل تنفيذ خط الأنابيب داخل كتلة قابلة للاستدعاء أو إرجاع مثيل خط أنابيب مع القدرة على سلسلة الأوامر بفضل واجهته بطلاقة:
// 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 ();
يوفر العميل تجريدًا لمعاملات Redis استنادًا إلى MULTI
و EXEC
مع واجهة مشابهة لخطوط توجيه الأوامر:
// 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 ();
يمكن لهذا التجريد إجراء عمليات التحقق والضبط بفضل WATCH
و UNWATCH
ويوفر إعادة المحاولة التلقائية للمعاملات التي تم إحباطها بواسطة Redis عند لمس مفاتيح WATCH
ed. للحصول على مثال لمعاملة باستخدام CAS، يمكنك رؤية المثال التالي.
بينما نحاول تحديث Predis للبقاء على اطلاع بجميع الأوامر المتوفرة في Redis، فقد تفضل الالتزام بإصدار قديم من المكتبة أو توفير طريقة مختلفة لتصفية الوسائط أو تحليل الاستجابات لأوامر معينة. ولتحقيق ذلك، يوفر Predis القدرة على تنفيذ فئات أوامر جديدة لتعريف الأوامر أو تجاوزها في مصنع الأوامر الافتراضي الذي يستخدمه العميل:
// 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 ();
هناك أيضًا طريقة لإرسال أوامر أولية دون تصفية وسيطاتها أو تحليل الاستجابات. يجب على المستخدمين توفير قائمة الوسائط للأمر كمصفوفة، باتباع التوقيعات كما هو محدد في وثائق Redis للأوامر:
$ response = $ client -> executeRaw ([ ' SET ' , ' foo ' , ' bar ' ]);
على الرغم من أنه من الممكن الاستفادة من برمجة Lua النصية على Redis 2.6+ باستخدام EVAL
و EVALSHA
مباشرة، إلا أن Predis يقدم أوامر البرنامج النصي كتجريد بمستوى أعلى مبني عليها لتسهيل الأمور. يمكن تسجيل أوامر البرنامج النصي في مصنع الأوامر الذي يستخدمه العميل ويمكن الوصول إليها كما لو كانت أوامر Redis عادية، ولكنها تحدد نصوص Lua النصية التي يتم نقلها إلى الخادم للتنفيذ عن بعد. داخليًا، يستخدمون EVALSHA
افتراضيًا ويحددون البرنامج النصي من خلال تجزئة SHA1 الخاصة به لحفظ النطاق الترددي، ولكن يتم استخدام EVAL
كبديل عند الحاجة:
// 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 استخدام واجهات خلفية مختلفة للاتصال بـ Redis. يعمل تكامل Relay المدمج على تعزيز امتداد Relay لـ PHP لتحقيق مكاسب كبيرة في الأداء، عن طريق تخزين نسخة متماثلة جزئية من مجموعة بيانات Redis في ذاكرة وقت التشغيل المشتركة PHP.
$ client = new Predis Client ( ' tcp://127.0.0.1 ' , [
' connections ' => ' relay ' ,
]);
يمكن للمطورين إنشاء فئات الاتصال الخاصة بهم لدعم الواجهات الخلفية للشبكة الجديدة بالكامل، أو توسيع الفئات الموجودة أو توفير تطبيقات مختلفة تمامًا. يجب أن تقوم فئات الاتصال بتطبيق PredisConnectionNodeConnectionInterface
أو توسيع 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 ' ],
]);
للحصول على رؤية أكثر تعمقًا حول كيفية إنشاء واجهات خلفية جديدة للاتصال، يمكنك الرجوع إلى التنفيذ الفعلي لفئات الاتصال القياسية المتوفرة في مساحة الاسم PredisConnection
.
تحظى المساهمات في Predis بتقدير كبير إما في شكل طلبات سحب للحصول على ميزات جديدة، أو إصلاحات الأخطاء، أو مجرد تقارير الأخطاء. نطلب منكم فقط الالتزام بنماذج طلبات الإصدار والسحب.
تنبيه : لا تقم مطلقًا بتشغيل مجموعة الاختبار المرفقة مع Predis مقابل مثيلات Redis التي تعمل في بيئات الإنتاج أو التي تحتوي على البيانات التي تهمك!
يحتوي Predis على مجموعة اختبار شاملة تغطي كل جانب من جوانب المكتبة ويمكنها إجراء اختبارات التكامل بشكل اختياري مقابل مثيل قيد التشغيل من Redis (المطلوب >= 2.4.0 للتحقق من السلوك الصحيح لتنفيذ كل أمر. اختبارات التكامل للأنظمة غير المدعومة يتم تخطي أوامر Redis تلقائيًا إذا لم يكن Redis قيد التشغيل، فيمكن تعطيل اختبارات التكامل، راجع الملف التمهيدي للاختبارات للحصول على مزيد من التفاصيل حول اختبار هذه المكتبة.
يستخدم Predis إجراءات GitHub للتكامل المستمر ويمكن العثور على سجل الإصدارات السابقة والحالية في صفحة الإجراءات الخاصة به.
يتم توزيع رمز Predis بموجب شروط ترخيص MIT (انظر الترخيص).