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 为什么需要使用缓存

说明:使用缓存可以有效的降低用户访问物理设备的频次,有效的减少并发的压力。保护后端真实的服务器。

linux redis 查看key的值 格式化 linux查看redis数据量_缓存

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

linux redis 查看key的值 格式化 linux查看redis数据量_java_02


linux redis 查看key的值 格式化 linux查看redis数据量_Redis_03

1.5 修改Redis配置文件

1.5.1 补充说明

1).补充

如果修改配置文件时,出现了.swp文件,则表示上一次改文件没有正确的保存,生成了保护性文件.所以一般删除改文件即可

方式1: 如果提示按D删除,则按D

方式2: 如果没有按D提示,则 采用 rm -rf .xxxxx.swp

linux redis 查看key的值 格式化 linux查看redis数据量_缓存_04

1.5.2 编辑redis.conf

1)命令 vim redis.conf 2)修改IP绑定

linux redis 查看key的值 格式化 linux查看redis数据量_缓存_05


3) 修改保护模式

linux redis 查看key的值 格式化 linux查看redis数据量_缓存_06


4)开启后台启动

linux redis 查看key的值 格式化 linux查看redis数据量_Test_07

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类型

linux redis 查看key的值 格式化 linux查看redis数据量_redis_08

1.6.2 Hash类型

说明:可以用散列类型保存对象和属性值。

例子:User对象{id:2,name:小明,age:19}

linux redis 查看key的值 格式化 linux查看redis数据量_java_09

1.6.3 List类型

说明:Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据.

List集合可以当做队列使用,也可以当做栈使用。

队列:存入数据的方向和获取数据的方向相反。

栈:存入数据的方向和获取数据的方向相同。

linux redis 查看key的值 格式化 linux查看redis数据量_redis_10

1.6.4 事务命令

说明:redis中操作可以添加事务的支持.一项任务可以由多个redis命令完成,如果有一个命令失败导致入库失败时.需要实现事务回滚.

linux redis 查看key的值 格式化 linux查看redis数据量_java_11

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();		//事务回滚
		}
	}
}