一、Redis Java代码使用
pom文件引入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>
不使用线程池的方式
package com.strivelearn.java.redis;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.JedisFactory;
/**
* @author strivelearn
* @version RedisOp.java, 2022年12月11日
*/
public class RedisOp {
public static void main(String[] args) {
DefaultJedisClientConfig config = DefaultJedisClientConfig.builder()
.password("xys6154@")
.build();
Jedis jedis = new Jedis("192.168.234.100", 6379, config);
String set = jedis.set("student", "zhangsan");
String student = jedis.get("student");
System.out.println(student);
jedis.close();
}
}
使用线程池的方式
package com.strivelearn.java.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Redis连接池方式
*
* @author strivelearn
* @version RedisPoolOp.java, 2022年12月11日
*/
public class RedisPoolOp {
public static void main(String[] args) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//连接池最大空闲连接数
jedisPoolConfig.setMaxIdle(10);
//连接池创建的最大连接数
jedisPoolConfig.setMaxTotal(10);
//创建链接的超时时间
jedisPoolConfig.setMaxWaitMillis(2000);
//表示从连接池中获取链接的时候会测试一下,是否可用,这样可以保证取出的连接都是可用的
jedisPoolConfig.setTestOnBorrow(true);
//获取jedis连接池
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.234.100", 6379);
//从jedis连接池取出一个链接
Jedis resource = jedisPool.getResource();
String zhangsan = resource.get("student");
System.out.println("student" + zhangsan);
//1.如果jedis是直接创建的单链接,此时表示直接关闭这个链接
//2.如果jedis是从连接池中获取的链接,此时会把这个链接返回给连接池
jedisPool.close();
}
}
二、封装Redis工具类
package com.strivelearn.java.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @author xys
* @version RedisUtils.java, 2022年12月11日
*/
public class RedisUtils {
//私有构造函数,禁止new操作
private RedisUtils() {
}
private static JedisPool jedisPool = null;
/**
* 获取redis链接
*
* @return
*/
public static synchronized Jedis getJedis() {
if (jedisPool == null) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//连接池最大空闲连接数
jedisPoolConfig.setMaxIdle(10);
//连接池创建的最大连接数
jedisPoolConfig.setMaxTotal(10);
//创建链接的超时时间
jedisPoolConfig.setMaxWaitMillis(2000);
//表示从连接池中获取链接的时候会测试一下,是否可用,这样可以保证取出的连接都是可用的
jedisPoolConfig.setTestOnBorrow(true);
//获取jedis连接池
jedisPool = new JedisPool(jedisPoolConfig, "192.168.234.100", 6379);
}
return jedisPool.getResource();
}
/**
* 归还redis链接
*
* @param jedis
*/
public static void returnResource(Jedis jedis) {
jedis.close();
}
}
二、Redis高级命令
2.1、expire 生成时间
| 命令 | 格式 | 解释 |
|---|---|---|
| expire | expire key seconds | 设置key的过期时间(单位:秒) |
| ttl | ttl key | 获取key的剩余有效时间 |
| persist | persist key | 取消key的过期时间 |
| expireat | expireat key timestamp | 设置key在指定时间戳过期 |
2.2、pipeline管道
- 针对批量操作数据或者批量初始化数据的时候使用,效率高
- Redis的pipeline功能在命令行中没有实现,在Java客户端(jedis)中可以使用的
管道的原理:相当于一次性交互多条语句,提升效率
package com.strivelearn.java.redis;
import redis.clients.jedis.Jedis;
/**
* @author strivelearn
* @version PipelineMain.java, 2022年12月26日
*/
public class PipelineMain {
public static void main(String[] args) {
Jedis jedis = RedisUtils.getJedis();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
jedis.set("test" + i, "value" + i);
}
long endTime = System.currentTimeMillis();
System.out.println("插入10w条数据,消耗时间:" + (endTime - startTime) / 1000 + "s");
}
}
插入10w条数据,消耗时间:42s
Jedis jedis = RedisUtils.getJedis();
Pipeline pipelined = jedis.pipelined();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
pipelined.set("test1" + i, "value2" + i);
}
long endTime = System.currentTimeMillis();
System.out.println("插入10w条数据,消耗时间:" + (endTime - startTime) + "ms");
插入10w条数据,消耗209ms
三、Redis持久化
- Redis持久化简单理解就是把内存中的数据持久化到磁盘中可以保证Redis重启之后还能恢复之前的数据
- Redis支持两种持久化,可以
单独使用或者组合使用 - RDB(默认方式)和AOF
3.1、RDB(Redis Database)
RDB持久化是通过快照完成,当符合一定条件时Redis会自动将内存中的所有数据执行快照操作并存储到硬盘上,默认存储在dump.rdb文件中
RDB的优点:
- 由于存储的有数据快照文件,恢复数据很方便
RDB的缺点
- 会丢失最后一次快照以后更改的所有数据
3.2、AOF(Append Only File)
AOF持久化是通过日志文件的方式,默认情况下没有开启,可以通过appendonly参数开启。存储在appendonly.aof文件中
四、Redis的安全策略
- 设置Redis密码,在redis.conf配置文件中,requirepass
- 禁用flushall。在redis.conf把flushall进行重命名 rename-command flushall ""
五、Redis监控命令-monitor
六、Redis架构演进
6.1、主从复制
- Redis的复制功能支持多个数据库之间的数据同步
- 通过Redis的复制功能可以很好的实现数据库的
读写分离提高服务器的负载能力。主数据库(Master)主要进行写操作,而从数据库(Slave)负责读操作 - 一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库
存在的问题:
如果master节点挂了,从节点是无法自动切换为主节点的。
6.2、哨兵机制(Sentinel)
- 监控:Sentinel实时监控主服务器和从服务器运行状态
- 提醒:当被监控的某个Redis服务器出现问题时,Sentinel可以向系统管理员发送通知,也可以通过API向其他程序发送通知
- 自动故障转移:当一个主服务器不能正常工作时,Senitinel可以将一个从服务器升级为主服务器,并对其他从服务器进行配置,让它们使用新的主服务器
6.3、集群模式
- Redis集群是一个无中心的分布式Redis存储架构,可以在多个节点之间数据共享,解决了Redis高可用,可扩展等问题
- 一个Redis集群包含
16384个哈希槽(hash slot),数据库中的每个数据都属于这个16384个哈希槽中的一个 - 集群使用公式
CRC16(key)%16384来计算键key属于哪个槽,集群中的每一个节点负责维护一部分哈希槽 - 集群中的每个节点都有1个或者N个复制品,其中一个伪主节点其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作
- 如果一个主节点和它所有的从节点都下线的话,集群就会通知工作了。