Redis缓存介绍

Redis

NOSQL数据库分类

键值存储:

这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署

代表: Redis

列存储数据库:

这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。

代表: HBase

文档型数据库:

文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高

代表: MongoDb

图形数据库

什么是Redis

在这里插入图片描述

Redis是以键值对的形式存储,和传统数据库不一样,不一定遵守传统数据库的基本要求

优点以及作用:

对数据进行高并发的读写,对海量数据的高效率存储和访问

提高数据的可拓展性和可用性

单线程操作每个操作都是原子操作.没有并发的相关问题

redis的定位

** 定位是缓存,提高数据的读写速度,减轻在访问的时候对数据库的压力**

redis的缺点:

没有办法做复杂关系型的数据库

优势

性能极高redis支持超过10w次每秒的读写速度

Redis数据类型

Redis命令格式:

类型命令 key 参数数据

set name aaa

String类型

String类型包含多种类型的特殊类型,是二进制安全的,序列化的对象进行存储

类型命令 key 参数数据 常用的命令

set key value -> 存入键值对

get key -> 根据键取出值

incr key -> 把值递增1

decr key -> 把值递减1

del key -> 根据键删除键值对

setex key timeout value -> 存入键值对,timeout表示失效时间,单位s

ttl key->可以查询出当前的key还剩余多长时间过期

setnx key value -> 如果key已经存在,不做操作, 如果key不存在,直接添加

应用场景

计数器:快速计算数据,查询缓存

共享session:处于负载均衡的考虑,用redis将用户session集中管理,

​ 在这种模式下只要保证redis的高可用和扩展性的,每次获取用户更新或查询登录信息

​ 都直接从redis中集中获取。

hash类型

hash类型是String类型的field和value的映射表,或者说是一个String的集合,它特别适合存储对象

相对于String占用空间更小,方便存储整个对象

常用指令

hset key hashkey hashvalue -> 存入一个hash对象

hget key hashkey -> 根据hash对象键取去值

hexists key hashkey -> 判断hash对象是含有某个键

hdel key hashkey -> 根据hashkey删除hash对象键值对

应用场景

可以用来对用户的信息管理,但是哈希类型和关系型数据库有所不同,哈希类型是稀疏的,

共享session:

key:user_token

value:

class User{

private String userame;

private String password;

private int age;

}

user(“dafei”, “666”, 18)

-------------------------------------

方案1: 将user对象转换json格式字符串存redis 【侧重于查, 改非常麻烦】

key value

list类型

Redis中的list类型跟java中的集合操作

它是一个链表结构的集合,其主要的功能主要有push,pop,这个类型是一个双端链表结构,通过操作,可以在头或者尾部进行添加或者删除元素,list又可以作为栈使用,还可以作为队列使用

Map<String, List>

rpush key value -> 往列表右边添加数据

lrange key start end -> 范围显示列表数据,全显示则设置0 -1

lpush key value -> 往列表左边添加数据

lpop key -> 弹出列表最左边的数据,就是相当于删除最左边的数据,然后第二个进行顶替

rpop key -> 弹出列表最右边的数据,同上

llen key -> 获取列表长度

set类型

这个类型存储的时候是无序的

如何选用数据类型

1>如果排序的功能选用zset

2>如果数据是多个并且允许重复使用选用list

3>如果数据是多个且不允许重复,选用set

4>剩下的选用String

5>如果是对象类型可以使用hash类型

hash —> 转换成json格式

{

key1:value1

key2:value2 ------> “{key1:value1, key2:value2}”

}

JSON.toJsonString(map)

有些公司约定key和value必须使用字符串,这时候

排序选用zset,其他的使用String

所以有些公司统一规范, 统一使用字符串, 减少泛型操作

Listlist = …

Set set = …

Map<String, Object> map = …

key和value的设计

key的设计:

1:唯一性

2:可读性

3:灵活性

4:时效性

value值根据需求决定

redis高级指令

返回满足所有的键

keys *(模糊查询,查询所有的key)

