栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis缓存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis缓存

当并发访问比较高时,一直访问数据库会造成大量的压力,导致性能的下降,严重时直接导致系统宕机。所以我们就需要一个对访问进行缓存的数据库为数据库进行分担压力。所以我们就需要使用redis。

Redis是一个key-value存储系统,是一个分布式缓存数据库。

安装redis数据库

第一步:下载镜像文件

docker pull redis

第二步:准备配置文件

创建redis配置文件目录

mkdir -p /usr/local/docker/redis01/conf

在配置文件录下创建redis.conf配置文件(这个文件一定要创建,否在我们进行目录挂载时默认生成的是一个目录)

touch /usr/local/docker/redis01/conf/redis.conf

第三步:创建redis实例并启动

sudo docker run -p 6379:6379 --name redis01
-v /usr/local/docker/redis01/data:/data
-v /usr/local/docker/redis01/conf/redis.conf:/etc/redis/redis.conf
-d redis redis-server /etc/redis/redis.conf 

第四步:查看正在运行的程序

dicker ps

访问redis服务器


第一步:控制台直接连接redis测试

docker exec -it redis01 bash

第二步:检测redis 版本

redis-server  -v

或者

redis-cli -v

第三步:登录redis(默认不需要密码)

redis-cli

或者直接将上面的两个步骤合为一个步骤执行也可以,指令如下:

docker exec -it redis01 redis-cli

停止和启动redis服务
停止

docker stop redis01

启动

docker start redis01

重启

docker restart redis01

 可以进行查看进入redis 并执行短句验证成功:

 查看启动的redis进程信息

ps -ef|grep redis

 

 登录redis服务

登录本地:

redis-cli
或者
redis-cli -p 6379
或者
redis-cli -p 6379 -a  password #-a后面为password,此操作需要开启redis.conf文件中的 requirepass选项

 登录远程redis:

redis-cli  -h ip  -p 6379  -a  password

 关闭redis服务

127.0.0.1:6379> shutdown

系统帮助:可以基于help指令查看相关指令帮助:

 

127.0.0.1:6379> help
redis-cli 2.8.19
Type: "help @" to get a list of commands in 
      "help " for help on 
      "help " to get a list of possible help topics
      "quit" to exit
127.0.0.1:6379> help type

  TYPE key
  summary: Determine the type stored at key
  since: 1.0.0
  group: generic
Redis数据存储操作:

查看redis中所有的key:

127.0.0.1:6379> keys *
(empty list or set)

 基于key/value形式存储数据

 

 获取使用get:

 清除redis中的数据:

清除当前数据库数据:

flushdb

清除所有数据库数据:

flushall

设置时效:单位一般默认为毫秒

expire

 其中,TTL查看key的剩余时间,当返回值为-2时,表示键被删除。
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。

 取现时长设置:

Persist (取消时长设置)

Redis常用的数据类型:

Reids中基础数据结构包含字符串、散列,列表,集合,有序集合。工作中具体使用哪种类型要结合具体场景。

String类型操作实践

字符串类型是redis中最简单的数据类型,它存储的值可以是字符串,其最大字符串长度支持到512M。基于此类型,可以实现博客的字数统计,将日志不断追加到指定key,实现一个分布式自增iid,实现一个博客的的点赞操作等

incr/incrby 递增

当存储的字符串是整数时,redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。

如果数值为空,则自动增加1.

incr  key 自动增加1.    incrby key 2 根据自己定义数据自增

 decr/decrby  递减

decr key 自减1   decrby key 3 根据自定义递减

 append  尾部追加值

append key 20 根据自己定义的数值进行追加并返回总长度

 strlen 返回字符串长度

如果键值为0返回的也是0

 mset/mget 设置多个值/获取多个值

mset x 1 y 2 z 3   /  mget x y z 

 Hash类型应用实践

Redis散列类型相当于Java中的HashMap,实现原理跟HashMap一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多232-1个字段。

hset/hget   赋值和取值

hgetall 为得到全部对应hsah值

 

 HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。

hmset/hmget  同时执行多个hash集合

 hexists 判断属性是否存在

存在返回 1 不存在返回 0 

 

hdel  删除属性

 hkeys/hvals  只获取字段名/只获取字段值

 hlen   获取元素的个数

 

List类型应用实践

Redis的list类型相当于java中的linkedList,其原理就就是一个双向链表。支持正向、反向查找和遍历等操作,插入删除速度比较快。经常用于实现热销榜,最新评论等的设计。

lpush / lrange  创建list集合 /获取list值

lpush key xxx  将数值xxx存入 key集合中

lrange  key 0 -1 从列表第一个开始 到最后一个结束

 其中,Redis Lrange 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推

rpush 在对应list尾部添加字符串

linsert 在对应list的特定位置前后添加字符串

 lset  修改指定的下标元素

 lrem   删除list中与定义的数字相同value元素

且删除的value也相同才可。 当定义的数字大于0时从头到尾删除,当小于0时从尾到头

 ltrim   保留指定key的取值范围

 

lpop 从list头部删除元素

lindex 根据下标返回对应的元素

 

rpoplpush

从第一个list的尾部移除元素并添加到第二个list的头部,最后返回被移除的元素值,整个操作是原子的.如果第一个list是空或者不存在返回nil:
rpoplpush lst1 lst1
rpoplpush lst1 lst2

 rpop 从尾部删除

 

 del  清除集合元素

 

Set类型应用实践

Redis的Set类似Java中的HashSet,是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

sadd  添加元素 smembers 获取元素

重复添加会失败 返回0

 spop 移除集合中的一个随机元素。。。。

 scard 获取集合中成员个数

smove 移动一个元素到另外一个集合

 sunion 实现集合的并集操作

 

java中应用redis

