Maison  >  Article  >  base de données  >  Introduction à la construction de clusters distribués Redis

Introduction à la construction de clusters distribués Redis

尚
avant
2019-12-12 17:18:083468parcourir

Introduction à la construction de clusters distribués Redis

Schéma d'architecture du cluster Redis

Introduction à la construction de clusters distribués Redis

La couleur bleue dans l'image ci-dessus est le nœud du cluster Redis.

Utilisez la commande ping entre les nœuds pour tester si la connexion est normale. Il n'y a pas de distinction principale entre les nœuds. Lorsque vous vous connectez à un nœud pour des opérations, il peut être transmis à d'autres nœuds.

1. Mécanisme de tolérance aux pannes Redis

Les nœuds s'enverront régulièrement des commandes ping pour tester l'état de santé des nœuds. Lorsque les nœuds reçoivent la commande ping, ils renverront une corde de pong.

Mécanisme de vote : si un nœud A envoie un ping au nœud B mais n'obtient pas de retour pong, les autres nœuds seront informés d'envoyer à nouveau un ping à B si plus de la moitié des nœuds du cluster ne le peuvent pas. recevoir le pong du nœud B. On considère alors que le nœud B est en panne. Généralement, un nœud de sauvegarde est fourni pour chaque nœud. En cas de panne, il sera basculé vers le nœud de sauvegarde.

2. Principe de stockage du cluster Redis