exisit (是否存在指定的key)

expire 设置某个key的存活时间,使用ttl查看剩余的存活时间

persist 取消设置的存活时间,这个需要在存活结束之前取消,要不然就是没有效果

flushdb 清空当前的数据库,fiushal清空所有的数据库

dbsize查看数据库key的数量

redis事务

redis的的事务非常简单,使用方法: 首先是使用multi方法打开事务,然后进行设置,这时候设置的数据会放到队列里进行保存,最后使用exec执行,把数据依次存储到redis中,使用discard方法取消事务

redis持久化机制

RDB方式和AOF方式

RDB方式是快照方式,将内存中以快照的方式写入到二进制文件中,.默认为dump.rdb.可以自己配置快照的自动化方式,定制在n秒内超过修改了m个key然后就进行快照,

ave 900 1 #900秒内如果超过1个Key被修改则发起快照保存

save 300 10 #300秒内如果超过10个key被修改,则发起快照保存

AOF方式是append–only–file缩写,快照的方式不是因为是一段时间进行存储一次,这样的话服务器重启的时候很可能会造成数据的丢失,AOF虽然也不是直接存储到硬盘中,但是可以通过强制修改的方法写到硬盘中

aof设置:

appendonly yes //启动aof持久化方式有三种修改方式

#appendfsync always//收到命令就立即写到磁盘,效率最慢.但是能保证完全的持久化

#appendfsync everysec//每秒写入磁盘一次,在性能和持久化方面做了很好的折中

#appendfsync no //完全以依赖os 性能最好,持久化没保证

在这里插入图片描述

redis淘汰机制

服务器就算再大也会有用完的时候,这时候就会删除key

常见的四种方式:

1: LRU:LRU是least recently used,意思近期较少使用,简单理解就是从数据库中删除那些最少访问,长期不使用的key

2:LEU:Least Frequently Used,用的最少,跟上面基本一个意思,使用次数最少,

3:TTL:就是那些设置的时间限制,存活时间的,反正都要退休,干脆直接删除

4:随机淘汰:就是随机去淘汰,生死有命富贵在天

redis实际使用

jedis基本使用:

// 1:创建Jedis连接池
        JedisPool pool = new JedisPool("localhost", 6379);
        // 2:从连接池中获取Jedis对象
        Jedis je = pool.getResource();
        /* 设置密码*/
        je.auth("admin");

//-------------------String类型--------------------
        je.set("name","dagfei");
        je.set("age","12");//设置键值对
        System.out.println(je.incr("age"));//递增
        System.out.println(je.get("name"));//获取key对应的value

        System.out.println(je.decr("age"));//递减一
        System.out.println("删除"+je.del("age"));//删除某个key
//        je.setex("age",100,"22");//设置存活时间
        System.out.println(je.ttl("age"));//查看存活时间
        Long age = je.setnx("age", "12");//如果已经有这个key值不做改变,返回0,如果没有直接添加
        System.out.println(age);
        System.out.println("-------------------hash类型--------------------");
        je.hset("user","name","ben");
//        je.hset("user","age","12");
        je.hset("test","age","12");//设置对象类型的键值,key对象对应的value是属性key和值value
        System.out.println(je.hget("user","age"));
        System.out.println("是否包含"+je.hexists("user", "h"));
        System.out.println("是否包含"+je.hexists("user", "name"));//检查是否包含这个hashkey
        System.out.println("0是成功删除"+je.hdel("user","age"));//通过hashkey删除键值对,这个删除的相当于对象里面的属性字段


        System.out.println("-------------------list类型--------------------");
//        je.lpush("game","地平线","GTAV","剑灵","战地");
//        je.rpush("game","右边添加");//在左边或者在右边添加
        System.out.println("查看所有数据"+je.lrange("game", 0, -1));//0---(-1)代表的是查询所有,想要查询对应的数据可以根据对应的索引区间查找
