Redis入门-开启了解使用redis的大门

Redis入门

 
1.了解数据库分类

2.Redis简介
  2.1 什么是redis?
  2.2 Redis优缺点
  2.3 redis-memcache与redis有什么区别?

3.Redis数量类型指令
  3.1 String类型
  3.2 hash类型
  3.2 list类型
  3.3 set类型
  3.4 zset类型

4.redis进阶-高级命令

5.redis持久化机制

6.redis内存淘汰机制以及过去key处理

7.Java redis应用
  7.1jedis
  7.2 lettuce


了解数据库分类

  • 关系型数据库:Oracle,MySQL,SqlServer,DB2
  • 非关系型的数据库(NoSql):

NoSql分类

  • 键值存储(key,value) :Redis
  • 列存储数据库:HBase等
  • 文档型数据库:MongoDb等
  • 图形结构的数据库:Neo4J等

NoSql特点

  • 数据模型比较简单
  • 对数据库性能要求较高
  • 不需要高度的数据一致性
  • 需要灵活性更强的应用系统
  • 对于给定key,比较容易映射复杂值的环境.


Redis简介

Redis官网

Redis中文官网

Redis 菜鸟教程


什么是redis?

redis是是以key-value形式存储的非关系型数据库,其性能极高,Redis能支持超过 10W次每秒的读写频率

redis定位是缓存,提高数据读写速度,减轻对数据库存储和访问压力

只要涉及缓存(临时存储),首选都是redis


Redis优缺点

优点:

  • 对数据高并发读写(直接内存进行读写)
  • 对海量数据的高效率存储和访问
  • 对数据的可拓展性和高可用性
  • 单线程操作,每个操作都是原子性操作 (Redis 6 外界多线程排队等待)

缺点:

  • redis(ACID处理非常简单)
  • 无法做太复杂的关系数据库模型

redis安装,目前官方版本已经6.0.6版本,windows还是3.2(大神没有更新)

项目操作涉及到缓存操作:redis-memcache --拓展


redis-memcache与redis有什么区别?

什么是memcache?

Memcache是一个高性能,分布式于内存对象中的缓存系统,能够存储包括图像,文件,sql语句结果等数据.使用K-V形式的方式来存储数据,查询的效率高,协议简单.

区别

redismemcache
数据操作不同Redis支持的数据类型丰富list,set,hash等只支持简单的key-value存储
内存管理机制不同redis有部份存在硬盘上,这样能保证数据的持久性,支持数据的持久化memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
性能不同Redis只使用单核Memcached可以使用多核,Memcached性能要高于Redis
value 值大小不同Redis 最大可以达到 1GBmemcache 只有 1MB
集群管理不同Redis更偏向于在服务器端构建分布式存储Memcached只能采用客户端实现分布式存储
  • 使用底层模型不同:它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。redis有自己构建VM 机制
  • 应用场景:Memcached:动态系统中减轻数据库负载,提升性能;做缓存;Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统

引用参考文章:
Memcache与Redis有什么区别
Redis和Memcache区别,优缺点对比


Redis数量类型指令


1.String类型 Map<String, String> map

  • 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不存在添加

应用场景:

