1 Redis缓存
1.1 Redis介绍
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
性能问题: 读速度 11.2万次/秒 ,写 8.6万次/秒 ,平均 10万次/秒。
1.2 为什么需要使用缓存
说明:使用缓存可以有效的降低用户访问物理设备的频次,有效的减少并发的压力。保护后端真实的服务器。
1.3 缓存应该如何设计
1.缓存使用K-V的数据结构,且key必须唯一。
2.由于缓存需要进行快速的读取,所以开发语言为C语言,且软件运行在内存中。
3.将内存(缓存)中数据持久化到磁盘中,可以有效防止内存数据丢失。
4.内存空间优化算法:LRU算法/LFU算法。
5.缓存使用高可用(HA)部署Redis集群,可以防止宕机带来的影响。
1.4 Redis安装(Linux环境下)
上传安装包,之后解压,解压完成后安装Redis
说明:在Redis根目录中执行
1)make
2)make install
1.5 修改Redis配置文件
1.5.1 补充说明
1).补充
如果修改配置文件时,出现了.swp文件,则表示上一次改文件没有正确的保存,生成了保护性文件.所以一般删除改文件即可
方式1: 如果提示按D删除,则按D
方式2: 如果没有按D提示,则 采用 rm -rf .xxxxx.swp
1.5.2 编辑redis.conf
1)命令 vim redis.conf
2)修改IP绑定
3) 修改保护模式
4)开启后台启动
1.5.3 关于Redis服务器的命令
1.启动Redis redis-server redis.conf
2.进入客户端 redis-cli -p 6379
3.关闭Redis redis-cli -p 6379 shutdown
简化操作: 如果操作的redis是默认的端口 则可以省略不写。
1.6 Redis命令
1.6.1 String类型
1.6.2 Hash类型
说明:可以用散列类型保存对象和属性值。
例子:User对象{id:2,name:小明,age:19}
1.6.3 List类型
说明:Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据.
List集合可以当做队列使用,也可以当做栈使用。
队列:存入数据的方向和获取数据的方向相反。
栈:存入数据的方向和获取数据的方向相同。
1.6.4 事务命令
说明:redis中操作可以添加事务的支持.一项任务可以由多个redis命令完成,如果有一个命令失败导致入库失败时.需要实现事务回滚.
1.7 Redis入门案例
1.7.1 导入jar包
<!--spring整合redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
1.7.2 编辑测试类
package com.jt.test;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.SetParams;
public class TestRedis {
/**
* 1.spring整合redis
* 报错说明:
* 1).如果测试过程中报错 则检查redis配置文件 改3处
* 2).检查redis启动方式 redis-server redis.conf
* 3).检查Linux的防火墙
* 做完的 测试其他命令.
*/
@Test
public void testString01() {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
//2.操作redis
jedis.set("a", "redis入门案例");
String value = jedis.get("a");
System.out.println(value);
}
@Test
public void testString02() {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
//2.判断当前数据是否存在
if(jedis.exists("a")) {
System.out.println(jedis.get("a"));
}else {
jedis.set("a", "测试是否存在的方法");
}
}
/**
* 1.能否简化是否存在的判断
* 2.如果该数据不存在时修改数据,否则不修改
* setnx方法: 只有当数据不存在时赋值.
*/
@Test
public void testString03() {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.setnx("a", "测试setnx方法1");
jedis.setnx("a", "测试setnx方法2");
System.out.println(jedis.get("a"));
}
/**
* 为数据添加超时时间
* @throws InterruptedException
* setex方法 保证赋值操作和添加超时时间的操作的原子性
* 原子性: 要么同时成功,要么同时失败(类似事务)
*/
@Test
public void testString04() throws InterruptedException {
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.set("a", "aaaa"); //如果程序报错,则超时方法将不会执行,改数据将永不超时
//程序报错,意外终止!!!!!!!
jedis.expire("a", 20); //添加超时时间 不是原子性操作
Thread.sleep(2000);
System.out.println("剩余存活时间:"+jedis.ttl("a"));
//2.实现原子性操作
jedis.setex("b", 20, "原子性测试");
System.out.println(jedis.get("b"));
}
/**
*
* 1.只有数据不存在时允许修改
* 2.要求实现添加超时时间,并且是原子性操作
* SetParams 参数说明:
* 1.NX 只有key不存在时才能修改
* 2.XX 只有key存在时,才能修改
* 3.PX 添加的时间单位是毫秒
* 4.EX 添加的时间单位是秒
*/
@Test
public void testString05(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
SetParams params = new SetParams();
params.xx().ex(20);
jedis.set("aa", "测试A", params);
jedis.set("aa", "测试B", params);
System.out.println(jedis.get("aa"));
}
/**
* 存储一类数据时,可以使用hash.
*/
@Test
public void testHASH(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.hset("user", "name", "tomcat");
jedis.hset("user", "id", "100");
System.out.println(jedis.hgetAll("user"));
}
@Test
public void testList(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
jedis.lpush("list", "1","2","3","4");
System.out.println(jedis.rpop("list"));
}
//控制事务
@Test
public void testTx(){
//1.创建jedis对象
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.flushAll(); //清空所有的redis缓存
Transaction transaction = jedis.multi(); //2.开启事务
try {
transaction.set("aaa", "aaa");
transaction.set("bbb", "bbbbb");
transaction.set("ccc", "cccccc");
transaction.exec(); //事务提交
} catch (Exception e) {
e.printStackTrace();
transaction.discard(); //事务回滚
}
}
}