当并发访问比较高时,一直访问数据库会造成大量的压力,导致性能的下降,严重时直接导致系统宕机。所以我们就需要一个对访问进行缓存的数据库为数据库进行分担压力。所以我们就需要使用redis。
Redis是一个key-value存储系统,是一个分布式缓存数据库。
安装redis数据库第一步:下载镜像文件
docker pull redis
第二步:准备配置文件
创建redis配置文件目录
mkdir -p /usr/local/docker/redis01/conf
在配置文件录下创建redis.conf配置文件(这个文件一定要创建,否在我们进行目录挂载时默认生成的是一个目录)
touch /usr/local/docker/redis01/conf/redis.conf
第三步:创建redis实例并启动
sudo docker run -p 6379:6379 --name redis01
-v /usr/local/docker/redis01/data:/data
-v /usr/local/docker/redis01/conf/redis.conf:/etc/redis/redis.conf
-d redis redis-server /etc/redis/redis.conf
第四步:查看正在运行的程序
访问redis服务器dicker ps
第一步:控制台直接连接redis测试
docker exec -it redis01 bash
第二步:检测redis 版本
redis-server -v
或者
redis-cli -v
第三步:登录redis(默认不需要密码)
redis-cli
或者直接将上面的两个步骤合为一个步骤执行也可以,指令如下:
docker exec -it redis01 redis-cli
停止和启动redis服务
停止
docker stop redis01
启动
docker start redis01
重启
docker restart redis01
可以进行查看进入redis 并执行短句验证成功:
查看启动的redis进程信息
ps -ef|grep redis
登录redis服务
登录本地:
redis-cli
或者
redis-cli -p 6379
或者
redis-cli -p 6379 -a password #-a后面为password,此操作需要开启redis.conf文件中的 requirepass选项
登录远程redis:
关闭redis服务redis-cli -h ip -p 6379 -a password
127.0.0.1:6379> shutdown
系统帮助:可以基于help指令查看相关指令帮助:
127.0.0.1:6379> help redis-cli 2.8.19 Type: "help @" to get a list of commands in "help " for help on "help " to get a list of possible help topics "quit" to exit
127.0.0.1:6379> help type TYPE key summary: Determine the type stored at key since: 1.0.0 group: genericRedis数据存储操作:
查看redis中所有的key:
基于key/value形式存储数据127.0.0.1:6379> keys *
(empty list or set)
获取使用get:
清除redis中的数据:清除当前数据库数据:
flushdb
清除所有数据库数据:
设置时效:单位一般默认为毫秒flushall
expire
其中,TTL查看key的剩余时间,当返回值为-2时,表示键被删除。
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。
取现时长设置:
Redis常用的数据类型:Persist (取消时长设置)
Reids中基础数据结构包含字符串、散列,列表,集合,有序集合。工作中具体使用哪种类型要结合具体场景。
String类型操作实践字符串类型是redis中最简单的数据类型,它存储的值可以是字符串,其最大字符串长度支持到512M。基于此类型,可以实现博客的字数统计,将日志不断追加到指定key,实现一个分布式自增iid,实现一个博客的的点赞操作等
incr/incrby 递增当存储的字符串是整数时,redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。
如果数值为空,则自动增加1.
decr/decrby 递减incr key 自动增加1. incrby key 2 根据自己定义数据自增
append 尾部追加值decr key 自减1 decrby key 3 根据自定义递减
strlen 返回字符串长度append key 20 根据自己定义的数值进行追加并返回总长度
如果键值为0返回的也是0
mset/mget 设置多个值/获取多个值Hash类型应用实践mset x 1 y 2 z 3 / mget x y z
Redis散列类型相当于Java中的HashMap,实现原理跟HashMap一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多232-1个字段。
hset/hget 赋值和取值hgetall 为得到全部对应hsah值
HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。
hmset/hmget 同时执行多个hash集合 hexists 判断属性是否存在存在返回 1 不存在返回 0
hdel 删除属性 hkeys/hvals 只获取字段名/只获取字段值 hlen 获取元素的个数
List类型应用实践
Redis的list类型相当于java中的linkedList,其原理就就是一个双向链表。支持正向、反向查找和遍历等操作,插入删除速度比较快。经常用于实现热销榜,最新评论等的设计。
lpush / lrange 创建list集合 /获取list值lpush key xxx 将数值xxx存入 key集合中
lrange key 0 -1 从列表第一个开始 到最后一个结束
其中,Redis Lrange 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推
rpush 在对应list尾部添加字符串 linsert 在对应list的特定位置前后添加字符串 lset 修改指定的下标元素 lrem 删除list中与定义的数字相同value元素且删除的value也相同才可。 当定义的数字大于0时从头到尾删除,当小于0时从尾到头
ltrim 保留指定key的取值范围lpop 从list头部删除元素 lindex 根据下标返回对应的元素
rpoplpush
从第一个list的尾部移除元素并添加到第二个list的头部,最后返回被移除的元素值,整个操作是原子的.如果第一个list是空或者不存在返回nil:
rpoplpush lst1 lst1
rpoplpush lst1 lst2
del 清除集合元素
Set类型应用实践
Redis的Set类似Java中的HashSet,是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
sadd 添加元素 smembers 获取元素重复添加会失败 返回0
spop 移除集合中的一个随机元素。。。。
scard 获取集合中成员个数
smove 移动一个元素到另外一个集合 sunion 实现集合的并集操作java中应用redis
创建meven工程
添加相关依赖:
redis.clients
jedis
3.5.2
com.google.code.gson
gson
2.8.6
通过Jedis连接redis,并进行测试。
public class JedisTests {
@Test
public void testGetConnection(){
//通过jedis对象连接redis
Jedis jedis = new Jedis("192.168.64.131", 6379);
//添加数据
jedis.set("id","100");
jedis.set("name","tome");
//进行修改数据
jedis.incr("id");
jedis.incrBy("id",100);
jedis.set("name","tom");
//得到数据
String id = jedis.get("id");
String name = jedis.get("name");
System.out.println(id+name);
//删除数据
// jedis.del("id","name");
//释放资源
jedis.close();
}
}
测试字符串操作:
@Test
public void test2(){
//通过jedis对象连接redis
Jedis jedis = new Jedis("192.168.64.131", 6379);
HashMap
测试list:
测试list结构
*/
@Test
public void test3(){
//通过jedis对象连接redis
Jedis jedis = new Jedis("192.168.64.131", 6379);
//存储数据
jedis.lpush("list110","a","b","c","d");
//更改数据
Long lpos = jedis.lpos("list110", "a");//获取a的位置
jedis.lset("list110",lpos,"E");//将a换成E
//获取数据
int list1 = jedis.llen("list110").intValue();//获取list元素个数
List lll = jedis.lrange("list110", 0, -1);
System.out.println(lll);
List list11 = jedis.rpop("list110", list1);//获取并删除list所有元素
System.out.println(list11);
jedis.close();
测试set类型
@Test
public void test4(){
//通过jedis对象连接redis
Jedis jedis = new Jedis("192.168.64.131", 6379);
jedis.sadd("lsp","1","2","3");
Set lsp = jedis.smembers("lsp");
System.out.println(lsp);
jedis.close();
}
创建JedisPool连接池
我们直接基于Jedis访问redis时,每次获取连接,释放连接会带来很大的性能开销,可以借助Jedis连接池,重用创建好的连接,来提高其性能,简易应用方式如下:
public class JedisDataSource {
private static final String IP = "192.168.64.131";
private static final int PORT = 6379; //redis.conf 默认端口号
private static volatile JedisPool jedisPool;
//懒汉式池对象的创建
public static Jedis getConnection(){
if (jedisPool == null){
synchronized (JedisDataSource.class){
if (jedisPool==null){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(16);
jedisPoolConfig.setMaxIdle(8);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, IP, PORT);
//创建对象分析
//1.开辟内存空间
//2.执行属性的默认初始化
//3.执行构造方法
//4.将创建的对象的内存地址赋值给jedisPool变量
//假如使用了volatile修饰jedisPool变量,可以保证如上几个步骤是顺序执行的
}
}
}
return jedisPool.getResource();
}
public static void close(){
jedisPool.close();
}
RedisTemplate
RedisTemplate为SpringBoot工程中操作redis数据库的一个Java对象,此对象封装了对redis的一些基本操作。是一个比上面方法方便的方式。
添加对应依赖:
org.springframework.boot spring-boot-dependencies2.3.2.RELEASE import pom org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-data-redisorg.springframework.boot spring-boot-starter-testtest
在yml配置中进行配置:
spring:
redis:
host: 192.168.64.131
port: 637
相应测试,存储数据,存储对象。
@SpringBootTest
public class test00 {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void lsp() throws JsonProcessingException {
//通过调用底层的对应方法进行实现数据存储
ValueOperations vo = redisTemplate.opsForValue();
vo.set("id","66");
Object id = vo.get("id");
System.out.println(id);
//设置数据存活时间
vo.set("z","100", Duration.ofSeconds(100));
//更新数据
String s = UUID.randomUUID().toString();
vo.set(s,"mike3");
vo.set(s,"mike2");
vo.set(s,"mike1");
Object o = vo.get(s);
System.out.println(o); //数据会进行覆盖
//获取Hash操作对象
HashOperations ho = redisTemplate.opsForHash();
ho.put("lsp","id",100);
ho.put("lsp","name","lll");
Object o1 = ho.get("lsp", "id");
Object o2 = ho.get("lsp", "name");
System.out.println(o1+"name"+o2);
//将对象写入redis数据库
ValueOperations vo2 = redisTemplate.opsForValue();
user01 user01 = new user01();
user01.setId(10);
user01.setName("王大陆");
//将对象转换为json串
ObjectMapper objectMapper = new ObjectMapper();
String s1 = objectMapper.writevalueAsString(user01);
vo2.set("6",s1);
Object o3 = vo2.get("6");
System.out.println(o3);
}
}



