上期我们讲了对于Redis来说最重要的部分,配置文件,持久化与Redis事务的使用.有兴趣的同学可以看一下.
本期为Redis连载的最后收尾篇。主要讲一下在Redis中如果建议Redis集群,以及主从关系.另外就是如何在Java程式中调用Redis.

简介:
主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制.Master以写为主,Slave以读为主.

作用 :
- 读写分享
- 容灾恢复

使用技巧:
- 配从(库)不配主(库)
- 从库配置:slaveof主库IP主库端口(每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件)
- 修改配置文件细节操作
- 常用3招
- 一主二仆
- 薪火相传
- 反客为主
创建集群:

1:通过复制多个redis.conf文件,修改成不同的端口.通过
redis-server /pathxxx/redis.conf 来启动.
# redis.conf位置,/etc/redis/redis.conf
redis-server /pathxxx/redis.conf

打开redis.conf文件
# 打开复制的redis.conf
sudo vim /pathxxx/redis

2:修改各自的port
# 通过/port找到修改port的地方,把端口修改成一个其他任意端口,只要不冲突就可以.
port 6380

3:修改pid文件名
# 通过 /.pid 找到修改 pip 的地方.
pidfile /var/run/redis/redis-server-80.pid

4:修改log文件名
# 通过 /logfile 找到修改log名的地方,进行文件名修改.
logfile /var/log/redis/redis-server-80.log

5:修改rdb文件名
# 通过/dbfilename 找到修改 pip 的地方.
dbfilename dump-80.rdb

6:修改完成保存退出
键盘按下esc键
键盘按下shift+ZZ

7:分别通过以下命令来启动Redis
redis-server /pathxxx/redis.conf

首先要查看本台服务器的基本信息(前提要通过 redis-cli redis.conf登录到当前redis)
info replication
设置从机数据备份,就是如果主机上的数据有什么变化,从机跟着变化.
slaveof 127.0.0.1 6379 [slaveof 主机IP 主机Port]

例如:要主机上面:
# 主机
set k1 v1
# 从机是可以get到的
get k1
| - 从机的数据和主机的数据一样,是从头到尾都有的. |
| - 从机只有读的权限,没办法添加一个新值到Redis. |
| - 当生机挂掉以后,从机会选择待命状态,原值还可以get到. |
| - 主机从down机状态恢复正常后.从机随机恢复连接状态. |
| - 从机down机后重新启动后,除写入配置文件(Redis.conf)以外的情况,需要重新与主机进行连接. |

原因:
单一主机在面对多台从机的时候会变成主机压力较大,比减小主机压力.需要去中心化,在从机上面再挂从机.
操作:
一个slave可以是下一个slave的master.slave同样可以接收其他slave的连接和请求.那么该slave作为下一人slave的master.从而减小主maser的负担 .
设置:
设置非常的简单,像第一台从机一样.只能通过命令直接告诉Redis备用机需要挂载到哪一台下面就好了.
slaveof 127.0.0.1 6380
结果:
当我们在主机master上面添加一个新值的时候,数据首先被第一级从机备份,紧接着被第二级从机备份.此时,两三从机都可以get到最新的数据.

出现原因:
当redis主机down机以后.为了服务器可以正常运行.我们需要选择一台新的机器来作为主机使用.
例如,我们选择一台原来主机的从机作为现在的主机.
执行命令
# 恢复从机的主机身份
# 使当前的数据库停止与其他数据库的同步.转为主库,形成一个新的中心点.
slaveof no one

简介:
反客为主的自动版.
原理:
写一个配置档(固定名称:sentinel.conf)与自定义redis.conf文件同级,设置去监控主机.如果主机出现down机的话.以投票的形式选出一台新主机.
Sentinel.conf
# sentinel monitor 监控主机名(随便启) 监控主机IP 监控主机port 票数(当某一台从机的票数大于这个额度时按票# # 数多少选为主机)
sentinel monitor xiaobaibi-redis 127.0.0.1 6379 1
此时如果之前用6.3中的安装方式的话.redis是不存在redis-sentinel 插件的.需要通过命令进行安装
sudo apt install redis-sentinel
启动sentinel:
# 如果当前路径不是sentinel.conf所有的路径,需要指定文件夹地址
sudo redis-sentinel sentinel.conf
启动成功

