Redis是一个基于 内存的 key-value结构数据库
基于内存存储,读写性能高
适合存储热点数据(热点商品,资讯,新闻)
企业应用广泛
适合的场景: 高并发,热点数据
Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库,缓存和消息中间件。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。
NoSql,不仅仅是SQL,泛指非关系型数据库。NOSql数据库并不是要取代关系型数据库,而是关系型
数据库的补充
缓存:
最终我们使用redis,是为了减轻mysql数据库压力,提高用户的体验
任务队列
消息队列
分布式锁
(windows中)
1.解压到非中文路径
2.服务器启动:cmd 后 redis-server redis.windows.conf启动(双击启动是按默认配置启动)
3.客户端启动:redis-cli.exe
4.检验:输入ping,会回pong.
(Linex中)
1.将安装包上传到Linex
2.解压:tar -zxvf redis-4.0.0.tar.gz -C /usr/local/redis
3.安装Redis的依赖环境gcc,命令:yum install gcc-c++
4.进入/usr/local/redis/redis-4.0.0进行编译,命令:make
5.进入redis的src目录进行安装,命令:make install
6.因为redis-cli和redis-server和redis.conf不在同一目录下不好启动所以把他们拖到
同一目录下,方便启动:
mv src/redis-server ./redis-server
mv src/redis-cli ./redis-cli
7.启动服务端:在指定目录下./redis-server redis.conf
8.启动客户端:./redis-cli
9.检验:输入ping,会回pong.
1.设置Redis服务后台运行:
行号136:daemonize yes
2.设置密码:
行号500:requirepass 密码
3.设置允许客户端连接Redis服务
(Redis服务默认只能客户端本地连接,不允许客户端远程连接,要将配置中的绑定注释掉)
行号69:# bind 127.0.0.1
4.客户端远程连接
redis-cli -h IP地址 -p 端口号(6379) -a 密码
只是常用的,更多内容可去redis中文网查询
普通字符串,常用
set key value: 设置指定key的值
get key:获取指定key的值
setex key seconds value:指定key的值,并将key 的过期时间设为seconds秒
setnx key value:只有在key不存在时设置key值
适合存储对象
hset key field value: 将哈希表key中的字段field设为value
hget key field: 获取存储在哈希表中指定字段的值
hdel key field: 删除存储在哈希表中指定字段
hkeys key :获取哈希表中所有字段
hvals key :获取哈希表中所有值
hgetall key:获取在哈希表中指定key的所有字段和值
按照插入顺序排序,可以有重复元素
lpush key value1 [value2] :将一个或多个值插入到列表头部(l从左边插r从右边插)
lrange key start stop :获取列表指定范围内的元素(lrange key 0 -1:查询所有)
rpop key :移除并获取列表最后一个元素
llen: 获取列表长度
brpop key1 [key2] timeout: 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
无序集合,没有重复元素
sadd key member1 [member2] : 向集合中添加一个或多个成员。
srem key member1 [member2] : 移除集合中一个或多个成员
smembers key : 返回集合中所有成员
sinter key1 [key2] : 返回所有集合的交集
sunion key1 [key2] : 返回所有集合的并集
sdiff key1 [key2] : 返回所有集合的差集
集合中每个元素关联一个分数(double的score),根据分数升序排序没有重复元素,但分数可以重复
zadd key score1 meber1 [score2 meber2] : 向有序集合添加一个或多个成员,或者更新已存在成员
的分数。
zrange key start stop [withscores] : 通过索引区间返回有序集合中指定区间内的成员,[withscores]是分数也显示出来
zincrby key increment member : 有序集合中对指定成员的分数加上增量increment
zrem key member1 [member2] : 移除有序集合中一个或多个成员
keys pattern :查找所有符合给定模式(pattern)的key(pattern不要用*,避免因数据量过大造成宕机) key *a*
exists key: 检查给定key是否存在
type key: 返回key所存储的值的类型
ttl key: 返回给定key的剩余生存时间(TTL,time to live),以秒为单位(-1:永久,正数:剩余存活时间,-2:不存在)
del key: 该命令用于在key存在时删除key
Redis的Java客户端很多,官方推荐的有三种:
Jedis
Lettuce
Redisson
使用Jedis操作Redis的步骤:
1.获取连接
2.执行操作
3.关闭连接
1.导入Jedis的Maven坐标
redis.clients
jedis
2.8.0
2.编写Java代码
import redis.clients.jedis.Jedis;
/**
* jedis 入门测试
* 1.创建jedis对象,获取连接
* 2.执行操作
* 3.关闭资源
*/
public class TestJedis {
public static void main(String[] args) {
//1.创建jedis对象,获取连接
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.auth("root");
//2.执行操作
jedis.set("name","hahaha");
System.out.println(jedis.get("name"));
//3.关闭资源
jedis.close();
}
}
Spring对Redis客户端进行了整合,提供了Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis
Spring data Redis 是Spring的一部分,提供了在Spring应用中通过简单的配置就可以访问Redis服务,对Redis底层开发包进行了高度封装。
1.环境搭建:在springboot工程的基础上,在pom中引入依赖
org.springframework.boot
spring-boot-starter-data-redis
2.在yml添加redis配置
spring:
# redis相关配置
redis:
host: 47.92.88.189
port: 6379
password: 3569717299Asd!
database: 0 # 操作的是0号数据库
jedis:
#redis连接池配置
pool:
max-active: 8 #最大连接数
max-wait: 1ms #连接池最大阻塞等待时间
max-idle: 4 #连接池中最大空闲连接
min-idle: 0 #连接池中最小空闲连接
3.使用RedisTemplate进行操作测试
Spring Data Redis 中提供了一个高度封装的类 : RedisTemplate,针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
ValueOperations: 简单K-V操作
SetOperations: set类型数据操作
ZSetOperations: zset类型数据操作
HashOperations: 针对map类型数据操作
ListOperations: 针对list类型数据操作
//以此为例子
@RestController
@RequestMapping("hello")
public class HelloController {
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("hi")
public String hi(String key,String value){
redisTemplate.opsForValue().set(key,value);
return "打招呼";
}
@GetMapping("also")
public String hi(String key){
String value = (String) redisTemplate.opsForValue().get(key);
return value;
}
}
4.配置类(非必须)
当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象,但是默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别
/**
* Redis配置类
*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate
设置配置类前:
设置配置类后:
@Slf4j
@RestController
@RequestMapping("redis")
public class HelloController {
@Autowired
private RedisTemplate redisTemplate;
/**
* 操作String类型数据
* @return
*/
@GetMapping("string")
public String string(String key1,String value1,String key2,String value2,String key3,String value3){
//1.set key value
redisTemplate.opsForValue().set(key1,value1);
//2.get key
String result = (String) redisTemplate.opsForValue().get(key1);
//3.setex key seconds value
redisTemplate.opsForValue().set(key2,value2,60, TimeUnit.SECONDS);
//4.setnx key value
redisTemplate.opsForValue().setIfAbsent(key3,value3);//Absent:缺席的,不存在的
return result;
}
/**
* 操作列表类型数据
* @param key1
* @param value1
* @return
*/
@GetMapping("list")
public List list(String key1,String value1){
//1.lpush key value [value...]
redisTemplate.opsForList().leftPush(key1,value1);
redisTemplate.opsForList().leftPush(key1,value1);
redisTemplate.opsForList().leftPush(key1,value1);
redisTemplate.opsForList().leftPush(key1,value1);
redisTemplate.opsForList().leftPush(key1,value1);
//lrange key start stop
List list = redisTemplate.opsForList().range(key1, 0, -1);
//lpop key
String leftPop = (String) redisTemplate.opsForList().leftPop(key1);
log.info("leftPop:{}",leftPop);
//llen key
Long size = redisTemplate.opsForList().size(key1);
log.info("长度:{}",size);
//brpop key [key...] timeout
String brpop = (String) redisTemplate.opsForList().rightPop(key1, 60, TimeUnit.SECONDS);
log.info("阻塞删除:{}",brpop);
return list;
}
/**
* 操作hash类型数据
* @param hash
* @param key
* @param value
*/
@GetMapping("hash")
public void hash(String hash,String key,String value){
//hset key field value
redisTemplate.opsForHash().put(hash,key,value);
redisTemplate.opsForHash().put(hash,"age",23);
redisTemplate.opsForHash().put(hash,"sno",2020240314);
redisTemplate.opsForHash().put(hash,"addr","武汉");
redisTemplate.opsForHash().put(hash,"hobby","哈哈哈");
//hget key field
String name = (String) redisTemplate.opsForHash().get(hash, key);
log.info("get了个{}",name);
//hkeys key
Set keys = redisTemplate.opsForHash().keys(hash);
keys.forEach(o -> System.out.println("键为"+o));
log.info("=============================================");
//hvals key
List values = redisTemplate.opsForHash().values(hash);
values.forEach(o -> System.out.println("值为"+o));
log.info("=============================================");
//hgetall key
Map map = redisTemplate.opsForHash().entries(hash);
Set keySet = map.keySet();
keySet.forEach(o -> System.out.println(o+":"+map.get(o)));
log.info("=============================================");
//hdel key field [field ...]
redisTemplate.opsForHash().delete(hash,key);
}
/**
* 操作set类型数据
*/
@GetMapping("set")
public void set(){
//sadd key member [member ...]
redisTemplate.opsForSet().add("set1","tian","23","玩游戏");
redisTemplate.opsForSet().add("set2","tian","23","敲代码","喜欢");
//srem key member [member ...]
redisTemplate.opsForSet().remove("set2","喜欢");
//smembers key
Set members = redisTemplate.opsForSet().members("set2");
members.forEach(o -> System.out.println(o));
log.info("===============================================");
//sinter key [key ...]
Set intersect = redisTemplate.opsForSet().intersect("set1", "set2");
intersect.forEach(o -> System.out.println(o));
log.info("===============================================");
//sunion key1 [key2]
Set union = redisTemplate.opsForSet().union("set1", "set2");
union.forEach(o -> System.out.println(o));
log.info("===============================================");
//sdiff key1 [key2]
Set difference = redisTemplate.opsForSet().difference("set1", "set2");
difference.forEach(o -> System.out.println(o));
}
/**
* 操作zset类型的数据
*/
@GetMapping("zset")
public void zset(){
//zadd key score member [score member ...]
redisTemplate.opsForZSet().add("zset","a1",0.4);
redisTemplate.opsForZSet().add("zset","a2",0.5);
redisTemplate.opsForZSet().add("zset","a3",0.6);
redisTemplate.opsForZSet().add("zset","a4",0.7);
redisTemplate.opsForZSet().add("zset","a5",0.8);
//zrange key start stop
Set zset = redisTemplate.opsForZSet().range("zset", 0, -1);
zset.forEach(o -> System.out.println(o));
log.info("===============================================");
//zincrby key increment member
redisTemplate.opsForZSet().incrementScore("zset","a2",10);
//zrem key member [member ...]
redisTemplate.opsForZSet().remove("zset","a1");
}
/**
* 通用操作
*/
@GetMapping("common")
public void common(){
//keys pattern
Set keys = redisTemplate.keys("*");
keys.forEach(o -> System.out.println(o));
log.info("==================================================");
//exists key [key ...]
Boolean hasKey1 = redisTemplate.hasKey("list");
Boolean hasKey2 = redisTemplate.hasKey("tian");
log.info("list存在吗:{},tian存在吗:{}",hasKey1,hasKey2);
log.info("==================================================");
//type key
DataType type = redisTemplate.type("zset");
log.info("zset的数据类型:{}",type);
//ttl key
Long expire = redisTemplate.getExpire("list");
log.info("list的剩余生存时间:{}",expire);
//del key [key ...]
redisTemplate.delete("string1");
}
@GetMapping("hi")
public String hi(String key,String value){
redisTemplate.opsForValue().set(key,value);
return "打招呼";
}
@GetMapping("also")
public String hi(String key){
String value = (String) redisTemplate.opsForValue().get(key);
return value;
}
}