Redis

Redis是一个基于 内存key-value结构数据库
         基于内存存储,读写性能高
         适合存储热点数据(热点商品,资讯,新闻)
         企业应用广泛
适合的场景: 高并发,热点数据

1.Redis简介

Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库缓存消息中间件。它存储的value类型比较丰富,也被称为结构化的NoSql数据库

NoSql,不仅仅是SQL,泛指非关系型数据库。NOSql数据库并不是要取代关系型数据库,而是关系型

数据库的补充


2.Redis应用场景

缓存

最终我们使用redis,是为了减轻mysql数据库压力,提高用户的体验

任务队列

消息队列

分布式锁


3.安装Redis

(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.


4.远程访问配置

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 密码


5.Redis存储数据

只是常用的,更多内容可去redis中文网查询

1.字符串(string)

普通字符串,常用

set key value: 设置指定key的值

get key:获取指定key的值

setex key seconds value:指定key的值,并将key 的过期时间设为seconds秒

setnx key value:只有在key不存在时设置key值


2.哈希(hash)

适合存储对象

hset key field value: 将哈希表key中的字段field设为value

hget key field: 获取存储在哈希表中指定字段的值

hdel key field: 删除存储在哈希表中指定字段

hkeys key :获取哈希表中所有字段

hvals key :获取哈希表中所有值

hgetall key:获取在哈希表中指定key的所有字段和值


3.列表(list):

按照插入顺序排序,可以有重复元素

lpush key value1 [value2] :将一个或多个值插入到列表头部(l从左边插r从右边插)

lrange key start stop :获取列表指定范围内的元素(lrange key 0 -1:查询所有)

rpop key :移除并获取列表最后一个元素

llen: 获取列表长度

brpop key1 [key2] timeout: 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止


4.集(set):

无序集合,没有重复元素

sadd key member1 [member2] : 向集合中添加一个或多个成员。

srem key member1 [member2] : 移除集合中一个或多个成员

smembers key : 返回集合中所有成员

sinter key1 [key2] : 返回所有集合的交集

sunion key1 [key2] : 返回所有集合的并集

sdiff key1 [key2] : 返回所有集合的差集


5.有序集合(sorted set/zset):

集合中每个元素关联一个分数(double的score),根据分数升序排序没有重复元素,但分数可以重复

zadd key score1 meber1 [score2 meber2] : 向有序集合添加一个或多个成员,或者更新已存在成员

的分数。

zrange key start stop [withscores] : 通过索引区间返回有序集合中指定区间内的成员,[withscores]是分数也显示出来

zincrby key increment member : 有序集合中对指定成员的分数加上增量increment

zrem key member1 [member2] : 移除有序集合中一个或多个成员


6.通用命令:

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


6.Jedis

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();
    }
}

7.Spring Data Redis

Spring对Redis客户端进行了整合,提供了Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis

Spring data Redis 是Spring的一部分,提供了在Spring应用中通过简单的配置就可以访问Redis服务,对Redis底层开发包进行了高度封装。

1.Spring Data 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 redisTemplate(RedisConnectionFactory connectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate<>();

        //默认的key序列化器为:JdkSerializationRedisSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.setConnectionFactory(connectionFactory);

        return 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;
    }
}

你可能感兴趣的:(redis,redis,数据库,缓存)