结论
当主机因各种原因下线down机时,sentinel会自己从从机中选择一台转换为主机.这个过程大概在主机离线30秒以后.当主机被修复好重新上线以后.会被sentinel安排为新主机的从机.
复制延时
由于所有的写操作都是在master上操作.然后同步更新到Slave上.所有从Master同步到slave机器有一定的延迟.当系统很繁忙的时候,延迟问题会更加严重.Slave机器数量的增加也会使这个问题更加严重.
1> 使用 IDEA 或 Eclipse创建一个普通的 Java Maven项目.
2> 导入 Jedis 的 Maven GVA
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>java-redis</groupId>
<artifactId>jedis-study</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
</project>
3> 创建一个Java测试类,测试连接是否正常
package com.jedis;
import redis.clients.jedis.Jedis;
public class JedisTest {
public static void main(String[] args) {
try {
Jedis jedis = new Jedis("192.168.93.43",6380);
System.out.println(jedis.ping());
}catch (Exception e){
e.printStackTrace();
}
}
}
附:
如果Redis服务器与你的Java程式不在同一台服务器上面.需要对redis.conf进行修改,以让Redis 可以被其他服务器连接到.
修改地方:
# redis 服务器 IP 地址
bind 192.168.93.43
4> API 操作
package com.api;
import redis.clients.jedis.Jedis;
import java.util.Set;
public class RedisAPITest {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.93.43",6381);
// 获取全部的 Key
Set<String> sets = jedis.keys("k*");
for (String key : sets) {
System.out.println(key);
}
// 添加一个 key
jedis.set("j_k1","这是一个 jedis value");
System.out.println(jedis.get("j_k1"));
}
}
5> 事务
package com.trans;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
/**
* 事务测试类
*/
public class RedisTransTest {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.93.43",6381);
// 开启事务
Transaction multi = jedis.multi();
// 执行操作
multi.set("tk1","tv1");
multi.set("tk2","tv2");
multi.set("tk3","tv3");
// 提交操作
multi.exec();
// 放弃本次操作
// multi.discard();
}
}
6> 其他的操作与之前的命令操作几本一样.遇到需要的直接以命令的格式使用即可.
7> 主从复制
package com.mands;
import redis.clients.jedis.Jedis;
/**
* 主从复制
*/
public class RedisMAS {
public static void main(String[] args) {
Jedis jedis80 = new Jedis("192.168.93.43",6380);
Jedis jedis81 = new Jedis("192.168.93.43",6381);
// 将6381修改为6380的从机
jedis81.slaveof("192.168.93.43",6380);
// 主机写值
jedis80.set("k3", "v3");
// 从机读值
System.out.println(jedis81.get("k3"));
}
}

知识点:

连接池主类
package com.pool;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* redis 连接池
*/
public class JedisPoolTools {
private static volatile JedisPool jedisPool = null;
private JedisPoolTools(){};
public static JedisPool getJedisInstance(){
if (jedisPool == null){
synchronized (JedisPoolTools.class){
if (jedisPool == null){
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最多有多少个空闲状态的实例.
poolConfig.setMaxIdle(20);
poolConfig.setMaxWaitMillis(100*1000);
// 获取一个jedis实例的时候是否检查连接可用性.如果为true.得到jedis实例均是可用的.
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig, "192.168.93.43",6380);
}
}
}
return jedisPool;
}
public static void close(JedisPool jedisPool, Jedis jedis){
if (jedis != null){
jedis.close();
}
}
}
连接池测试类
package com.pool;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* 测试类
*/
public class JedisPoolTest {
public static void main(String[] args) {
try {
JedisPool jedisPool = JedisPoolTools.getJedisInstance();
Jedis jedis = jedisPool.getResource();
jedis.set("k4","v4");
jedis.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
今天讲的内容不太多,集群主从复制是非常实用的部分,面试也是重点内容.
Jedis只不过是Java中如何去调用Redis而已.所有的命令都是通过jedis那个对象就可以调用出来.只要会了命令就完全可以直接使用 edis.

公众号回复:
[ redisdemo ] :获取Java的Jedis Demo.
[ redisbook ] : 获取小编学习笔记.