1.计数器 :能够快速实现技术,查询缓存的功能
2.共享session  [[每次获得用户更新信息/登录信息等从redis获取]  


2.hash类型 Map<string, Map<string, ?>> map

  • hset key hashkey hashvalue : 存入一个hash对象
  • hget key hashkey : 根据hash对象键取去值
  • hexists key hashkey : 判断hash对象是含有某个键
  • hdel key hashkey : 根据hashkey删除hash对象键值对
  • hincrby key hashkey 递增值 : 递增hashkey对应的值
  • hkeys key : 获取hash对象的所有键
  • hvals key : 获取hash对象的所有值
  • hgetall key : 获取hash对象的所有数据


3.list类型 Map<String, List>

List :类似java中的(双向)队列,是一个链表结构的集合

  • rpush key value : 往列表右边添加数据
  • lrange key start end : 范围显示列表数据,全显示则设置0 -1
  • lpush key value : 往列表左边添加数据
  • lpop key : 弹出列表最左边的数据
  • rpop key : 弹出列表最右边的数据
  • llen key : 获取列表长度

应用场景

用户收藏文章列表 article:id [aid1,aid2,aid3]


4.set类型

  • sadd key value : 往set集合中添加元素
  • smembers key : 列出set集合中的元素
  • srem key value : 删除set集合中的元素
  • spop key count: 随机弹出集合中的元素
  • sdiff key1 key2 : 返回key1中特有元素(差集)
  • sinter key1 key2:返回两个set集合的交集
  • sunion key1 key2 : 返回两个set集合的并集
  • scard key : 返回set集合中元素个数

应用场景 :去重


5.zset类型

  • zadd key score column : 存入分数和名称
  • zincrby key score column : 偏移名称对应的分数
  • zrange key start end : 按照分数升序输出名称
  • zrevrange key start end : 按照分数降序输出名称
  • zrank key name : 升序返回排名
  • zrevrank key name: 降序返回排名
  • zcard key : 返回元素个数

应用场景:排行榜

什么时候使用对应类型

如果确定使用redis, 此时需要考虑使用哪个数据类型
1.如果要排序选用zset
2.如果数据是多个且允许重复选用list
3.如果数据是多个且不允许重复选用set
4.剩下的使用string

怎么设计key与value值

key

  1. 唯一性
  2. 可读性
  3. 灵活性
  4. 时效性

value:根据 需求决定


redis进阶

redis高级命令(全局)

  • key * :返回所有key (可以模糊查询 key h*, h开头的key)
  • exists:是否存在指定key
  • expire:设置某个key的过期时间(已存在的key),使用ttl查看剩余时间
  • persist:取消过期时间
  • flushdb:清空当前数据库,flushall清空所有数据库

redis安全性

redis权限密码设置

修改对应配置文件redis.windows-service.conf ,把# requirepass foobared把#注释去掉 ,foobared修改为自己的密码,重启redis服务,使用

**redis-cli -a [密码]**指令进入redis操作,如果设置了密码,没有输入直接进行操作会报错(error)NOAUTH Authentication required.

redis事务

redis事务提供了一种“将多个命令打包, 然后一次性、按顺序地执行”的机制.Redis中一个事务从开始到执行会经历 开始事务命令入队执行事务 三个阶段,Redis是不支持回滚

  • multi方法打开事务
  • exec执行
  • discard方法取消事务


redis持久化机制

启动redis服务时,去到硬盘中加载数据 ,刚开始内存是没有数据,我们添加到内存中,redis会按照某种规则添加(持久化)到硬盘中

redis持久化两种方式:

  • RDB (快照) :默认,snapshotting.将内存中以快照的方式写入到二进制文件中,可以进行配置设置持久化方式
Snapshotting设置:
save 900 1  #900秒内如果超过1个Key被修改则发起快照保存
save 300 10 #300秒内如果超过10个key被修改,则发起快照保存
save 60 10000
  • AOF(拼接):AOF比快照方式有更好的持久化性,快照方式在一定时间间隔可能会发生数据丢失情况,使用AOF,redis会将每一个收到的写命令都通过write函数追加到命令中,重启时,会重新执行命名重建数据库内容(相当于ctrlC+ctrlV)

aof设置

appendonly yes //启动aof持久化方式有三种修改方式
#appendfsync always//收到命令就立即写到磁盘,效率最慢.但是能保证完全的持久化
#appendfsync everysec//每秒写入磁盘一次,在性能和持久化方面做了很好的折中
#appendfsync no //完全以依赖os 性能最好,持久化没保证


redis内存淘汰机制以及过去key处理

内存淘汰机制 ,四大类:

  1. LRU:短时间内没有使用的数据干掉
  2. LFU:最不经常使用的,使用次数最少与频次有关
  3. TTL:设置了过期时间的部分数据,快过期提前一点把你干掉
  4. 随机淘汰:全凭天命,阎王要你三更走,你就不能留到五更

过期key的清除操作,三种策略

  1. 惰性删除:当key多期,下次来访问时,判断是否过期,过期删除
  2. 定时删除:设置key的过期时间,到点删除
  3. 定期删除:隔一段时间,对数据进行检查,通过算法删除过期key


Java redis应用

java对redis常用的有两种jedis与lettuce


jedis

1.导入对应依赖
<!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
2.API test
  • String
public class TestStringJedis {

    @Test
    public void testJedis() {
        // 1:创建Jedis连接池
        JedisPool pool = new JedisPool("localhost", 6379);
        // 2:从连接池中获取Jedis对象
        Jedis jedis = pool.getResource();
        /* 设置密码
	    jedis.auth(密码); */
        // 3:TODO
        
        /**String**/
        jedis.set("name","xuan");
        jedis.set("age","18");
        jedis.set("delkey","hhhh");
        System.out.println(jedis.get("name"));
        // age+1
        jedis.incr("age");
        System.out.println(jedis.get("age"));
        //age -1
        jedis.decr("age");
        System.out.println(jedis.get("age"));
        //del
        //jedis.del("delkey");
        //设置失效时间 ,查询还剩多少时间
        //jedis.setex("love",30,"520");
        System.out.println(jedis.ttl("love"));

        //setnx ,如果不存在key直接添加
        jedis.setnx("name1","setnxdemo");

        //全局 获取所有key
        System.out.println(jedis.keys("*"));


        /**
         *
         */
        System.out.println(jedis);
        // 4:关闭资源
        jedis.close();
        pool.destroy();
    }
  • hash
jedis.hset("emps","age","18");
        jedis.hset("emps","kk","qq");
        System.out.println(jedis.hget("emps", "age"));

        //age+1
        jedis.hincrBy("emps","age",1);
        System.out.println(jedis.hget("emps", "age"));
        //判断是否存在
        System.out.println(jedis.hexists("emps", "name"));  //true

        //删除 dept中的name
        jedis.hdel("dept","name");
        System.out.println(jedis.hget("dept", "name"));

        //全局 获取所有key
        System.out.println(jedis.keys("*"));
  • List

    /**List**/
            jedis.rpush("name","php","java","go","python");
            System.out.println(jedis.lrange("name", 0, -1)); //[php, java, go, python]
    
            //往左边添加数据
            //jedis.lpush("name","xuan");
            System.out.println(jedis.lrange("name", 0, -1)); //[xuan, php, java, go, python]
    
            //从左边弹出数据
            System.out.println(jedis.lpop("name")); //弹出xuan  [php, java, go, python]
    
            //从右边弹出数据
            System.out.println(jedis.rpop("name")); //弹出 python  [php, java, go]
    
            //获取列表长度
            System.out.println(jedis.llen("name")); //3
    
  • Set

/**Set**/
        //添加
        jedis.sadd("name","yue","xuan","dong","hao","ying");
        //列出set中的元素
        System.out.println(jedis.smembers("name")); //[yue, xuan, hao, dong, ying]

        //随机弹出元素
        System.out.println(jedis.spop("name"));  //yue
        //删除集合中的元素
        jedis.srem("name", "xuan");
        System.out.println(jedis.smembers("name"));  //[ying, dong, hao]



        jedis.sadd("set1","1","2","3","4");
        jedis.sadd("set2","6","5","3","4");
        //比较两个集合的不同 set1相比于set2哪里不同 差集
        System.out.println(jedis.sdiff("set1", "set2"));  //[2, 1]

        //交集
        System.out.println(jedis.sinter("set1", "set2")); //[3, 4]

        //并集
        System.out.println(jedis.sunion("set1", "set2"));  //[1, 2, 3, 4, 5, 6]

        //返回指定集合的元素个数
        System.out.println(jedis.scard("set1"));
  • ZSet
/**ZSet**/

        //jedis.zadd("score",80,"xuan");
        //jedis.zadd("score",60,"tian");
        //jedis.zadd("score",100,"yue");

        //按照分数升序排序
        System.out.println(jedis.zrange("score", 0, -1)); //[tian, xuan, yue]
        ///按照分数 降序排序
        System.out.println(jedis.zrevrange("score", 0, -1)); //[yue, xuan, tian]


        //偏移名称对应的分数
       // System.out.println(jedis.zincrby("score", 10, "xuan"));  //xuan --90.0

        //升序返回排名 从0开始
        System.out.println(jedis.zrank("score", "xuan"));

        //降序,返回排名
        System.out.println(jedis.zrevrank("score", "xuan"));

        //返回元素个数
        System.out.println(jedis.zcard("score"));


lettuce

Springboot底层 默认是lettuce

Springboot-redis api方法 是redis命令全称,全局命令:封装在 对象中

1.改造成Springboot,配置对应依赖
<!--Springboot集成redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
2.API test
  • String
@SpringBootTest
public class TestRedis {

    //@Autowired
    //private RedisTemplate<String,Object> template;
    @Autowired
    private StringRedisTemplate template;

    @Test
    public void RedisTest(){
        //操作String
        //template.opsForValue().set("name","xuan");
        //template.opsForValue().set("age","18");
        //template.opsForValue().set("qqq","15");
        System.out.println(template.opsForValue().get("name"));

        //increment age+1
       System.out.println(template.opsForValue().increment("age"));  //19
        //decrement age -1
        System.out.println(template.opsForValue().decrement("age"));


        //设置key的过期时间  参数2:时间 ,参数3:时间单位
        // template.expire("qqq",30, TimeUnit.SECONDS);
        //获取剩余时间
        System.out.println(template.getExpire("qqq"));

        //全局命令
        //获得所有key
        System.out.println(template.keys("*"));
    }
}
  • Hash
 //操作hash
        template.opsForHash().put("emps","name","xuan");
        template.opsForHash().put("emps","age","18");
        template.opsForHash().put("emps","course","java"); 

        System.out.println(template.opsForHash().get("emps", "course"));  //java

        //  increment age +1
        //System.out.println(template.opsForHash().increment("emps", "age", 1));

        //判断是否有该 key 和字段
        System.out.println(template.opsForHash().hasKey("emps", "qqq"));

        //返回所有字段
        System.out.println(template.opsForHash().keys("emps")); //[name, age, course]
        //返回value
        System.out.println(template.opsForHash().values("emps"));  //[xuan, 19, java]

        //删除
        template.opsForHash().delete("emps", "course");
  • List
//操作List
        template.opsForList().rightPush("name","php");
        template.opsForList().rightPush("name","java");
        template.opsForList().rightPush("name","go");
        //template.opsForList().rightPushAll("age","18","20","19");

        System.out.println(template.opsForList().range("name", 0, -1));  //[php, java, go]
        System.out.println(template.opsForList().range("age", 0, -1));  //[18, 20, 19]

        //弹出左边
        //emplate.opsForList().leftPop("name");
        System.out.println(template.opsForList().range("name", 0, -1)); //[java, go]

        //获得长度
        System.out.println(template.opsForList().size("name"));

        //删除
        template.opsForList().remove("age",1,"18");
        System.out.println(template.opsForList().range("age", 0, -1));
  • Set
//操作Set
        //添加
        template.opsForSet().add("name","yue","xuan","dong","hao","ying");
        //获取
        System.out.println(template.opsForSet().members("name"));  //[yue, xuan, hao, dong, ying]

        
        template.opsForSet().add("set1","1","2","3","4","5");
       template.opsForSet().add("set2","8","7","6","4","5");
        //差集
        System.out.println(template.opsForSet().difference("set1", "set2"));  //[1, 2, 3]
        //交集
        System.out.println(template.opsForSet().intersect("set1", "set2"));  //[4, 5]
        //并集
        System.out.println(template.opsForSet().union("set1", "set2")); //[1, 2, 3, 4, 5, 6, 7, 8]

        //随机弹出数据
        System.out.println(template.opsForSet().pop("name"));  //ying

        //获取长度
        System.out.println(template.opsForSet().size("name"));
  • ZSet
//操作ZSet
        template.opsForZSet().add("score","y",80);
        template.opsForZSet().add("score","x",70);
        template.opsForZSet().add("score","q",60);
        template.opsForZSet().add("score","a",50);

        //按照分数升序
        System.out.println(template.opsForZSet().range("score", 0, -1));  //[a, q, x, y]
        //按照分数倒序
        System.out.println(template.opsForZSet().reverseRange("score", 0, -1)); //[y, x, q, a]

        //升序返回排名,从0开始
        System.out.println(template.opsForZSet().rank("score", "x"));  //2

        //返回元素个数
        System.out.println(template.opsForZSet().zCard("score"));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值