Redis
1. NoSQL的引言
2. 为什么是NoSQL
随着互联网网站的兴起,传统的关系数据库在应付动态网站,特别是超大规模和高并发的纯动态网站已经显得力不从心,暴露了很多难以克服的问题。如
商城网站中对商品数据频繁查询
、
对热搜商品的排行统计
、
订单超时问题
、以及微信朋友圈(音频,视频)存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。nosql这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。
商城网站中对商品数据频繁查询
、
对热搜商品的排行统计
、
订单超时问题
、以及微信朋友圈(音频,视频)存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。nosql这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。
3. NoSQL的四大分类
3.1 键值(Key-Value)存储数据库
3.2 列存储数据库
3.3 文档型数据库
# 1.说明
– 文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高
# 2.特点
– 以文档形式存储
# 3.相关产品
3.4 图形(Graph)数据库
4. NoSQL应用场景
-
对数据库性能要求较高
5. 什么是Redis
6. Redis特点
7. Redis安装
8. Redis数据库相关指令
8.1 数据库操作指令
– 清空全部的库 FLUSHALL
8.2 操作key相关指令
– 可用版本: >= 1.0.0
# 2.EXISTS指令 exists
– 语法: EXISTS key
– 可用版本: >= 1.0.0
# 3.EXPIRE expire
– 可用版本: >= 1.0.0
# 4.KEYS keys
– 语法:
KEYS * 匹配数据库中所有key 。
– 可用版本: >= 1.0.0
– 语法 : MOVE key db
– 可用版本: >= 1.0.0
# 6.PEXPIRE pexpire
– 可用版本: >= 2.6.0
– 可用版本: >= 2.6.0
# 8.TTL ttl
– 语法 : TTL key
– 可用版本: >= 1.0.0
– 返回值:
当key 不存在时,返回-2 。
当key 存在但没有设置剩余生存时间时,返回-1 。
否则,以秒为单位,返回key 的剩余生存时间。
– Note : 在Redis 2.8 以前,当key 不存在,或者key 没有设置剩余生存时间时,命令都返回-1 。
# 9.PTTL pttl
– 语法 : PTTL key
– 可用版本: >= 2.6.0
– 返回值: 当key 不存在时,返回-2 。当key 存在但没有设置剩余生存时间时,返回-1 。
– 否则,以毫秒为单位,返回key 的剩余生存时间。
– 注意 : 在Redis 2.8 以前,当key 不存在,或者key 没有设置剩余生存时间时,命令都返回-1 。
# 10.RANDOMKEY randomkey
– 语法 : RANDOMKEY
– 可用版本: >= 1.0.0
– 语法 : RENAME key newkey
– 可用版本: >= 1.0.0
# 12.TYPE type
– 语法 : TYPE key
– 作用 : 返回key 所储存的值的类型。
– 可用版本: >= 1.0.0
– 返回值:
none (key 不存在)
8.3 String类型
1. 内存存储模型
2. 常用操作命令
命令
|
|
设置一个key/value
|
|
获得原始key的值,同时设置新值
|
|
setex
|
设置一个新key存活的有效期(秒)
|
psetex
|
设置一个key存活的有效期(毫秒)
|
存在不做任何操作,不存在添加
|
|
进行数值类型的-1操作
|
|
根据提供的数据进行减法操作
|
|
Incr
|
进行数值类型的+1操作
|
根据提供的数据进行加法操作
|
|
8.4 List类型
1.内存存储模型
2.常用操作指令
命令
|
|
lpush
|
|
lpushx
|
同lpush,但是必须要保证这个key存在
|
rpush
|
|
rpushx
|
同rpush,但是必须要保证这个key存在
|
lpop
|
|
rpop
|
|
llen
|
|
lset
|
|
lrem
|
|
ltrim
|
|
在某一个元素之前,之后插入新元素
|
8.5 Set类型
1.内存存储模型
2.常用命令
命令
|
|
sadd
|
|
smembers
|
显示集合中所有元素 无序
|
scard
|
|
spop
|
|
srem
|
|
sismember
|
|
随机返回元素
|
|
sdiff
|
去掉第一个集合中和另一个集合含有的相同元
|
sinter
|
求交集
|
求和集
|
8.6 ZSet类型
1.内存模型
2.常用命令
命令
|
|
zadd
|
|
zcard
|
返回集合的元素个数
|
zrank
|
返回排名,0是第一
|
倒序排名
|
|
显示某一个元素的分数
|
|
zrem
|
移除某一个元素
|
zincrby
|
给某个特定元素加分
|
8.7 hash类型
1.内存模型
2.常用命令
命令
|
|
hset
|
|
hget
|
|
hgetall
|
获得所有的key/value对
|
hdel
|
删除某一个key/value对
|
hexists
|
判断一个key是否存在,0:不存在,1:存在
|
hkeys
|
获得所有的key
|
hvals
|
获得所有的value
|
hmset
|
设置多个key/value
|
hmget
|
获得多个key的value
|
hsetnx
|
设置一个不存在的key的值
|
hincrby
|
为value进行加法运算
|
hincrbyfloat
|
为value加入浮点值
|
修改为 0.0.0.0
9. 持久化机制
9.1 快照(Snapshot)
1. 特点
9.2 AOF 只追加日志文件
1.特点
这种方式可以将所有客户端执行的写命令记录到日志文件中,AOF持久化会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集.
2.开启AOF持久化
# 1.always 【谨慎使用】
– 解释: 如果用户使用了always选项,那么每个redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少;遗憾的是,因为这种同步策略需要对硬盘进行大量的写入操作,所以redis处理命令的速度会受到硬盘性能的限制;
– 解释: 为了兼顾数据安全和写入性能,用户可以考虑使用everysec选项,让redis每秒一次的频率对AOF文件进行同步;redis每秒同步一次AOF文件时性能和不使用任何持久化特性时的性能相差无几,而通过每秒同步一次AOF文件,redis可以保证,即使系统崩溃,用户最多丢失一秒之内产生的数据。
– 说明: 由操作系统决定何时同步
4.修改同步频率
9.3 AOF文件的重写
1. AOF带来的问题
AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件Redis提供了AOF重写(ReWriter)机制。
2. AOF重写
用来在一定程度上减小AOF文件的体积
3. 触发重写方式
# 2.服务器配置方式自动触发
4. 重写原理
# 重写流程
9.4 持久化总结
10. java操作Redis
10.1 环境准备
</dependency>
10.2 操作key相关API
@Before
this.jedis = new Jedis(“192.168.202.205”, 7000);
}
@After
}
//测试key相关
@Test
//删除一个key
jedis.del(“name”);
//删除多个key
jedis.del(“name”,”age”);
//判断一个key是否存在exits
Boolean name = jedis.exists(“name”);
//获取一个key超时时间 ttl
Long age1 = jedis.ttl(“newage”);
//随机获取一个key
String s = jedis.randomKey();
//修改key名称
jedis.rename(“age”,”newage”);
//查看可以对应值的类型
String name1 = jedis.type(“name”);
}
@Test
//查询所有的key
//Set<String> keys = jedis.keys(“*”);
//删除key
//Long name = jedis.del(“name”);
//检查给定的key是否存在
//Boolean name = jedis.exists(“name”);
//为key设置生存时间,当key过期自动删除,设置时间为秒
//查询符合条件的所有key
//Set<String> keys1 = jedis.keys(“w*”);
//移动key到指定数据库
//设置key的存活时间,过期自动删除,设置时间为毫秒
//查看key的剩余生存时间,时间为秒
//Long who = jedis.ttl(“who”);
//查看key的剩余生存时间,时间为毫秒
//Long who = jedis.pttl(“who”);
//从当前数据库中随机返回一个key,不删除
//String s = jedis.randomKey();
//修改key的名称
//返回key存储值得类型
//String arr = jedis.type(“arr”);
}
10.3操作String相关API
//测试String相关
@Test
//set
jedis.set(“name”,”小陈”);
//get
String s = jedis.get(“name”);
//mset
//mget
//getset
String set = jedis.getSet(“name”, “小明”);
//…………
}
@Test
//设置一个key或者给指定的key设置值value
//String set = jedis.set(“wuxinke”, “吴帅”);
//根据key获取value
//String wuxinke = jedis.get(“wuxinke”);
//一次设置多个key
//String mset = jedis.mset(“hao”, “好好”,”weixin“,”OO200506”);
//一次获取多个key的value
//获得key原始的值同时设置新的值
//String set = jedis.getSet(“wuxinke”, “吴帅”);
//给key追加能容
//截取key的value值
//String weixin = jedis.getrange(“weixin”, 2, -1);
//设置一个key存活的有效期,时间为秒
//设置一个key存活的有效期,时间为毫秒
//String hao = jedis.psetex(“hao”, 30000,”ninhao”);
//key存在不做任何操作,不存在添加
//Long setnx = jedis.setnx(“liyi”, “李艺”);
//可以同时设置多个key,只要有一个存在都不保存
//Long msetnx = jedis.msetnx(“ww”, “123”, “aa”, “456”, “ee”, “789”);
//对数值类型进行-1操作
//Long aa = jedis.decr(“aa”);
//根据提供的数据进行减法操作
//Long aa = jedis.decrBy(“aa”, 10);
//对数值类型+1操作
//Long aa = jedis.incr(“aa”);
//根据提供的数据进行加法操作
//Long aa = jedis.incrBy(“aa”, 100);
//根据提供的数据加上浮点数
//Double aa = jedis.incrByFloat(“aa”, 10.99);
}
10.4操作List相关API
@Test
public void testList(){
//将值加入到key列表头部,但是必须保证key存在
//Long lpushx = jedis.lpushx(“arr”, “zhangziyi”, “zhangyixing”);
//Long rpush = jedis.rpush(“arr”, “yiyi”);
//将值添加到key列表末尾,但必须保证key存在
//Long rpushx = jedis.rpushx(“arr”, “ziyi”, “zirui“);
//String arr = jedis.lpop(“arr”);
//String arr = jedis.rpop(“arr”);
//List<String> arr = jedis.lrange(“arr”, 0, -1);
//获取列表元素个数
//Long arr = jedis.llen(“arr”);
//设置某一个指定索引的值,索引必须存在
//String arr = jedis.lset(“arr”, 2, “123”);
//获取某一个指定索引位置的元素
//String arr = jedis.lindex(“arr”, 2);
//删除重复元素
//Long lrem = jedis.lrem(“arr”, 1, “yiyi”);
//String arr = jedis.ltrim(“arr”, 2, 4);
//在某一个元素之前或者之后插入元素
}
10.5操作Set的相关API
@Test
public void testSet(){
//为集合添加元素
//显示集合中的所有元素,无序
//Set<String> sets = jedis.smembers(“sets”);
//返回集合中得个数
//随机返回一个元素,并删除该元素
//String sets = jedis.spop(“sets”);
//从一个集合中向另一个集合中移动元素,必须是同一种类型
//从集合中删除一个元素
//Long srem = jedis.srem(“sets”, “qianqi”);
//判断一个集合中是否存在这个元素
//Boolean sismember = jedis.sismember(“sets”, “zhangsan”);
//随机返回一个元素
//String sets = jedis.srandmember(“sets”);
//去掉第一个集合中和其他集合含有的相同元素,不删除
//求交集
//Set<String> sets = jedis.sinter(“sets”,”sets2″);
//求和集
//Set<String> sets = jedis.sunion(“sets”,”sets2″);
}
10.6 操作ZSet相关API
//测试ZSET相关
@Test
public void testZset(){
//zadd
jedis.zadd(“names”,10,”张三”);
//zrange
jedis.zrange(“names”,0,-1);
//zcard
jedis.zcard(“names”);
//zrangeByScore
jedis.zrangeByScore(“names”,”0″,”100″,0,5);
//..
}
@Test
public void testZset(){
//返回集合的元素个数
//Long zsets1 = jedis.zcard(“zsets1”);
//Set<String> zsets1 = jedis.zrangeByScore(“zsets1”, 80, 100);
//返回排名
//Long zsets1 = jedis.zrank(“zsets1″,”zhangsan”);
//倒序排名
//Long zsets1 = jedis.zrevrank(“zsets1”, “xiaohei”);
//显示某一个元素的分数
//移除某一个元素
//Long zrem = jedis.zrem(“zsets1”, “xiaohei”);
//给某一个特定元素加分
//Double zincrby = jedis.zincrby(“zsets1”, 10, “zahngsan”);
}
10.7 操作Hash相关API
//测试HASH相关
@Test
public void testHash(){
//hset
jedis.hset(“maps“,”name”,”zhangsan”);
//hget
jedis.hget(“maps“,”name”);
//hgetall
jedis.hgetAll(“mps”);
//hkeys
//hvals
jedis.hvals(“maps“);
//….
}
@Test
public void testHash(){
//设置一个key/value对
//Long hset = jedis.hset(“hsets1”, “yijia”, “wuxinke”);
//获得一个key对应的value
//String hget = jedis.hget(“hsets1”, “yijia”);
//获得所有的key/value对
//Map<String, String> hsets1 = jedis.hgetAll(“hsets1”);
//删除某一个key/value对
//Long hdel = jedis.hdel(“hsets1”, “oo6”);
//判断一个key是否存在
//获得所有的key
//Set<String> hsets1 = jedis.hkeys(“hsets1”);
//获得所有的value
//List<String> hsets1 = jedis.hvals(“hsets1”);
//设置多个key/value 对
//HashMap<String, String> map = new HashMap<>();
//map.put(“yijia”,”liyi”);
//String hsets1 = jedis.hmset(“hsets1”, map);
//获得多个key的value
//List<String> hmget = jedis.hmget(“hsets1”, “oo5”, “oo7”, “yijia”);
//给一个不存在的key设置值
//Long hsetnx = jedis.hsetnx(“hsets1”, “love”, “liyi”);
//对value进行加法运算
//Long aLong = jedis.hincrBy(“hsets1”, “yi1”, 5);
//对value加入浮点值
//Double aDouble = jedis.hincrByFloat(“hsets1”, “yi2”, 9.99);
}
11.SpringBoot整合Redis
Spring Boot Data(数据) Redis 中提供了
RedisTemplate和StringRedisTemplate
,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,
RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。
RedisTemplate和StringRedisTemplate
,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,
RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。
11.1 环境准备
<groupId>org.springframework.boot</groupId>
</dependency>
2.配置application.propertie
11.2 使用StringRedisTemplate和RedisTemplate
StringRedisTemplate操作
@Autowired
//对key进行操作
@Test
public void testKey(){
//Set<String> keys = stringRedisTemplate.keys(“*”);//匹配所有key
//Set<String> keys = stringRedisTemplate.keys(“w*”);//匹配w开头的所有key
//删除指定的key
//ArrayList<String> list = new ArrayList<>();
//list.add(“ww”);
//list.add(“aa”);
//检查指定的key是否存在
//给指定的key设置生存时间,过期自动删除,时间单位可以是 天,小时,分钟,秒,毫秒
//Boolean ee = stringRedisTemplate.expire(“Hello”, Duration.ofSeconds(50));//返回真假,true:设置成功,false:设置失败
//获取指定key的类型
//获取指定key的存活的剩余时间单位秒
//在当前数据库随机返回一个key,不删除
//String s = stringRedisTemplate.randomKey();
//修改key的名称
//stringRedisTemplate.rename(“liyi”,”home“);
}
//对String进行操作
@Test
public void testString(){
//设置一个key
//stringRedisTemplate.opsForValue().set(“we”,”wuxinke and liyi”);
//根据key获取对应的value
//String we = stringRedisTemplate.opsForValue().get(“we”);
//一次设置多个key和value
//HashMap<String, String> map = new HashMap<>();
//map.put(“name1″,”zhangsan”);
//map.put(“name3″,”wangwu”);
//stringRedisTemplate.opsForValue().multiSet(map);
//一次获取多个key的value
//Collection<String> collection = new ArrayList<>();
//collection.add(“name1”);
//collection.add(“name2”);
//collection.add(“name3”);
//List<String> list = stringRedisTemplate.opsForValue().multiGet(collection);
//根据key获取原始的value,同时设置新的value
//String andSet = stringRedisTemplate.opsForValue().getAndSet(“we”, “Wuxinke Love Liyi”);
//根据key获取对应value的长度
//根据key给对应的value追加内容
//截取value的内容,起始索引是0,-1表示末尾
//String we = stringRedisTemplate.opsForValue().get(“we”, 0, -1);
//设置一个新key存活的有效期,过期自动删除,时间单位可以是 天,小时,分钟,秒,毫秒
//stringRedisTemplate.opsForValue().set(“#001″,”井001”,Duration.ofSeconds(60));
//stringRedisTemplate.opsForValue().set(“#002″,”井002”,60*10, TimeUnit.SECONDS);
//判断key是否存在,存在不做任何操作,存在做添加操作
//Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(“Liyi”, “宁宁”);//返回真假,true:不存在,false:不存在
//同时添加多个key,只要有一个存在都不做添加
//HashMap<String, String> map = new HashMap<>();
//map.put(“keys4″,”value4”);
//map.put(“keys5″,”value5”);
//map.put(“Liyi”,”ll”);
//Boolean aBoolean1 = stringRedisTemplate.opsForValue().multiSetIfAbsent(map);//返回真假,true:添加成功,false:添加失败
//根据key对对应的value进行-1操作,value是数字必须是类型
//Long age = stringRedisTemplate.opsForValue().decrement(“age”);//返回操作后的数值
//根据key对对应的value进行减法操作,value是数字必须是类型
//Long age1 = stringRedisTemplate.opsForValue().decrement(“age”, 2);//返回操作后的数值
//根据key对对应的value进行+1操作,value是数字必须是类型
//Long age = stringRedisTemplate.opsForValue().increment(“age”);//返回操作后的数值
//根据key对对应的value进行加法操作,value是数字必须是类型
//Long age = stringRedisTemplate.opsForValue().increment(“age”, 5);//返回操作后的数值
//根据key对对应的value进行浮点数的加法操作,value是数字必须是类型
//Double age = stringRedisTemplate.opsForValue().increment(“age”, 5.5);//返回操作后的数值
}
//对List集合进行操作
@Test
public void testList(){
//将某一个数据加入到某个集合的头部,key不存在,不会创建key
//将某一个数据加入到某个集合的末尾,key不存在不会报错,会创建key类型为list
//Long aLong1 = stringRedisTemplate.opsForList().rightPush(“a”, “name4”);//返回集合中key的个数
//将某一个数据加入到某个集合的末尾,key不存在,不会创建key
//String arr = stringRedisTemplate.opsForList().leftPop(“arr”);
//String arr = stringRedisTemplate.opsForList().rightPop(“arr”);
//List<String> arr = stringRedisTemplate.opsForList().range(“arr”, 2, -1);
//获取列表内元素个数
//Long arr1 = stringRedisTemplate.opsForList().size(“arr”);
//给某个指定索引位置设置值,如果该索引有值就覆盖,索引必须存在
//stringRedisTemplate.opsForList().set(“arr”,2,”zhangsan”);
//获取指定索引位置的元素
//String arr = stringRedisTemplate.opsForList().index(“arr”, 2);
//保留列表中特定区间内的元素,其他都删除
//stringRedisTemplate.opsForList().trim(“arr”,2,-1);
}
//对set集合进行操作
@Test
public void testSet(){
//添加元素
//Long add = stringRedisTemplate.opsForSet().add(“sets”, “李四”);//返回添加个数,1:添加一条,0:没有添加进去
//显示集合中所有元素,无序
//Set<String> sets = stringRedisTemplate.opsForSet().members(“sets”);
//返回集合中元素个数
//Long size = stringRedisTemplate.opsForSet().size(“sets”);
//随机返回一个元素,并将该元素删除
//String sets = stringRedisTemplate.opsForSet().pop(“sets”);
//从一个集合向另一个集合中移动元素,必须是同一种类型的key
//Boolean move = stringRedisTemplate.opsForSet().move(“sets”, “张三”, “sets2”);//返回真假,true:成功,false:失败
//从指定的key集合中删除一个或多个元素
//Long remove = stringRedisTemplate.opsForSet().remove(“sets”, “6”, “李四”);//返回删除的个数
//在指定的key中判断一个集合中是否包含指定元素
//Boolean member = stringRedisTemplate.opsForSet().isMember(“sets”, “5”);//返回真假,true:存在,false:不存在
//随机返回一个元素,不删除
//String sets = stringRedisTemplate.opsForSet().randomMember(“sets”);
//获取两个集合或多个集合没有重复的元素,不做删除
//获取两个集合或多个集合中重复的元素,不做删除
//获取两个集合或多个集合中所有的元素,不做删除
}
//对ZSet集合进行操作
@Test
public void testZSet(){
//向指定的集合中添加一个或多个元素
//Boolean add = stringRedisTemplate.opsForZSet().add(“zsets1”, “张三”, 66.5);
//HashSet<ZSetOperations.TypedTuple<String>> hashSet = new HashSet<>();
//hashSet.add(typedTuple1);
//hashSet.add(typedTuple2);
//hashSet.add(typedTuple3);
//Long zsets1 = stringRedisTemplate.opsForZSet().add(“zsets1”, hashSet);
//返回集合中元素个数
//Long zsets1 = stringRedisTemplate.opsForZSet().size(“zsets1”);
//Set<String> zsets11 = stringRedisTemplate.opsForZSet().range(“zsets1”, 0, -1);
//返回指定范围内的元素,降序,起始索引:0,末尾:-1
//Set<String> zsets11 = stringRedisTemplate.opsForZSet().reverseRange(“zsets1”,0,-1);
//Set<String> zsets1 = stringRedisTemplate.opsForZSet().rangeByScore(“zsets1”,90.0,100.0);
//返回指定元素的排名,排名按照添加顺序排名,第一名为0
//Long zsets1 = stringRedisTemplate.opsForZSet().rank(“zsets1″,”李艺”);
//Long aLong = stringRedisTemplate.opsForZSet().reverseRank(“zsets1”, “吴新科”);
//显示某一个元素的分数
//移除某一个元素
//Long remove = stringRedisTemplate.opsForZSet().remove(“zsets1”, “zahngsan”);
//给某个特定元素加分
//Double aDouble = stringRedisTemplate.opsForZSet().incrementScore(“zsets1”, “张三”, 5.5);//返回加分后的分数
}
//对hash集合进行操作
@Test
public void testHash(){
//添加一个或多个元素
//stringRedisTemplate.opsForHash().put(“map”,”吴新科”,”196″);
//HashMap<String, String> map = new HashMap<>();
//map.put(“李艺”,”199″);
//map.put(“吴旭”,”182″);
//map.put(“李浩”,”112″);
//stringRedisTemplate.opsForHash().putAll(“map”,map);
//获得key对应的value
//Object o = stringRedisTemplate.opsForHash().get(“map”, “吴新科”);
//获得所有的key/value对
//Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(“map”);
//删除指定的一个key或多个key
//判断一个key是否存在
//Boolean aBoolean = stringRedisTemplate.opsForHash().hasKey(“map”, “李艺”);//返回真假,true:存在,false:不存在
//获得所有的key
//Set<Object> map = stringRedisTemplate.opsForHash().keys(“map”);
//获得所有的value
//List<Object> map = stringRedisTemplate.opsForHash().values(“map”);
//获得多个key的value
//ArrayList<Object> list = new ArrayList<>();
//list.add(“吴新科”);
//list.add(“李艺”);
//List<Object> map = stringRedisTemplate.opsForHash().multiGet(“map”, list);
//判断key是否存在,存在不添加,不存在添加
//Boolean aBoolean = stringRedisTemplate.opsForHash().putIfAbsent(“map”, “浩浩”, “126”);//返回真假,true:不存在添加,false:存在不添加
//对指定的value进行加法运算,
}
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate(){
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//redisTemplate的hash集合的value使设置序列化策略,默认是JdkSerializationRedisSerializer策略,可以修改成StringRedisSerializer
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
}
@Autowired
@Autowired
private RedisTemplate redisTemplate; //存储对象
@Test
public void testRedisTemplate(){
//设置redistemplate值使用对象序列化策略
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());//指定值使用对象序列化
//redisTemplate.opsForValue().set(“user“,new User(“21″,”小黑”,23,new Date()));
// Set keys = redisTemplate.keys(“*”);
/*Object name = redisTemplate.opsForValue().get(“name”);
//Object xiaohei = redisTemplate.opsForValue().get(“xiaohei”);
/*redisTemplate.opsForValue().set(“name”,”xxxx“);
Object name = redisTemplate.opsForValue().get(“name”);
List lists = redisTemplate.opsForList().range(“lists”, 0, -1);
}
//key的绑定操作 如果日后对某一个key的操作及其频繁,可以将这个key绑定到对应redistemplate中,日后基于绑定操作都是操作这个key
//boundValueOps 用来对String值绑定key
//boundListOps 用来对List值绑定key
//boundSetOps 用来对Set值绑定key
//boundZsetOps 用来对Zset值绑定key
//boundHashOps 用来对Hash值绑定key
@Test
public void testBoundKey(){
BoundValueOperations<String, String> nameValueOperations = stringRedisTemplate.boundValueOps(“name”);
nameValueOperations.set(“1”);
//yuew
nameValueOperations.set(“2”);
String s = nameValueOperations.get();
System.out.println(s);
}
//hash相关操作 opsForHash
@Test
public void testHash(){
stringRedisTemplate.opsForHash().put(“maps”,”name”,”小黑”);
Object o = stringRedisTemplate.opsForHash().get(“maps”, “name”);
System.out.println(o);
}
//zset相关操作 opsForZSet
@Test
public void testZSet(){
stringRedisTemplate.opsForZSet().add(“zsets”,”小黑”,10);
Set<String> zsets = stringRedisTemplate.opsForZSet().range(“zsets”, 0, -1);
zsets.forEach(value-> System.out.println(value));
}
//set相关操作 opsForSet
@Test
public void testSet(){
Set<String> sets = stringRedisTemplate.opsForSet().members(“sets”);
sets.forEach(value-> System.out.println(value));
}
//list相关的操作opsForList
@Test
public void testList(){
// stringRedisTemplate.opsForList().leftPushAll(“lists”,”张三”,”李四”,”王五”);
List<String> lists = stringRedisTemplate.opsForList().range(“lists”, 0, -1);
lists.forEach(key -> System.out.println(key));
}
//String相关的操作 opsForValue
@Test
public void testString(){
//stringRedisTemplate.opsForValue().set(“166”,”好同学“);
String s = stringRedisTemplate.opsForValue().get(“166”);
System.out.println(s);
Long size = stringRedisTemplate.opsForValue().size(“166”);
System.out.println(size);
}
//key相关的操作
@Test
public void test(){
Set<String> keys = stringRedisTemplate.keys(“*”);//查看所有key
Boolean name = stringRedisTemplate.hasKey(“name”);//判断某个key是否存在
stringRedisTemplate.delete(“age”);//根据指定key删除
stringRedisTemplate.rename(“”,””);//修改key的名称
stringRedisTemplate.expire(“key”,10, TimeUnit.HOURS);
stringRedisTemplate.move(“”,1);//移动key
}
注意:
[2.].Redis缓存
注意:
//构造方法
public RedisCache(String id){
this.id=id;
}
public String getId() {
return this.id;
}
public void putObject(Object o, Object o1) {
getRedisTemplate().opsForHash().put(id.toString(),o.toString(),o1);
}
public Object getObject(Object o) {
return getRedisTemplate().opsForHash().get(id.toString(),o.toString());
}
public Object removeObject(Object o) {
}
public void clear() {
getRedisTemplate().delete(id.toString());
}
//缓存数量
public int getSize() {
return getRedisTemplate().opsForHash().size(id.toString()).intValue();
}
@Override
}
public RedisTemplate getRedisTemplate(){
RedisTemplate redisTemplate = (RedisTemplate) RedisContextUtils.getBean(“redisTemplate”);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
Spring工厂创建RedisTemplate
缓存优化
StudentMapper.xml
UserMapper.xml
12. Redis 主从复制
12.1 主从复制
12.2 主从复制架构图
12.3 搭建主从复制
13. Redis哨兵机制
13.1 哨兵Sentinel机制
Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。简单的说哨兵就是带有
自动故障转移功能的主从架构
。
自动故障转移功能的主从架构
。
13.2 哨兵架构原理
13.3 搭建哨兵架构
13.4 通过springboot操作哨兵
# redis sentinel 配置
-
注意:如果连接过程中出现如下错误:RedisConnectionException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command ‘CONFIG SET protected-mode no‘ from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2)
14. Redis集群
14.1 集群
Redis在3.0后开始支持Cluster(模式)模式,目前redis的集群支持节点的自动发现,支持slave-master选举和容错,支持在线分片(sharding shard )等特性。reshard
14.2 集群架构图
14.3 集群细节
14.4 集群搭建
判断一个是集群中的节点是否可用,是集群中的所用主节点选举过程,如果半数以上的节点认为当前节点挂掉,那么当前节点就是挂掉了,所以搭建redis集群时建议节点数最好为奇数,
搭建集群至少需要三个主节点,三个从节点,至少需要6个节点
。
搭建集群至少需要三个主节点,三个从节点,至少需要6个节点
。
1.创建集群
# 2.创建集群
# 3.集群创建成功出现如下提示
2.查看集群状态
# 1.查看集群状态 check [原始集群中任意节点] [无]
– ./redis-trib.rb check 192.168.202.205:7000
# 2.集群节点状态说明
– 主节点
主节点不能删除
一个主节点可以有多个从节点
主节点宕机时多个副本之间自动选举主节点
– 从节点
从节点没有hash slots
从节点可以删除
从节点不负责数据的写,只负责数据的同步
3.添加主节点
# 1.添加主节点 add-node [新加入节点] [原始集群中任意节点]
– ./redis-trib.rb add-node 192.168.1.158:7006 192.168.1.158:7005
– 注意:
1.该节点必须以集群模式启动
2.默认情况下该节点就是以master节点形式添加
4.添加从节点
– 注意:
5.删除副本节点
# 1.删除节点 del-node [集群中任意节点] [删除节点id]
– ./redis-trib.rb del-node 127.0.0.1:7002 0ca3f102ecf0c888fc7a7ce43a13e9be9f6d3dd1
– 注意:
15.Redis实现分布式Session管理
15.1 管理机制
redis的session管理是利用spring提供的session管理解决方案,将一个应用session交给Redis存储,整个应用中所有session的请求都会去redis中获取对应的session数据。
15.2 开发Session管理
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2. 开发Session管理配置类
持续更新!
原文地址:https://blog.csdn.net/weixin_51689532/article/details/130686806
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_20372.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。