创建meven工程

添加相关依赖:


    
        
            redis.clients
            jedis
            3.5.2
        

       
            com.google.code.gson
            gson
            2.8.6
        

通过Jedis连接redis,并进行测试。

public class JedisTests {
    @Test
    public void testGetConnection(){
        //通过jedis对象连接redis
        Jedis jedis = new Jedis("192.168.64.131", 6379);
        //添加数据
        jedis.set("id","100");
        jedis.set("name","tome");
        //进行修改数据
        jedis.incr("id");
        jedis.incrBy("id",100);
        jedis.set("name","tom");
        //得到数据
        String id = jedis.get("id");
        String name = jedis.get("name");
        System.out.println(id+name);
        //删除数据
//        jedis.del("id","name");
        //释放资源
        jedis.close();
    }
}

 测试字符串操作:

    
    @Test
    public void test2(){
        //通过jedis对象连接redis
        Jedis jedis = new Jedis("192.168.64.131", 6379);

        HashMap map = new HashMap<>();//创建一个map集合
        map.put("id",1000);
        map.put("name","tomm");
        Gson gson = new Gson();   //通过gson对象转换成字符串
        String s = gson.toJson(map);
        String s1 = UUID.randomUUID().toString();  //获取一个随机uuid
        jedis.set(s1,s); //存储到redis中
        String s2 = jedis.get(s1);
        System.out.println(s2);  //查看

        jedis.hset("xx","xxx","xxxx");//测试hset存储
        Map xx = jedis.hgetAll("xx");
        //自动根据时间删除数据
        jedis.expire("xx",10);
        System.out.println(xx);
        jedis.close();


    }

测试list:

测试list结构
     */
    @Test
    public void test3(){
        //通过jedis对象连接redis
        Jedis jedis = new Jedis("192.168.64.131", 6379);
        //存储数据
        jedis.lpush("list110","a","b","c","d");
        //更改数据
        Long lpos = jedis.lpos("list110", "a");//获取a的位置
        jedis.lset("list110",lpos,"E");//将a换成E
        //获取数据
        int list1 = jedis.llen("list110").intValue();//获取list元素个数
        List lll = jedis.lrange("list110", 0, -1);
        System.out.println(lll);
        List list11 = jedis.rpop("list110", list1);//获取并删除list所有元素
        System.out.println(list11);
        jedis.close();

测试set类型

   
    @Test
    public void test4(){
        //通过jedis对象连接redis
        Jedis jedis = new Jedis("192.168.64.131", 6379);

        jedis.sadd("lsp","1","2","3");
        Set lsp = jedis.smembers("lsp");
        System.out.println(lsp);
        jedis.close();
    }
创建JedisPool连接池

我们直接基于Jedis访问redis时,每次获取连接,释放连接会带来很大的性能开销,可以借助Jedis连接池,重用创建好的连接,来提高其性能,简易应用方式如下:

public class JedisDataSource {

    private static final String IP = "192.168.64.131";
    private static final int PORT = 6379; //redis.conf 默认端口号

    
    private static volatile JedisPool jedisPool;
    //懒汉式池对象的创建
    public static Jedis getConnection(){

        if (jedisPool == null){
            synchronized (JedisDataSource.class){
                if (jedisPool==null){
                    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                    jedisPoolConfig.setMaxTotal(16);
                    jedisPoolConfig.setMaxIdle(8);
                    JedisPool jedisPool = new JedisPool(jedisPoolConfig, IP, PORT);
                    //创建对象分析
                    //1.开辟内存空间
                    //2.执行属性的默认初始化
                    //3.执行构造方法
                    //4.将创建的对象的内存地址赋值给jedisPool变量
                    //假如使用了volatile修饰jedisPool变量,可以保证如上几个步骤是顺序执行的

                }
            }
        }

        return jedisPool.getResource();
    }
    public static void close(){
        jedisPool.close();
    }
RedisTemplate

RedisTemplate为SpringBoot工程中操作redis数据库的一个Java对象,此对象封装了对redis的一些基本操作。是一个比上面方法方便的方式。

添加对应依赖:

   
       
           
               org.springframework.boot
               spring-boot-dependencies
               2.3.2.RELEASE
               import
               pom
           
       
   

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

在yml配置中进行配置:

spring:
  redis:
    host: 192.168.64.131
    port: 637

相应测试,存储数据,存储对象。 

@SpringBootTest
public class test00 {
    
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void lsp() throws JsonProcessingException {
        //通过调用底层的对应方法进行实现数据存储
        ValueOperations vo = redisTemplate.opsForValue();
        vo.set("id","66");
        Object id = vo.get("id");
        System.out.println(id);
        //设置数据存活时间
        vo.set("z","100", Duration.ofSeconds(100));

        //更新数据
        String s = UUID.randomUUID().toString();
        vo.set(s,"mike3");
        vo.set(s,"mike2");
        vo.set(s,"mike1");
        Object o = vo.get(s);
        System.out.println(o); //数据会进行覆盖

        //获取Hash操作对象
        HashOperations ho = redisTemplate.opsForHash();
        ho.put("lsp","id",100);
        ho.put("lsp","name","lll");
        Object o1 = ho.get("lsp", "id");
        Object o2 = ho.get("lsp", "name");
        System.out.println(o1+"name"+o2);


        //将对象写入redis数据库
        ValueOperations vo2 = redisTemplate.opsForValue();
        user01 user01 = new user01();
        user01.setId(10);
        user01.setName("王大陆");
        //将对象转换为json串
        ObjectMapper objectMapper = new ObjectMapper();
        String s1 = objectMapper.writevalueAsString(user01);
        vo2.set("6",s1);
        Object o3 = vo2.get("6");
        System.out.println(o3);

    }
}

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/715986.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号