Redis effectuera une opération de hachage sur chaque clé stockée et générera une valeur de hachage de [0-16384] (effectuez d'abord

l'algorithme crc prend alors le reste de 16384).

Dans le cas d'un cluster, l'intervalle [0-16384] est divisé et placé dans différents redis.

3. Persistance Redis

Snapshotting : sauvegarder régulièrement les données en mémoire Redis sur le disque dur

AOF : sauvegarder toutes les commandes L'opération est enregistrée à l'AOF La fréquence de synchronisation de l'AOP est très élevée Même si les données sont perdues, la granularité est très faible, mais cela aura un impact sur les performances.

2. Construction d'environnement de cluster

outil de gestion de cluster redis redis-trib.rb En vous appuyant sur l'environnement Ruby, vous devez d'abord installer l'environnement Ruby

Installer Ruby

yum install ruby
yum install rubygems

Installer le programme d'interface pour Ruby ​​et Redis

Copier redis-3.0.0.gem vers /usr/local Exécuter sous

 :

gem install /usr/local/redis-3.0.0.gem

3. Créez un cluster Redis

Sur un serveur, vous pouvez utiliser différents numéros de port pour représenter différents serveurs Redis.

Le cluster Redis nécessite au moins trois serveurs, et chaque serveur nécessite un serveur de sauvegarde, donc au moins 6 serveurs sont requis. La planification du port est la suivante :

Serveur maître : 192.168.100.66:7001:7002:7003

Serveur esclave : 192.168.100.66:7004:7005:7006

Dans /usr/ local Créez un dossier pour stocker le programme serveur

mkdir 7001 7002 7003 7004 7005 7006

Si vous souhaitez que Redis prenne en charge le cluster, vous devez modifier le oui activé pour le cluster

🎜>Dans cet exemple, nous utilisons des ports pour distinguer différents services redis, nous devons donc également modifier le port de redis.config vers le port correspondant

Après avoir modifié le fichier de configuration, copiez le bin du répertoire d'installation redis dans chaque répertoire au-dessus du milieu.

Entrez respectivement 7001/bin/ 7002/bin....

Démarrez le service ./redis-server ./redis.conf

Affichez le processus redis : ps - aux|grep redis L'image suivante montre que le démarrage est réussi

Introduction à la construction de clusters distribués Redis

Créer un cluster :

Modifier redis-3.0.0/src/redis de le dossier -trib.rb précédemment décompressé est copié dans le répertoire redis-cluster

Exécuter

./redis-trib.rb create --replicas 1 192.168.100.66:7001 192.168.100.66:7002 192.168.100.66:7003 192.168.100.66:7004 192.168.100.66:7005  192.168.100.66:7006

S'il est exécuté, l'erreur suivante est signalée :

[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

La solution est de supprimez le fichier de configuration généré nodes.conf, s'il échoue, cela signifie que le nœud créé inclut désormais les informations de nœud de l'ancien cluster. Vous devez supprimer le fichier de persistance de redis puis redémarrer redis, par exemple : appendonly.aof. , dump.rdb

En cas de succès, saisissez ce qui suit :

Introduction à la construction de clusters distribués Redis

Requête des informations sur le cluster :

Introduction à la construction de clusters distribués Redis

Instructions :

./redis-cli -c - h 192.168.101.3 -p 7001, où -c indique la connexion à Redis en mode cluster, -h spécifie l'adresse IP et -p spécifie le numéro de port

nœuds de cluster Interroger les informations sur les nœuds de cluster

informations sur le cluster Interroger les informations sur l'état du cluster

Introduction à la construction de clusters distribués Redis

Réallocation des emplacements de hachage

Étape 1 : Connectez-vous au cluster

./ redis-trib.rb reshard 192.168.101.3:7001 (connectez-vous à n'importe quel nœud disponible dans le cluster)

Étape 2 : Entrez le nombre d'emplacements à attribuer

Introduction à la construction de clusters distribués Redis

Entrez 500 pour allouer 500 emplacements

Étape 3 : Entrez l'identifiant du nœud de l'emplacement de réception

Introduction à la construction de clusters distribués Redis

这里准备给7007分配槽,通过cluster nodes查看7007结点id为15b809eadae88955e36bcdbb8144f61bbbaf38fb

输入:15b809eadae88955e36bcdbb8144f61bbbaf38fb 

第四步:输入源结点id

Introduction à la construction de clusters distribués Redis

这里输入all

第五步:输入yes开始移动槽到目标结点id

Introduction à la construction de clusters distribués Redis

添加从节点

 

集群创建成功后可以向集群中添加节点,下面是添加一个slave从节点。

添加7008从结点,将7008作为7007的从结点。

./redis-trib.rb add-node --slave --master-id 主节点id 添加节点的ip和端口 集群中已存在节点ip和端口

执行如下命令:

./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4  192.168.101.3:7008 192.168.101.3:7001

cad9f7413ec6842c971dbcc2c48b4ca959eb5db4  是7007结点的id,可通过cluster nodes查看。

Introduction à la construction de clusters distribués Redis

注意:如果原来该结点在集群中的配置信息已经生成cluster-config-file指定的配置文件中(如果cluster-config-file没有指定则默认为nodes.conf),这时可能会报错:

[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

解决方法是删除生成的配置文件nodes.conf,删除后再执行./redis-trib.rb add-node指令

查看集群中的结点,刚添加的7008为7007的从节点:

1Introduction à la construction de clusters distribués Redis

 删除结点:

./redis-trib.rb del-node 127.0.0.1:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017

删除已经占有hash槽的结点会失败,报错如下:

[ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again.

需要将该结点占用的hash槽分配出去(参考hash槽重新分配章节)。

测试:

Maven:
<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.7.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.10.RELEASE</version>
        <scope>test</scope>
    </dependency>
</dependencies>

普通测试:

@Test
public void redisClusterTest1(){
    JedisPoolConfig config=new JedisPoolConfig();
    config.setMaxTotal(30);
    config.setMaxIdle(2);

    Set<HostAndPort> jedisNode=new HashSet<HostAndPort>();
    jedisNode.add(new HostAndPort("192.168.100.66",7001));
    jedisNode.add(new HostAndPort("192.168.100.66",7002));
    jedisNode.add(new HostAndPort("192.168.100.66",7003));
    jedisNode.add(new HostAndPort("192.168.100.66",7004));
    jedisNode.add(new HostAndPort("192.168.100.66",7005));
    jedisNode.add(new HostAndPort("192.168.100.66",7006));

    JedisCluster jc=new JedisCluster(jedisNode,config);
    jc.set("name","老王");
    String value=jc.get("name");
    System.out.println(value);
}

Spring测试:

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 连接池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="30" />
        <!-- 最大空闲连接数 -->
        <property name="maxIdle" value="10" />
        <!-- 每次释放连接的最大数目 -->
        <property name="numTestsPerEvictionRun" value="1024" />
        <!-- 释放连接的扫描间隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <!-- 连接最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="10000" />
        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
        <property name="maxWaitMillis" value="1500" />
        <!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testOnBorrow" value="true" />
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="true" />
        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="blockWhenExhausted" value="false" />
    </bean>
    <!-- redis集群 -->
    <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
        <constructor-arg index="0">
            <set>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.100.66"></constructor-arg>
                    <constructor-arg index="1" value="7001"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.100.66"></constructor-arg>
                    <constructor-arg index="1" value="7002"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.100.66"></constructor-arg>
                    <constructor-arg index="1" value="7003"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.100.66"></constructor-arg>
                    <constructor-arg index="1" value="7004"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.100.66"></constructor-arg>
                    <constructor-arg index="1" value="7005"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.100.66"></constructor-arg>
                    <constructor-arg index="1" value="7006"></constructor-arg>
                </bean>
            </set>
        </constructor-arg>
        <constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg>
    </bean>
</beans>

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-config.xml"})
public class RedisClusterTest {
    @Autowired
    private JedisCluster jedisCluster;
    @Test
    public void redisClusterTest2(){
        jedisCluster.set("username","小明啦啦");
        String name=jedisCluster.get("username");
        System.out.println(name);
    }
}

更多redis知识请关注redis数据库教程栏目。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer