1 jedis简介
jedis的是一款用于redis的数据库的Java客户端工具, jedis提供了一套非常省力的API, 其最大的特点就是其API和redis的命令是相同的, 这样就大大降低了学习的成本, 其本身也是redis官方推荐的一款javaAPI
2 jedis的入门
- 导入相关jedis的包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2、入门代码
@Test
public void jedisOne() {
//1. 创建jedis对象
Jedis jedis = new Jedis("192.168.72.144",6379);
//2. 测试是否连通
String pong = jedis.ping();
//返回PONG 表示已经连通
System.out.println(pong);
//3. 释放资源
jedis.close();
}
3、 jedis的常用API
/**
* jedis操作redis--> String
*
* String类型的应用场景:
* 做缓存
* @throws InterruptedException
*/
@Test
public void jedisOfString() throws InterruptedException {
//1. 创建jedis的对象
Jedis jedis = new Jedis("192.168.72.144", 6379);
//2. 执行相关操作:
//2.1 向redis中存值
jedis.set("age", "19");
//2.2 向redis中获取值
String age = jedis.get("age");
System.out.println(age);
//2.3 删除值
//jedis.del("age");
//2.4 为age进行+1操作
Long incr = jedis.incr(age);
System.out.println(incr);
//2.5 为age进行-1操作
Long decr = jedis.decr("age");
System.out.println(decr);
//2.6 拼接字符串: 如果key存在就是拼接, 如果不存在就会重新创建
jedis.append("hobby", "篮球");
String hobby = jedis.get("hobby");
System.out.println(hobby);
//2.7 为key 设置有效时长
//为已有的key设置有效时间
Long expire = jedis.expire("hobby", 5);
System.out.println(expire);//返回1 表示设置成功, 返回0 表示该key不存在
while(jedis.exists("hobby")) {
System.out.println(jedis.ttl("hobby"));//返回-1 表示永久有效, -2 key不存在
Thread.sleep(1000);
}
//为新建的key设置有效时间
jedis.setex("date", 10, "2018.9.15");
while(jedis.exists("date")) {
System.out.println(jedis.ttl("date"));
Thread.sleep(1000);
}
//3. 释放资源
jedis.close();
}
4 使用jedis操作redis–>list
/**
* 使用jedis操作redis --> list
*
* list可以将其看做是java的队列类似
*
* list数据类型的应用场景: 任务队列
*/
@Test
public void jedisOfList() {
//1. 创建jedis对象
Jedis jedis = new Jedis("192.168.72.144",6379);
//执行操作前删清空集合中的数据,否则会一直往里面添加
jedis.del("list1");
jedis.del("list2");
//2. 执行list相关的操作
//2.1 添加数据: 从左侧添加
jedis.lpush("list1", "a","b","c","d");
//2.2 弹出数据: 从右侧弹出数据
String rElement = jedis.rpop("list1");
System.out.println(rElement);
//2.3 添加数据: 从右侧添加
jedis.rpush("list2", "a","b","c","d");
//2.4 弹出数据: 从左侧弹出
String lElement = jedis.lpop("list2");
System.out.println(lElement);
//2.5 查看整个list中某个范围间的数据: start: 开始 end: 结束 0~-1 表示查询全部
List<String> list = jedis.lrange("list1", 0, -1);
System.out.println(list);
//2.6 获取元素中个数
Long llen = jedis.llen("list2");
System.out.println(llen);
//2.7 在 b元素之前插入0
jedis.linsert("list1", LIST_POSITION.BEFORE, "b", "0");
//2.8 在 c元素的后面插入1
jedis.linsert("list1", LIST_POSITION.AFTER, "c", "1");
//2.9 将最后一个元素弹出并将其添加某个list的头部(也可以是自己)
jedis.rpoplpush("list1", "list1");
list = jedis.lrange("list1", 0, -1);
System.out.println(list);
//3. 释放资源
jedis.close();
}
5 使用jedis操作redis –> hash
/**
* 使用jedis操作redis --> hash
*
* redis中hash和java中的hashMap类似
*
* hash的应用场景:
* 做缓存(目前使用较少,大部分的业务场景可以被String替代掉)
*/
@Test
public void jedisOfHash() {
//1. 创建jedis对象
Jedis jedis = new Jedis();
//2.执行操作hash的相关API
//2.1 添加数据
jedis.hset("persion", "name", "隔壁老王");
jedis.hset("persion", "age", "30");
jedis.hset("persion", "birthday", "1988年9.15");
//2.2 获取数据
String name = jedis.hget("persion", "name");
String age = jedis.hget("persion", "age");
String birthday = jedis.hget("persion", "birthday");
//2.3 一次性获取多个hash中的key的值
List<String> values = jedis.hmget("persion", "name","age");
System.out.println(values);
//2.4 获取hash所有的数据
Map<String, String> map = jedis.hgetAll("persion");
for (String key : map.keySet()) {
System.out.println(key+" "+ map.get(key));
}
//2.5 获取map中所有的key 和 所有的value
Set<String> hkeys = jedis.hkeys("persion");
List<String> hvals = jedis.hvals("persion");
System.out.println(hkeys );
System.out.println(hvals );
//2.6 删除map中的某个key
jedis.hdel("persion", "name","age"); //删除map的name和age
//2.7 删除整个map
jedis.del("persion");
//3. 释放资源
jedis.close();
}
6 使用jedis操作redis –>sortedSet
/*
* 使用jedis来操作redis --> sortedSet集合
*
* soredSet 特点: 有序 去重复
*
* sortedSet的的应用场景:
* 排行榜
*
*/
@Test
public void jedisOfsortedSet() {
//1. 创建jedis对象
Jedis jedis = new Jedis("192.168.72.144",6379);
//2. 执行sortedSet的相关的操作
//2.1 添加数据
jedis.zadd("math", 98.2, "老王");
jedis.zadd("math", 59.9,"小明");
jedis.zadd("math", 79,"老张");
jedis.zadd("math", 59.2,"小李");
//2.2 获取某个成员的分数
Double zscore = jedis.zscore("math", "老张");
System.out.println(zscore);
//2.3 查看sortedSet中某个元素的排名: 从小到大
Long zrank = jedis.zrank("math", "小李");
System.out.println(zrank);
//2.4 查看sortedSet中的元素: 从大到小
Set<Tuple> zrevrange = jedis.zrevrangeWithScores("math", 0, -1);
for (Tuple tuple : zrevrange) {
String element = tuple.getElement();
double score = tuple.getScore();
System.out.println(element+" "+ score);
}
//2.4 查看sortedSet中的元素: 从小到大
Set<Tuple> zrange = jedis.zrangeWithScores("math", 0, -1);
for (Tuple tuple : zrange) {
String element = tuple.getElement();
double score = tuple.getScore();
System.out.println(element+" "+ score);
}
//2.5 删除某个元素
jedis.zrem("math", "老张");
//3. 释放资源
jedis.close();
}
jedis连接池
当创建jedis的对象的时候, jedis会连接redis的服务器, 获取一个连接, 如果频繁的创建一个连接, 会造成资源的消耗, 在mysql中如果发生这样的现象, 采用的是连接池的技术,提前创建好几个连接,反复使用即可, 在redis中同样也是如此
jedis在jar中, 已经提供了一个jedis的连接池 叫 jedisPool
- 连接池的基本使用
/*
* jedis连接池的基本使用
*/
@Test
public void jedisPoolOfTest() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
JedisPool jedisPool = new JedisPool(poolConfig, "192.168.72.144", 6379);
Jedis jedis = jedisPool.getResource();
String pong = jedis.ping();
System.out.println(pong);
jedis.close();//归还连接
}
- 抽取一个工具类,专门用来从连接池中获取jedis的连接对象
package com.pjz.jedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisUtils {
private static JedisPool jedisPool;
static {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(5);//闲时最大的数量
poolConfig.setMaxTotal(100); //最大有100个
poolConfig.setMinIdle(3);//最小闲时的数量
jedisPool = new JedisPool(poolConfig, "192.168.72.144", 6379);
}
public Jedis getJedis() {
return jedisPool.getResource();
}
}
redis的持久化
我们知道, redis是将数据存储在了内存当中, 那么当关闭服务器, 内存的资源也就会消失了, 这时存储在redis中的数据也会消失, 那么我们应该如何做呢?
- 在redis中已经提供了两种持久化的方案
- RDB: redis提供的一种基于快照机制实现的持久化方案, 而快照就类似于照相机, 会将一个服务器某个时刻的一个状态整体保存下来, 快照文件一般都非常的小,只有几kb左右
- 优点: 由于持久化的文件非常小, 适合于做灾难恢复
- 缺点: 由于redis中持久化的时机问题, 会存在数据丢失的问题
- AOF: redis提供的一种基于日志机制实现的持久化方案, 会将用户操作(增 删 改)的所有的命令整体的记录下来保存到日志文件中,一般文件都比较庞大
- 优点: AOF机制可以让将用户所有的命令都记录下来, 顾其数据保存的比较完整, 不容易丢失
- 缺点: 持久化的文件比较庞大, 不利于灾难恢复
- RDB: redis提供的一种基于快照机制实现的持久化方案, 而快照就类似于照相机, 会将一个服务器某个时刻的一个状态整体保存下来, 快照文件一般都非常的小,只有几kb左右
- RDB保存机制: redis默认是开启RDB机制
save 900 1 : 在900秒之内,如果有一个数据进行修改,就会执行一下保存
save 300 10 : 在300秒之内, 如果有10个以上的数据被修改, 就会执行一下保存
save 60 10000 : 在60秒之内, 如果有10000个以上的数据被修改. 就会执行一下保存
- 当服务器宕机, 最大丢失数据量为在不到5分钟的时间里丢掉9999个数据
- 一般情况下redis的不会出现宕机的现象, 除非redis中的数据将内存撑爆了, 但这个现象在大公司是不会出现的
- AOF的保存机制:redis默认不开启
如何开启AOF:
- 打开redis的配置文件,修改下列两个参数即可
appendonly yes //默认此项是no,没有启动AOF机制
appendfsync everysec //appendfsync的取值: [always everysec no]
- always: 总是, 只要有新的命令执行, 就将其保存到文件中
- 优点: 数据保存最完整, 几乎不会丢掉数据
- 缺点: 大大降低了redis的性能
- everysec: 每秒钟执行一次保存
- 此种保存不会大幅度的降低redis的性能,但是会丢失最大1s的数据
- no: 不执行保存, 由操作系统自动调用保存(linux一般30分钟刷新一次内存)
- 一般不使用
开发中:
一般小公司会采用AOF + RDB 大公司只会使用RDB