Redis教程
这里是自己学习Redis的一些笔记,如果哪里有不恰当的,希望各位大佬指正,谢谢。
参考网址: https://www.cnblogs.com/edisonfeng/p/3571870.html
https://blog.csdn.net/liuchuanhong1/article/details/53206028
一、Redis 安装
Window 下安装
下载地址:redis下载地址
Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 redis。
打开一个 cmd 窗口 使用cd命令切换目录到 E:\redis 运行 redis-server.exe redis.windows.conf 。
如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:
这时候另启一个cmd窗口,原来的不要关闭,不然就无法访问服务端了。
切换到redis目录下运行 redis-cli.exe -h 127.0.0.1 -p 6379 。
设置键值对 set myKey abc
取出键值对 get myKey
二、java对redis的基本操作
2.1 新建Maven项目
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.2 新建测试类
public class Test {
public static void main(String[] args) {
new RedisClient().show();
}
}
2.3 新建功能类
public class RedisClient {
private Jedis jedis;// 非切片客户端连接
private JedisPool jedisPool; // 非切片连接池
private ShardedJedis shardedJedis; // 切片客户端连接
private ShardedJedisPool shardedJedisPool; // 切片连接池
public RedisClient() {
initalPool();
initalShardedPool();
jedis = jedisPool.getResource();
shardedJedis = shardedJedisPool.getResource();
}
/*
* 初始化非切片池
*/
private void initalPool() {
// 池基本配置
JedisPoolConfig config = new JedisPoolConfig();
// 最大空闲连接数
config.setMaxIdle(8);
// 获取连接时的最大等待毫秒数
config.setMaxWaitMillis(10001);
// 最大连接数
config.setMaxTotal(20);
// 在获取连接的时候检查有效性,默认false
config.setTestOnBorrow(false);
jedisPool = new JedisPool(config, "127.0.0.1", 6379);
}
/*
* 初始化切片池
*/
private void initalShardedPool() {
// 池基本配置
JedisPoolConfig config = new JedisPoolConfig();
// 最大空闲连接数
config.setMaxIdle(8);
// 获取连接时的最大等待毫秒数
config.setMaxWaitMillis(10001);
// 最大连接数
config.setMaxTotal(20);
// 在获取连接的时候检查有效性,默认false
config.setTestOnBorrow(false);
// slave连接,
// 也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,
// Master以写为主,Slave以读为主。
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo("127.0.0.1", 6379, "master"));
// 构造池
shardedJedisPool = new ShardedJedisPool(config, shards);
}
public void show() {
// KeyOperate();
// StringOperate();
// ListOperate();
// SetOperate();
// SortedSetOperate();
HashOperate();
jedisPool.close();
// jedisPool.returnResource(jedis);
shardedJedisPool.close();
// shardedJedisPool.returnResource(shardedJedis);
}
/*
* KEY功能
*/
private void KeyOperate() {
}
private void StringOperate() {
}
private void ListOperate() {
}
private void SetOperate() {
}
private void SortedSetOperate() {
}
private void HashOperate() {
}
}
2.4 各个功能函数
2.4.1 key功能
/*
* KEY功能
*/
private void KeyOperate() {
System.out.println("---------------KEY功能----------------");
// 清空数据
System.out.println("清空库中所有数据:" + jedis.flushDB());
// 判断key是否存在
System.out.println("判断key999键是否存在:" + shardedJedis.exists("key999"));
System.out.println("新增key001,value001键值对:" + shardedJedis.set("key001", "value001"));
System.out.println("判断key001是否存在:" + shardedJedis.exists("key001"));
// 输出系统中所有的key
System.out.println("新增key002,value002键值对:" + shardedJedis.set("key002", "value002"));
System.out.println("系统中所有的键如下:");
Set<String> keys = jedis.keys("*");
Iterator<String> iterator = keys.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 删除key
System.out.println("判断key002键是否存在:" + shardedJedis.exists("key002"));
System.out.println("删除key002:" + shardedJedis.del("key002"));
System.out.println("判断key002键是否存在:" + shardedJedis.exists("key002"));
// 设置key001过期时间
System.out.println("设置k001过期时间为5秒:" + shardedJedis.expire("key001", 5));
System.out.println("k001的值:" + shardedJedis.get("key001"));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("查看k001的剩余生存时间:" + shardedJedis.ttl("key001"));
// 移除某个key的生存时间
System.out.println("移除key001的生存时间:" + shardedJedis.persist("key001"));
System.out.println("查看key001的剩余生存时间:" + shardedJedis.ttl("key001"));
// 查看key所存储的数据类型
System.out.println("查看key001所存储的数据类型:" + shardedJedis.type("key001"));
}
---------------KEY功能----------------
清空库中所有数据:OK
判断key999键是否存在:false
新增key001,value001键值对:OK
判断key001是否存在:true
新增key002,value002键值对:OK
系统中所有的键如下:
key002
key001
判断key002键是否存在:true
删除key002:1
判断key002键是否存在:false
设置k001过期时间为5秒:1
k001的值:value001
查看k001的剩余生存时间:3
移除key001的生存时间:1
查看key001的剩余生存时间:-1
查看key001所存储的数据类型:string
2.4.2 String
private void StringOperate() {
System.out.println("---------------String功能----------------");
// 清空数据
System.out.println("清空库中所有数据:" + jedis.flushDB());
System.out.println("===============增加===============");
jedis.set("k001", "v001");
jedis.set("k002", "v002");
jedis.set("k003", "v003");
jedis.set("k004", "v004");
jedis.set("k005", "v005");
System.out.println("已经新增5个键值对如下");
for (int i = 1; i < 6; i++) {
System.out.println(jedis.get("k00" + i));
}
System.out.println("===============删除===============");
System.out.println("删除k003键值对:" + jedis.del("k003"));
System.out.println("获取k003键的值:" + jedis.get("k003"));
System.out.println("===============修改===============");
// 直接覆盖原来得数据
System.out.println("直接覆盖k001原来得数据:" + jedis.set("k001", "value001-update"));
System.out.println("获取k001对应的 新值:" + jedis.get("k001"));
// 直接覆盖原来得数据
System.out.println("在k002原来得值后面追加:" + jedis.append("k002", "+appendString"));
System.out.println("k002追加后的值为:" + jedis.get("k002"));
System.out.println("===============增、删、查(多个)===============");
/**
* mset、mget同时新增、修改、查询多个键值对 等价于: jedis.set("name","sss")
* jedis.set("age","45")
*/
System.out.println("一次性新增k201,k202,k203,k204及其对应的值:"
+ jedis.mset("k201", "v201", "k202", "v202", "k203", "v203", "k204", "v204"));
System.out.println("一次性获取k201,k202,k203,k204的各自对应的值:" + jedis.mget("k201", "k202", "k203", "k204"));
System.out.println("一次性删除k201,k202:" + jedis.del(new String[] { "k201", "k202" }));
System.out.println("一次性获取k201,k202,k203,k204的各自对应的值:" + jedis.mget("k201", "k202", "k203", "k204"));
// jedis具备的功能sharedJedis中也可以直接使用,下面测试一些前面没有用过的方法
System.out.println("===============sharedJedis操作===============");
// 清空数据
System.out.println("清空库中所有数据:" + jedis.flushDB());
System.out.println("===============新增键值对时防止覆盖原来得值===============");
System.out.println("原来k001不存在的时候添加k001:" + shardedJedis.setnx("k001", "v001"));
System.out.println("原来k002不存在的时候添加k002:" + shardedJedis.setnx("k002", "v002"));
System.out.println("原来k002不存在的时候添加k002:" + shardedJedis.setnx("k002", "v00222222"));
System.out.println("获取k001的值:" + shardedJedis.get("k001"));
System.out.println("获取k002的值:" + shardedJedis.get("k002"));
System.out.println("===============超过有效期的键值对被删除===============");
// 设置key的有效期,并存储数据
System.out.println("新增k003,并指定过期时间为2秒:" + shardedJedis.setex("k003", 2, "v003"));
System.out.println("获取k003的值:" + shardedJedis.get("k003"));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("3秒之后,获取k003的值:" + shardedJedis.get("k003"));
System.out.println("===============获取原值,更新为新值一步完成===============");
System.out.println("k002原来的值:" + shardedJedis.getSet("k002", "v002_after_getset"));
System.out.println("k002新值:" + shardedJedis.get("k002"));
System.out.println("===============获取子串===============");
System.out.println("获取k002的子串:" + shardedJedis.getrange("k002", 5, 7));
}
---------------String功能----------------
清空库中所有数据:OK
=增加=
已经新增5个键值对如下
v001
v002
v003
v004
v005
=删除=
删除k003键值对:1
获取k003键的值:null
=修改=
直接覆盖k001原来得数据:OK
获取k001对应的 新值:value001-update
在k002原来得值后面追加:17
k002追加后的值为:v002+appendString
=增、删、查(多个)=
一次性新增k201,k202,k203,k204及其对应的值:OK
一次性获取k201,k202,k203,k204的各自对应的值:[v201, v202, v203, v204]
一次性删除k201,k202:2
一次性获取k201,k202,k203,k204的各自对应的值:[null, null, v203, v204]
=sharedJedis操作=
清空库中所有数据:OK
=新增键值对时防止覆盖原来得值=
原来k001不存在的时候添加k001:1
原来k002不存在的时候添加k002:1
原来k002不存在的时候添加k002:0
获取k001的值:v001
获取k002的值:v002
=超过有效期的键值对被删除=
新增k003,并指定过期时间为2秒:OK
获取k003的值:v003
3秒之后,获取k003的值:null
=获取原值,更新为新值一步完成=
k002原来的值:v002
k002新值:v002_after_getset
=获取子串=
获取k002的子串:aft
2.4.3 List
private void ListOperate() {
System.out.println("---------------List功能----------------");
// 清空数据
System.out.println("清空库中所有数据" + jedis.flushDB());
System.out.println("==========增==========");
shardedJedis.lpush("stringlist", "vector");
shardedJedis.lpush("stringlist", "ArrayList");
shardedJedis.lpush("stringlist", "vector");
shardedJedis.lpush("stringlist", "vector");
shardedJedis.lpush("stringlist", "LinkedList");
shardedJedis.lpush("stringlist", "MapList");
shardedJedis.lpush("stringlist", "SerialList");
shardedJedis.lpush("stringlist", "HashList");
shardedJedis.lpush("numlist", "3");
shardedJedis.lpush("numlist", "2");
shardedJedis.lpush("numlist", "4");
shardedJedis.lpush("numlist", "5");
System.out.println("stringlist所有元素:" + shardedJedis.lrange("stringlist", 0, -1));
System.out.println("numlist所有元素:" + shardedJedis.lrange("numlist", 0, -1));
System.out.println("========删========");
// 删除列表指定的值,第二个参数为删除的个数(有重复时),后add进去的值先被删除,类似于出栈
System.out.println("stringlist成功删除指定元素个数" + shardedJedis.lrem("stringlist", 2, "vector"));
System.out.println("stringlist删除指定元素后" + shardedJedis.lrange("stringlist", 0, -1));
// 删除区间之外的数据
System.out.println("stringlist删除下标0-3区间之外的元素:" + shardedJedis.ltrim("stringlist", 0, 3));
System.out.println("stringlist删除下标0-3区间之外的元素后:" + shardedJedis.lrange("stringlist", 0, -1));
// 列表元素出栈
System.out.println("stirnglist列表元素出站:" + shardedJedis.lpop("stringlist"));
System.out.println("stringlist元素出栈后:" + shardedJedis.lrange("stringlist", 0, -1));
System.out.println("=======修改=======");
// 修改列表中指定下标的值
shardedJedis.lset("stringlist", 0, "Hello World!");
System.out.println("stringlist下标为0 的值修改之后:" + shardedJedis.lrange("stringlist", 0, -1));
System.out.println("=======查=======");
System.out.println("stringlist长度:" + shardedJedis.llen("stringlist"));
System.out.println("numlist长度:" + shardedJedis.llen("numlist"));
// 排序
/**
* list中存字符串时必须指定参数为alpha,如果不使用SortingParams,而是直接使用sort("list"), 会出现"ERR
* One or more scores can't be converted into double"
*/
SortingParams sortingParams = new SortingParams();
sortingParams.alpha();
sortingParams.limit(0, 3);
System.out.println("stringlist返回排序后的结果:" + shardedJedis.sort("stringlist", sortingParams));
System.out.println("numlist返回排序后的结果:" + shardedJedis.sort("numlist"));
// 子串:start为元素下标,end也为元素下标,-1代表倒数第一个元素,-2代表倒数第二个元素
System.out.println("子串——第二个元素开始到结束:" + shardedJedis.lrange("stringlist", 1, -1));
// 获取列表指定小标的值
System.out.println("获取小标为2的元素:" + shardedJedis.lindex("stringlist", 2) + "\n");
}
---------------List功能----------------
清空库中所有数据OK
增
stringlist所有元素:[HashList, SerialList, MapList, LinkedList, vector, vector, ArrayList, vector]
numlist所有元素:[5, 4, 2, 3]
删
stringlist成功删除指定元素个数2
stringlist删除指定元素后[HashList, SerialList, MapList, LinkedList, ArrayList, vector]
stringlist删除下标0-3区间之外的元素:OK
stringlist删除下标0-3区间之外的元素后:[HashList, SerialList, MapList, LinkedList]
stirnglist列表元素出站:HashList
stringlist元素出栈后:[SerialList, MapList, LinkedList]
=修改=
stringlist下标为0 的值修改之后:[Hello World!, MapList, LinkedList]
=查=
stringlist长度:3
numlist长度:4
stringlist返回排序后的结果:[Hello World!, LinkedList, MapList]
numlist返回排序后的结果:[2, 3, 4, 5]
子串——第二个元素开始到结束:[MapList, LinkedList]
获取小标为2的元素:LinkedList
2.4.4 Set
private void SetOperate() {
System.out.println("---------------Set功能----------------");
// 清空数据
System.out.println("清苦库中所有数据:" + jedis.flushDB());
System.out.println("=======新增=======");
System.out.println("向sets集合中加入元素element001:" + jedis.sadd("sets", "element001"));
System.out.println("向sets集合中加入元素element002:" + jedis.sadd("sets", "element002"));
System.out.println("向sets集合中加入元素element003:" + jedis.sadd("sets", "element003"));
System.out.println("向sets集合中加入元素element004:" + jedis.sadd("sets", "element004"));
System.out.println("查看sets集合中的所有元素:" + jedis.smembers("sets") + "\n");
System.out.println("=======删除=======");
System.out.println("集合中删除element002:" + jedis.srem("sets", "element002"));
System.out.println("查看sets集合中的所有元素:" + jedis.smembers("sets"));
System.out.println("=======查======");
System.out.println("判断element001是否在集合sets中:" + jedis.sismember("sets", "element001"));
System.out.println("循环查询获取sets中的每个元素:");
Set<String> sets = jedis.smembers("sets");
Iterator iterator = sets.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("======集合运算======");
System.out.println("sets1中添加元素element001:" + jedis.sadd("sets1", "element001"));
System.out.println("sets1中添加元素element002:" + jedis.sadd("sets1", "element002"));
System.out.println("sets1中添加元素element003:" + jedis.sadd("sets1", "element003"));
System.out.println("sets2中添加元素element002:" + jedis.sadd("sets2", "element002"));
System.out.println("sets2中添加元素element003:" + jedis.sadd("sets2", "element003"));
System.out.println("sets2中添加元素element004:" + jedis.sadd("sets2", "element004"));
System.out.println("查看sets1集合中所有的元素:" + jedis.smembers("sets1"));
System.out.println("查看sets2集合中所有的元素:" + jedis.smembers("sets2"));
System.out.println("sets1和sets2交集:" + jedis.sinter("sets1", "sets2"));
System.out.println("sets1和sets2并集:" + jedis.sunion("sets1", "sets2"));
// 差集:sets1中有,sets2中没有的元素
System.out.println("sets1和sets2差集:" + jedis.sdiff("sets1", "sets2"));
}
---------------Set功能----------------
清苦库中所有数据:OK
=新增=
向sets集合中加入元素element001:1
向sets集合中加入元素element002:1
向sets集合中加入元素element003:1
向sets集合中加入元素element004:1
查看sets集合中的所有元素:[element004, element003, element001, element002]
=删除=
集合中删除element002:1
查看sets集合中的所有元素:[element004, element003, element001]
=查
判断element001是否在集合sets中:true
循环查询获取sets中的每个元素:
element004
element003
element001
集合运算
sets1中添加元素element001:1
sets1中添加元素element002:1
sets1中添加元素element003:1
sets2中添加元素element002:1
sets2中添加元素element003:1
sets2中添加元素element004:1
查看sets1集合中所有的元素:[element003, element001, element002]
查看sets2集合中所有的元素:[element004, element003, element002]
sets1和sets2交集:[element003, element002]
sets1和sets2并集:[element001, element003, element002, element004]
sets1和sets2差集:[element001]
2.4.5 SortedSet(有序集合)
private void SortedSetOperate() {
System.out.println("---------------SortedSet(有序集合)功能----------------");
// 清空数据
jedis.flushDB();
System.out.println("======新增=====");
// zset中添加元素
jedis.zadd("zset", 7.0, "element001");
jedis.zadd("zset", 8.0, "element002");
jedis.zadd("zset", 5.0, "element003");
jedis.zadd("zset", 3.0, "element004");
jedis.zadd("zset", 2.0, "element005");
jedis.zadd("zset", 1.0, "element006");
jedis.zadd("zset", 4.0, "element007");
jedis.zadd("zset", 6.0, "element008");
jedis.zadd("zset", 9.0, "element009");
// 按照权重值排序
System.out.println("zset集合中所有元素:" + jedis.zrange("zset", 0, -1));
System.out.println();
System.err.println("======删除=====");
System.out.println("zset中删除元素element002:" + jedis.zrem("zset", "element002"));
System.out.println("zset集合中所有元素:" + jedis.zrange("zset", 0, -1));
System.out.println("=======查=======");
System.out.println("统计zset集合中的元素个数:" + jedis.zcard("zset"));
System.out.println("统计zset集合中权重在某个范围内(1.0-5.0),元素的个数:" + jedis.zcount("zset", 1.0, 5.0));
System.out.println("查看zset集合中element004的权重:" + jedis.zscore("zset", "element004"));
System.out.println("查看下标1到2范围内的元素值:" + jedis.zrange("zset", 1, 2));
}
---------------SortedSet(有序集合)功能----------------
==新增=
zset集合中所有元素:[element006, element005, element004, element007, element003, element008, element001, element002, element009]
zset中删除元素element002:1
zset集合中所有元素:[element006, element005, element004, element007, element003, element008, element001, element009]
=查=
统计zset集合中的元素个数:8
统计zset集合中权重在某个范围内(1.0-5.0),元素的个数:5
查看zset集合中element004的权重:3.0
查看下标1到2范围内的元素值:[element005, element004]
2.4.6 Hash
private void HashOperate() {
System.out.println("---------------Hash功能----------------");
System.out.println("清空库中的数据:" + jedis.flushDB());
System.out.println("======新增======");
System.out.println("hashs中添加h-k001和h-v001键值对:" + jedis.hset("hashs", "h-k001", "h-v001"));
System.out.println("hashs中添加h-k002和h-v002键值对:" + jedis.hset("hashs", "h-k002", "h-v002"));
System.out.println("hashs中添加h-k003和h-v003键值对:" + jedis.hset("hashs", "h-k003", "h-v003"));
System.out.println("hashs中添加h-k004和4的整型键值对:" + jedis.hincrBy("hashs", "h-k004", 4));
System.out.println("设置hashs过期时间为5秒" + jedis.expire("hashs", 5));
System.out.println("hashs中的所有值:" + jedis.hvals("hashs"));
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("6秒后hashs中的所有值:" + jedis.hvals("hashs"));
System.out.println();
System.out.println("======删除=====");
System.out.println("hashs中删除h-k002键值对:" + jedis.hdel("hashs", "h-k002"));
System.out.println("hashs中所有的键值对: " + jedis.hvals("hashs"));
System.out.println("=======修改=======");
System.out.println("h-k004键值对的值增加100;" + jedis.hincrBy("hashs", "h-k004", 100));
System.out.println("hashs中所有值:" + jedis.hvals("hashs"));
System.out.println("========查看=======");
System.out.println("判断h-k003是否存在:" + jedis.hexists("hashs", "h-k003"));
System.out.println("获取h-k004对应的值:" + jedis.hget("hashs", "h-k004"));
System.out.println("获取h-k001和h-k003对应的值:" + jedis.hmget("hashs", "h-k001", "h-k003"));
System.out.println("获取hashs中所有的key:" + jedis.hkeys("hashs"));
System.out.println("获取hashs中所有的values:" + jedis.hvals("hashs"));
}
---------------Hash功能----------------
清空库中的数据:OK
新增
hashs中添加h-k001和h-v001键值对:1
hashs中添加h-k002和h-v002键值对:1
hashs中添加h-k003和h-v003键值对:1
hashs中添加h-k004和4的整型键值对:4
==删除=
设置hashs过期时间为5秒1
hashs中的所有值:[h-v001, h-v002, h-v003, 4]
6秒后hashs中的所有值:[]
==删除=
hashs中删除h-k002键值对:0
hashs中所有的键值对: []
=修改=
h-k004键值对的值增加100;100
hashs中所有值:[100]
==查看=
判断h-k003是否存在:false
获取h-k004对应的值:100
获取h-k001和h-k003对应的值:[null, null]
获取hashs中所有的key:[h-k004]
获取hashs中所有的values:[100]
三、Redis的主从复制,读写分离,主从切换
当数据量变得庞大的时候,读写分离还是很有必要的。同时避免一个redis服务宕机,导致应用宕机的情况,我们启用sentinel(哨兵)服务,实现主从切换的功能。
redis提供了一个master,多个slave的服务。
准备三个redis服务,依次命名文件夹子redis_master,redis_slaver1,redis_slaver2.这里为在测试机上,不干扰原来的redis服务,我们redis_master使用6000端口。
3.1 主从复制—修改配置文件(redis.windows.conf)
master配置修改端口:
port 6000
slave1修改配置:
port 6001
slaveof 127.0.0.1 6000
slave2修改配置:
port 6002
slaveof 127.0.0.1 6000
启动三台服务器
同样启动其他两台服务器,启动其余两台slave的时候,master报如下,就成功了。
master 新建aa,slave1中能查看到,成功了。
3.2 主从切换—修改配置
除了修改主从复制的配置外,创建并修改sentinel.conf,该模式使用了sentinel,所以我们需要复制3份sentinel.conf配置文件,其中修改sentinel.conf配置文件中的如下几个参数:
redis_master中sentinel.conf的配置
#当前Sentinel服务运行的端口
port 26000
#Sentinel去监视一个名为mymaster的主redis实例,这个主实例的IP地址为本机地址127.0.0.1,端口号为6001,而将这个主实例判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行
sentinel monitor mymaster 127.0.0.1 6000 2
#指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
sentinel parallel-syncs mymaster 1
#指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行
sentinel down-after-milliseconds mymaster 5000
#如果在该时间(ms)内未能完成failover操作,则认为该failover失败
sentinel failover-timeout mymaster 15000
#设置master和slaves验证密码
#sentinel auth-pass mymaster 123456
redis_slaver1中sentinel.conf的配置
#当前Sentinel服务运行的端口
port 26001
sentinel monitor mymaster 127.0.0.1 6000 2
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 15000
#sentinel auth-pass mymaster 123456
redis_slaver2中sentinel.conf的配置
#当前Sentinel服务运行的端口
port 26002
sentinel monitor mymaster 127.0.0.1 6000 2
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 15000
#sentinel auth-pass mymaster 123456
分别启动master,slave1,slave2
启动命令分别如下:
redis-server.exe redis.windows.conf
分别启动sentinel1,sentinel2,sentinel3
启动命令分别如下:
redis-server.exe sentinel.conf --sentinel
3.2.1 查看redis服务器状态
主服务器状态
从服务器状态
3.2.2 查看sentinel的状态
3.3、redis主从自动failover测试
1、停止master服务器
2、查看剩余服务器的状态
从上图中可以看出来,master的服务器端口从6000变成了6002,也就是说redis自动的实现了主从切换,我们可以在查看下sentinel的状态,如下: