Support » Plugin: Redis Object Cache » Support of redis-object-cache plugin to redis-cluster protocol

  • Resolved jack960330

    (@jack960330)


    Redis-Object-Cache plug-in does not support redis-cluster adequately. It is wrong to operate the cluster in the wrong way. You use redis-cluster in the same way as singleton, because the characteristics of redis-cluster determine that some operations are invalid, such as ping, modifying the following code of object-cache.php to recover from failure.

    
        public function __construct($fail_gracefully = true)
        {
            global $blog_id, $table_prefix;
    
            $parameters = array(
                'scheme' => 'tcp',
                'host' => '127.0.0.1',
                'port' => 6379
            );
    
            foreach (array( 'scheme', 'host', 'port', 'path', 'password', 'database' ) as $setting) {
                $constant = sprintf('WP_REDIS_%s', strtoupper($setting));
                if (defined($constant)) {
                    $parameters[ $setting ] = constant($constant);
                }
            }
    
            if (defined('WP_REDIS_GLOBAL_GROUPS') && is_array(WP_REDIS_GLOBAL_GROUPS)) {
                $this->global_groups = WP_REDIS_GLOBAL_GROUPS;
            }
    
            if (defined('WP_REDIS_IGNORED_GROUPS') && is_array(WP_REDIS_IGNORED_GROUPS)) {
                $this->ignored_groups = WP_REDIS_IGNORED_GROUPS;
            }
    
            $client = defined('WP_REDIS_CLIENT') ? WP_REDIS_CLIENT : null;
    
            if (class_exists('Redis') && strcasecmp('predis', $client) !== 0) {
                $client = defined('HHVM_VERSION') ? 'hhvm' : 'pecl';
            } else {
                $client = 'predis';
            }
    
            try {
                if (strcasecmp('hhvm', $client) === 0) {
                    $this->redis_client = sprintf('HHVM Extension (v%s)', HHVM_VERSION);
                    $this->redis = new Redis();
    
                    // Adjust host and port, if the scheme is <code>unix</code>
                    if (strcasecmp('unix', $parameters[ 'scheme' ]) === 0) {
                        $parameters[ 'host' ] = 'unix://' . $parameters[ 'path' ];
                        $parameters[ 'port' ] = 0;
                    }
    
                    $this->redis->connect($parameters[ 'host' ], $parameters[ 'port' ]);
                }
    
                if (strcasecmp('pecl', $client) === 0) {
                    $this->redis_client = sprintf('PhpRedis (v%s)', phpversion('redis'));
    
                    if (defined('WP_REDIS_SHARDS')) {
                        $this->redis = new RedisArray(array_values(WP_REDIS_SHARDS));
                    } elseif (defined('WP_REDIS_CLUSTER')) {
                        $this->redis = new RedisCluster(null, array_values(WP_REDIS_CLUSTER));
                    } else {
                        $this->redis = new Redis();
    
                        if (strcasecmp('unix', $parameters[ 'scheme' ]) === 0) {
                            $this->redis->connect($parameters[ 'path' ]);
                        } else {
                            $this->redis->connect($parameters[ 'host' ], $parameters[ 'port' ]);
                        }
                    }
                }
    
                if (strcasecmp('pecl', $client) === 0 || strcasecmp('hhvm', $client) === 0) {
                    if (isset($parameters[ 'password' ])) {
                        $this->redis->auth($parameters[ 'password' ]);
                    }
    
                    if (isset($parameters[ 'database' ])) {
                        $this->redis->select($parameters[ 'database' ]);
                    }
                }
    
                if (strcasecmp('predis', $client) === 0) {
                    $this->redis_client = 'Predis';
    
                    // Require PHP 5.4 or greater
                    if (version_compare(PHP_VERSION, '5.4.0', '<')) {
                        throw new Exception;
                    }
    
                    // Load bundled Predis library
                    if (! class_exists('Predis\Client')) {
                        $plugin_dir = defined('WP_PLUGIN_DIR') ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins';
                        require_once $plugin_dir . '/redis-cache/includes/predis/autoload.php';
                    }
    
                    $options = array();
                    $cluster = false;
    
                    if (defined('WP_REDIS_SHARDS')) {
                        $parameters = WP_REDIS_SHARDS;
                    } elseif (defined('WP_REDIS_SENTINEL')) {
                        $cluster = true;
                        $parameters = WP_REDIS_SERVERS;
                        $options[ 'replication' ] = 'sentinel';
                        $options[ 'service' ] = WP_REDIS_SENTINEL;
                    } elseif (defined('WP_REDIS_SERVERS')) {
                        $parameters = WP_REDIS_SERVERS;
                        $options[ 'replication' ] = true;
                    } elseif (defined('WP_REDIS_CLUSTER')) {
                        $cluster = true;
                        $parameters = WP_REDIS_CLUSTER;
                        $options[ 'cluster' ] = 'redis';
                    }
    
                    foreach (array( 'WP_REDIS_SERVERS', 'WP_REDIS_SHARDS', 'WP_REDIS_CLUSTER' ) as $constant) {
                        if (defined('WP_REDIS_PASSWORD') && defined($constant)) {
                            $options[ 'parameters' ][ 'password' ] = WP_REDIS_PASSWORD;
                        }
                    }
    
                    $this->redis = new Predis\Client($parameters, $options);
                    $this->redis->connect();
    
                    $this->redis_client .= sprintf(' (v%s)', Predis\Client::VERSION);
                }
    
                // Throws exception if Redis is unavailable
                $this->redis->ping();
    
                $this->redis_connected = true;
            } catch (Exception $exception) {
    
                if($cluster) {
                    $this->redis_connected = true;
                    return;
                }
    
                // When Redis is unavailable, fall back to the internal back by forcing all groups to be "no redis" groups
                $this->ignored_groups = array_unique(array_merge($this->ignored_groups, $this->global_groups));
    
                $this->redis_connected = false;
    
                if (! $fail_gracefully) {
                    throw $exception;
                }
            }
    
            // Assign global and blog prefixes for use with keys
            if (function_exists('is_multisite')) {
                $this->global_prefix = (is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE')) ? '' : $table_prefix;
                $this->blog_prefix = (is_multisite() ? $blog_id : $table_prefix);
            }
        }
    
    
Viewing 1 replies (of 1 total)
Viewing 1 replies (of 1 total)
  • You must be logged in to reply to this topic.