//        System.out.println(je.lpop("game"));//删除/弹出最左边的数据
//        System.out.println(je.rpop("game"));//删除/弹出最右边的数据
        System.out.println("长度"+je.llen("game"));//度就是索引的值
//        System.out.println(je.ltrim("game", 10, 20));//截取对应的长度


        je.set("name", "aaa");


        System.out.println("-------------------set类型--------------------");
//        je.sadd("number","1","2","3","4","5");
//        je.sadd("number","6");
//        je.sadd("number","7");
//        je.sadd("number","a","b","c","d");
        System.out.println("je.smembers(\"bnumber\") = " + je.smembers("number"));
//        System.out.println(je.spop("number", 2));
//        je.sadd("number2","1","2","3","4","5");
//        je.srem("number2","1");//删除集合中的某个数据
        System.out.println("je.smembers(\"bnumber2\") = " + je.smembers("number2"));
        System.out.println("差集"+je.sdiff("number", "number2"));
        System.out.println("交集"+je.sinter("number", "number2"));
        System.out.println("并集"+je.sunion("number", "number2"));
        System.out.println("个数"+je.scard("number"));
        System.out.println("-------------------sort类型--------------------");
//        je.zadd("hero",300,"黄忠");
//        je.zadd("hero",300,"赵云");
//        je.zadd("hero",400,"关羽");
//        je.zadd("hero",100,"马超");
        System.out.println(je.zrange("hero", 0, -1));//升序打印
        System.out.println(je.zrevrange("hero", 0, -1));//降序打印
//        je.zincrby("hero",400,"马超");//偏移名称对应的分数,就是加分
        System.out.println("je.zrank(\"hero\",\"马超\") = " + je.zrank("hero", "马超"));//排名4升序返回索引
        System.out.println("je.zrevrank(\"hero\",\"马超\") = " + je.zrevrank("hero", "马超"));//排名1降序返回索引
        System.out.println("个数"+je.zcard("hero"));//返回个数

        // 4:关闭资源
        je.close();
        pool.destroy();
@SpringBootTest
public class RediDemosTest {
    @Autowired
    private StringRedisTemplate redis;
    @Test
    public void redistemplates(){

        redis.opsForValue().set("name","dagfei");
        redis.opsForValue().set("age","12");//设置键值对
        System.out.println(redis.opsForValue().increment("age"));//递增
        System.out.println(redis.opsForValue().get("name"));//获取key对应的value

        System.out.println(redis.opsForValue().decrement("age"));//递减一
        System.out.println("-------------------hash类型--------------------");
        redis.opsForHash().put("product","奥迪","r8");
        redis.opsForHash().put("product","奥迪","q3L");
        redis.opsForHash().put("product","奔驰","g20");
        System.out.println(redis.opsForHash().get("product", "奥迪"));
        System.out.println(redis.opsForHash().hasKey("product","奥迪"));
        System.out.println(redis.opsForHash().keys("product"));//获取key对应所有的子元素
        System.out.println(redis.opsForHash().delete("product","奥迪"));//删除某一个key的子元素

        System.out.println("-------------------list类型--------------------");
        redis.opsForList().leftPush("foot","fish","carp");
        redis.opsForList().leftPush("foot","fish","crucianCarp");
        redis.opsForList().leftPushAll()
        redis.opsForValue();//操作字符串
        redis.opsForHash();//操作hash
        redis.opsForList();//操作list
        redis.opsForSet();//操作set
        System.out.println("-------------------set类型--------------------");
        redis.opsForSet().add("hobby","");//操作set
        redis.opsForZSet();//操作有序set
        System.out.println("-------------------sort类型--------------------");
        redis.opsForList().leftPushAll("hero","黄忠","1","1");
        redis.opsForZSet().add("hero","12",2000);//操作有序set
        redis.opsForZSet().add("hero","黄忠",2000);//操作有序set
        redis.opsForZSet().count("hero",0,-1);//个数
        redis.opsForZSet().reverseRange("player",0,-1);
        redis.opsForValue().set("hero","赵云");
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值