マルチマシン環境では、Redis サービスは書き込みコマンドを受信し、自身のデータとステータスが変更されると、そのコマンドを 1 つ以上の Redis にコピーします。このモードはマスター/スレーブ レプリケーションと呼ばれます。コマンド smileof を通じて、ある Redis サーバーは、Redis 内の別の Redis サーバーのデータとステータスをコピーできます。メインサーバーをマスター、スレーブサーバーをスレーブと呼びます。
マスター/スレーブ レプリケーションにより、ネットワークに異常が発生してネットワークが切断された場合でも、データが確実に複製されます。ネットワークが正常な場合、マスターはコマンドを送信してスレーブを更新し続けます。更新には、クライアントの書き込み、キーの有効期限または削除、その他のネットワーク異常が含まれます。マスターは一定期間スレーブから切断されます。スレーブは次のことを試みます。マスターに再接続した後に部分的に再接続し、切断中に失われたコマンドを同期して再取得します。部分再同期が実行できない場合は、完全再同期が実行されます。
データを失わないようにするために、永続化機能が使用されることがあります。ただし、これによりディスク IO 操作が増加します。マスター/スレーブ レプリケーション テクノロジを使用すると、永続性が置き換えられ、IO 操作が削減されるため、レイテンシが短縮され、パフォーマンスが向上します。
マスター/スレーブ モードでは、マスターが書き込みを担当し、スレーブが読み取りを担当します。マスターとスレーブの同期によりデータの不整合が生じる可能性がありますが、読み取り操作のスループットを向上させることができます。マスター/スレーブ モデルは、Redis のシングル ポイント リスクを回避します。レプリカを通じてシステムの可用性を向上させます。マスター ノードに障害が発生した場合、スレーブ ノードは新しいノードをマスター ノードとして選択し、システムの可用性を確保します。
マスター/スレーブ レプリケーションは、初期化、同期、コマンド伝播の 3 つの段階に分けることができます。
サーバーがslaveofコマンドを実行すると、スレーブサーバーはマスターサーバーとのソケット接続を確立し、初期化を完了します。メインサーバが正常であれば、接続確立後、pingコマンドによりハートビート検出を行い、応答を返します。障害が発生し、応答が受信されない場合、スレーブ ノードはマスター ノードへの接続を再試行します。マスターが認証情報を設定すると、認証データが正しいかどうかを確認します。認証に失敗した場合は、エラーが報告されます。
初期化完了後、マスターはスレーブからデータ同期指示を受信した際に、状況に応じて完全同期を行うか部分同期を行うかを判断する必要があります。
同期完了後、マスターサーバーとスレーブサーバーはハートビート検出によりお互いのオンライン状態を確認し、コマンド送信を行います。スレーブは、自身のコピー バッファのオフセットもマスターに送信します。これらのリクエストに基づいて、マスターは新しく生成されたコマンドをスレーブと同期する必要があるかどうかを判断します。スレーブは同期コマンドを受信後実行し、最終的にマスターと同期します。
Jedis、Redission、および Lettuce は一般的な Java Redis クライアントです。レタスを使用して、マスター/スレーブ モードでの読み取り/書き込み分離コマンドの実行をデモンストレーションします。
<dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>5.1.8.RELEASE</version> </dependency>
以下は
package redis; import io.lettuce.core.ReadFrom; import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.Utf8StringCodec; import io.lettuce.core.masterslave.MasterSlave; import io.lettuce.core.masterslave.StatefulRedisMasterSlaveConnection; import org.assertj.core.util.Lists; class MainLettuce { public static void main(String[] args) { List<RedisURI> nodes = Lists.newArrayList( RedisURI.create("redis://localhost:7000"), RedisURI.create("redis://localhost:7001") ); RedisClient redisClient = RedisClient.create(); StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave.connect( redisClient, new Utf8StringCodec(), nodes); connection.setReadFrom(ReadFrom.SLAVE); RedisCommands<String, String> redisCommand = connection.sync(); redisCommand.set("master","master write test2"); String value = redisCommand.get("master"); System.out.println(value); connection.close(); redisClient.shutdown(); } }
によって補足されます: Lettuce の構成と Redis クライアントの使用 (Spring Boot 2.x に基づく)
開発環境: Intellij IDEA Maven Spring Boot 2.x JDK 8
Spring Boot を使用 バージョン 2.0 以降、デフォルトの Redis クライアント Jedis は Lettuce に置き換えられます。Lettuce の構成と使用法については以下で説明します。
<properties> <redisson.version>3.8.2</redisson.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> </dependencies>
#Redis配置 spring: redis: database: 6 #Redis索引0~15,默认为0 host: 127.0.0.1 port: 6379 password: #密码(默认为空) lettuce: # 这里标明使用lettuce配置 pool: max-active: 8 #连接池最大连接数(使用负值表示没有限制) max-wait: -1ms #连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 5 #连接池中的最大空闲连接 min-idle: 0 #连接池中的最小空闲连接 timeout: 10000ms #连接超时时间(毫秒)
package com.dbfor.redis.config; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { /** * RedisTemplate配置 * @param connectionFactory * @return */ @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) { // 配置redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//value序列化 redisTemplate.afterPropertiesSet(); return redisTemplate; } }
package com.dbfor.redis; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class RedisApplication { public static void main(String[] args) { SpringApplication.run(RedisApplication.class); } }
package com.dbfor.redis; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest @RunWith(SpringRunner.class) @Component public class RedisTest { @Autowired private RedisTemplate redisTemplate; @Test public void set() { redisTemplate.opsForValue().set("test:set1", "testValue1"); redisTemplate.opsForSet().add("test:set2", "asdf"); redisTemplate.opsForHash().put("hash2", "name1", "lms1"); redisTemplate.opsForHash().put("hash2", "name2", "lms2"); redisTemplate.opsForHash().put("hash2", "name3", "lms3"); System.out.println(redisTemplate.opsForValue().get("test:set")); System.out.println(redisTemplate.opsForHash().get("hash2", "name1")); } }
以上がJava が Lettuce クライアントを使用して Redis マスター/スレーブ モードでコマンドを実行する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。