Schéma d'architecture du cluster 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
🎜>< du fichier de configuration redis.config 🎜>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
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 :
Requête des informations sur le cluster :
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
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
Entrez 500 pour allouer 500 emplacements
Étape 3 : Entrez l'identifiant du nœud de l'emplacement de réception
这里准备给7007分配槽,通过cluster nodes查看7007结点id为15b809eadae88955e36bcdbb8144f61bbbaf38fb
输入:15b809eadae88955e36bcdbb8144f61bbbaf38fb
第四步:输入源结点id
这里输入all
第五步:输入yes开始移动槽到目标结点id
添加从节点
集群创建成功后可以向集群中添加节点,下面是添加一个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查看。
注意:如果原来该结点在集群中的配置信息已经生成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的从节点:
删除结点:
./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!