phpredis Redis объекты подключения к кластеру повторно используют запросы

Мы используем библиотеку phpredis для подключения к нашему 64-узловому кластеру Redis с наших обслуживающих компьютеров. Хотя мы используем постоянные соединения, так как php не использует объекты в разных запросах, каждый запрос делает КЛАСТЕРНЫЕ СЛОТЫ сначала вызовите кластер Redis, а затем выполните выборку данных. Это оказывается очень дорогостоящим, так как увеличивает нагрузку на процессор как на API, так и на Redis, а также увеличивает использование сети для мета-информации (слоты CLUSTER), которые в противном случае могли бы быть кэшированы.
По сути, мы хотим, чтобы объект подключения кластера Redis повторно использовался в нескольких запросах в одном и том же процессе php-fpm. Любые предложения о том, как это сделать?

ОБНОВЛЕНИЕ: я попробовал следующий diff в коде cluster_library.c, но это, кажется, вызывает случайные исключения времени выполнения в php.

index 3e532b7..b2cbf16 100644
--- a/cluster_library.c
+++ b/cluster_library.c
@@ -7,6 +7,10 @@
#include <zend_exceptions.h>

extern zend_class_entry *redis_cluster_exception_ce;
+int cache_count = 0;
+//Cache the cluster slots value for every n requests/calls, n being 100 for now
+int CACHE_COUNT_VAL = 10;
+clusterReply *permSlots=NULL;

/* Debugging methods/
static void cluster_dump_nodes(redisCluster *c) {
@@ -939,7 +943,18 @@ PHP_REDIS_API int cluster_map_keyspace(redisCluster *c TSRMLS_DC) {
}

// Parse out cluster nodes.  Flag mapped if we are valid
-        slots = cluster_get_slots(seed TSRMLS_CC);
+ if (permSlots && cache_count <= CACHE_COUNT_VAL) {
+         slots = permSlots;
+         cache_count++;
+ }
+ else {
+         slots = cluster_get_slots(seed TSRMLS_CC);
+ }
+
if (slots) {
mapped = !cluster_map_slots(c, slots);
// Bin anything mapped, if we failed somewhere
@@ -951,8 +966,16 @@ PHP_REDIS_API int cluster_map_keyspace(redisCluster *c TSRMLS_DC) {
if (mapped) break;
} ZEND_HASH_FOREACH_END();

+    if((!permSlots && mapped && slots) ||
+             cache_count >= CACHE_COUNT_VAL) {
+ permSlots = slots;
+ cache_count = 0;
+    }
+
// Clean up slots reply if we got one
-    if(slots) cluster_free_reply(slots, 1);
+    // if(slots) cluster_free_reply(slots, 1);

// Throw an exception if we couldn't map
if(!mapped) {

1

Решение

Разработчик phpredis здесь. В настоящее время это ограничение / недостаток в phpredis, так как он должен выдавать команду CLUSTER SLOTS для каждого нового запроса. Насколько я знаю, единственный способ избежать этого — указывать phpredis на прокси Codis или же Corvis но у меня нет личного опыта их использования.

При этом я реализовал экспериментальную поддержку этой функции в этот ветка. Он использует PHP persistent_list кешировать информацию о слоте между запросами.

Поскольку внедрение Redis Cluster, похоже, набирает обороты, я постараюсь в скором времени перенести это в основную ветку разработки и, возможно, в следующую стабильную версию!

Ура,
Майк

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]