Redis入门总结

Redis是什么

Redis 是一个高性能的开源的、C语言写的Nosql(非关系型数据库),数据保存在内存中(快,容易丢失)。

Redis 是以key-value形式存储的Nosql,和传统的关系型数据库不一样。不一定遵循传统数据库的一些基本要求,比如说,不遵循sql标准,事务,表结构等等,非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。

特点(优势)

1.数据保存在内存,存取速度快,并发能力强

2.它支持存储的value类型相对memcached更多,包括string(字符串)、list(链表)、set(集合)、 zset(sorted set --有序集合)和hash(哈希类型)。

3.redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库(如MySQL)起到很好的补充作用。

4.它提供了Java,C/C++,C#,PHP,JavaScript等客户端,使用很方便。

5.Redis支持集群(主从同步)。数据可以主服务器向任意数量从的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。

6.支持持久化,可以将数据保存在硬盘的文件中

7.支持订阅/发布(subscribe/publish)功能 QQ群

8.数据能够支持过期设置

数据存储:

存放到内存中,并且还能不定期持久化到硬盘.

Value类型:

相较于memcached支持Value更多

客户端支持:

支持多种客户端-跨语言

超大并发支持:

支持集群

免费

redis常见数据类型

string==>String

set 设置一个字符串

get 获取一个字符串

mset 设置多个

mget 获取多个

如果设置的字符串的值是数值,可以用命令来进行加减操作

incr、decr、单个增减

incrby 、decrby、多个增减

incrbyfloat 浮点数

字符串在实际项目当中更多的石存JSON格式的字符串,缺点就是存了复杂的JSON字符串之后我们需要进行序列化操作

hash==>HashMap

hash用于存储多个键值对,一个存储空间可以存储多个数据,一般可以使用hash来存储对象信息。

基本操作:

存储数据(增)

语法:hset key field1 value1 field2 value2 ... fieldN valueN

redis4.0之后可以使用hset指令来完成多个属性的同时设置

redis4.0之前使用的hmset的指令来完成多个属性的同时设置,4.0之后,该指令被废弃,使用hset指令替代了。

获取数据(查)

查询单个属性的value的语法:hget key field

查询某个key下的所有属性的语法:hgetall key

一次查询多个属性的value的语法:hmget key field1 field2 ... fieldN

修改数据(改):用到的指令跟新增是一样的

语法:hset key field value

删除数据(删)

语法:hdel key field1 field2 ... fieldN

查看某个key下有多少个属性:hlen key

查看某个key下是否存在某个属性:hexists key field

查看某个key下所有的属性:hkeys key 了解

查看某个key下所有的value:hvals key 了解

hsetnx key field value:判断hash中是否存在某个field,如果存在,不做任何操作,如果不存在,则将键值对保存到hash中。

对数据型数据进行增减操作:

整数

hincrby key field increment

increment指的是要增加或减少的整形数据,值为正,做增加,值为负,做减少

浮点

hincrbyfloat key field increment

increment指的是要增加或减少的浮点数据,值为正,做增加,值为负,做减少

注意:hash类型设计之初就不是为了存储大量对象使用的,不要将其视为专门用于存储对象使用的数据类型。

list==>List

list其实就是类似于java中的list集合(LinkedList),用于存储多个数据。底层使用的是双向链表,对于list来说,着重考虑的是数据进行存储空间和从存储空间中取出数据的顺序。

我们可以使用list来实现队列和栈的效果。

基本操作:

存:

lpush(从左边向list中保存数据)

rpush(从右边向list中保存数据)

语法:

lpush key value1 value2 ... valueN

rpush key value1 value2 ... valueN

取:

取单个数据的语法:lindex key i,从list左边向外去获取数据,i,指的是list中保存的数据的下标

取多个数据的语法:lrange key start stop,start:从哪个下标开始,stop:到哪个下标结束,取值为-1时,表示要获取list中所有的数据

在获取的同时删除掉某个数据:

lpop key:从左边开始从list中获取第一个数据,并将该数据从list中删除掉

rpop key:从右边开始从list中获取第一个数据,并将该数据从list中删除掉

以上两条指令是会有返回值的。

从左向右,删除list中的指定数据:lrem key count value

count:要删除几个

value:要删除的值

该指令不会将被删除的数据返回出来,返回的是指令执行时实际删除的数据的个数。

set==>HashSet

set也是用于存储多个数据的。

list和set的区别:

list底层是双向链表,set的底层为hash,查询效率上来说,set优于list;

list是有序的,set是无序的;

list中元素是可重复出现的,set元素不允许重复;

基本操作:

存:

语法:sadd key member1 member2 ... memberN

取:

取全部:smembers key

删:

语法:srem key member1 member2 ... memberN

查看set中存储了多少个数据: scard key

查看set中是否存在某个元素:sismember key member

随机获取set中的元素(1个或多个):srandmember key [count] 了解

count是一个整数值,是可选的,如果设置了,则随机对应数值个数的数据

如果不设置,则默认随机获取set某一个元素

随机从set中获取并移除一个或多个元素:spop key [count]

spop指令的执行结果是对应的set中元素,并会将被匹配到的元素从set中移除掉。

zset(sorted set)==>TreeSet

zset是基于set的实现,在set的基础上增加了score(分值)属性用于进行排序。

基础操作:

存:

zadd key score1 member1 score2 member2 ... scoreN memberN

取:获取时,是按照score分值数值进行排序

升序:zrange key start stop [withscores]

加上withscores,返回时会显示score分值

降序:zrevrange key start stop [withscores]

查询score的值在某个范围内的元素:

升序:

zrangebyscore key min max [withscores] [limit offset count]

min:要查询的最小分值

max:要查询的最大分值

offset:从哪个下标开始

count:要查询几个元素

降序:

zrevrangebyscore key max min [withscores] [limit offset count]

注意:zset在排序时是按score的值进行排序的。

删:

zrem key member1 member2 ... memberN

删除分值在某个区间之内的元素:

按分值进行删除:

zremrangebyscore key min max

min和max还是指定的分值score

按索引进行删除:

zremrangebyrank key start stop

start和stop是指定的下标区间

统计:

zcard key:统计zset中的元素个数

zcount key min max:统计指定score分值区间内的元素个数

获取索引:了解

升序:

zrank key member

降序:

zrevrank key member

还有许多的数据类型,建议参考官网。

使用场景

1. 中央缓存(记住)

经常查询数据,不经常变化的数据,放到读速度很快的空间(内存),以便下次访问减少时间。减轻压力(数据库的压力),减少访问时间.而redis就是存放在内存中的。

Hibernte二级缓存,mybatis二级缓存,这些缓存默认都不支持在集群环境使用.redis中央缓存就OK.

2. 计数器应用

网站通常需要统计注册用户数,网站总浏览次数等等

新浪微博转发数、点赞数

3. 实时防攻击系统

暴力破解:使用工具不间断尝试各种密码进行登录。防:ip(账号)--->num,到达5次以后自动锁定IP,30分钟后解锁

解决方案:

1、存数据库

登录操作的访问量非常大

2、static Map<String,int> longinFailNumMap;

Map存储空间有限,大批量就不行,并且断电以后数据丢失。

问题:

1、每次查询数据库,查询速度慢,多次写 内存

2、断电会丢失数据,多个节点,不能共用 redis集群,容量可以无限大,可以共享数据、并且支持过期

4. 排行榜

总积分榜,今日积分榜,周积分,月积分,季度积分

方案:从数据库中查出来计算.

问题:

1、实时查询,查询速度慢

2、还要进行各种计算。

5. 设定有效期的应用

设定一个数据,到一定的时间失效。 自动解锁,购物券

6. 自动去重应用

Uniq 操作,获取某段时间所有数据排重值 这个使用 Redis 的 set 数据结构最合适了,只需要不断地将数据往 set 中扔就行了,set 意为 集合,所以会自动排重。

7. 队列

构建队列系统 使用 list 可以构建队列系统,使用 sorted set 甚至可以构建有优先级的队列系统。

秒杀:可以把名额放到内存队列(redis),内存就能处理高并发访问。

价格低,数量有限,有约束的时间:访问的多,服务器压力很大.

8. 消息订阅系统

Pub/Sub 构建实时消息系统 Redis 的 Pub/Sub 系统可以构建实时的消息系统,比如很多用 Pub/Sub 构建的实时聊天系统 的例子。

比如QQ群消息

集成spring-boot

Redisson

1.导入依赖

<dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson-spring-boot-starter</artifactId>
      <version>3.19.1</version>
</dependency>

2.配置

spring:
  redis:
    host: localhost
    port: 6379

spring-data-redis

spring-data-redis是spring-data项目其中的一块,专门用于操作redis的。

优势:了解

  1. 连接池进行自动管理,提供了一个高封装度的RedisTemplate。

  2. 将大量的api进行了封装,将同类型的操作封装到一个叫operation接口中;

    ValueOperations:简单的k-v操作(String)

    ListOperations:针对redis中list类型相关操作

    HashOperations:针对redis中hash类型相关操作

    SetOperations:针对redis中set类型相关操作

    ZSetOperations:针对redis中zset类型相关操作

  3. 序列化/反序列化,提供了多种序列化策略:

    JdkSerializationRedisSerializer:jdk的序列化策略,pojo对象的存储场景,默认策略

    StringRedisSerializer:key或者是value都是字符串

    Jackson2JsonRedisSerializer:提供了javabean和json之间的转换能力

    OxmSerializer:提供了javabean和xml之间的转换能力

boot项目中使用spring-data-redis的步骤:

  1. 引入相关依赖(spring-boot-starter-data-redis)

    <!--引入spring-data-redis
            后期需要做两个配置:
            redis的主机
            redis的端口
            配置主机的原因:  redis是安装在linux上,
                            而springboot自动配置中,
                            主机配置的是localhost
            配置端口的原因:我们在linux上启动的端口号是6380,
                          而自动配置中,
                          端口的默认配置是6379
            -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

  2. 在业务层中装配Redistemplate

    //泛型:
    //1.是key的数据类型
    //2.是value的数据类型
    @Resource
    private RedisTemplate<String,User> redisTemplate;

    此处要注意,不要使用@Autowried注解去装配,而应该使用@Resource去完成装配

  3. 在业务方法中通过Redistemplate对象,去获取操作指定数据类型的operation对象

    //1.通过redistemplate对象去获取操作redis的相应接口对象(ListOperations)
    //redistemplate有相关的api专门用于获取操作某种数据类型的对象
    //redistemplate.opsFor***()   ***指的是数据类型
    ListOperations<String,User> listOperations = redisTemplate.opsForList();

  4. 通过operation对象支调用相关的api完成对redis的增删改查

    //假设redis中保存了热点数据, 是一个list,key是users
    //查询
    List<User> users = listOperations.range("users", 0, -1);
    //新增
    listOperations.leftPushAll("users",list);//将热点数据保存到redis中

  5. 如果linux上redis启动的端口不是6379,则在springboot配置文件中应该配置端口号,除此以外,由于是远程连接的redis,在配置文件中还需要配置redis的主机。

    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.90.10:3306/test?characterEncoding=utf-8&useSSL=false
        username: root
        password: root
      redis:
        port: 6380
        host: 192.168.90.10
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    

  6. 使用redis的桌面应用rdm去测试远程连接linux的redis,需要关闭掉linux上的redis的受保护模式

    ## 查看redis的受保护模式是否开启,yes开启,no关闭
    config get protected-mode
    ## 关闭redis的受保护模式
    config set protected-mode no

    除此以外,如果还是不能连接,则需要将redis.conf配置文件中的bind绑定的主机改为0.0.0.0

Spring-Cache(with redisson)

1.加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2.改配置

spring:
  cache:
    type: redis
    redis:
      time-to-live: 60S

3.加注解

    @EnableCaching 加在启动类上
    public class xxxxApplication{}


    @Override
    @Cacheable(cacheNames = "accountCache",key = "#accountId")
    public Account findById(Integer accountId) {
        log.info("从数据库中查询用户:{}",accountId);
        return getById(accountId);
    }

    @CachePut(cacheNames = "accountCache",key = "#account.accountId")
    public Account modify(Account account){
        log.info("修改数据库:{}",account);
        updateById(account);
        return account;
    }

    @CacheEvict(cacheNames = "accountCache",key = "#accountId")
    public void delAccount(Integer accountId){
        log.info("删除用户:{}",accountId);
    }

4.redisson的sprign-cache 可单独写配置文件,针对某一个缓存

@Configuration
public class CacheAppConfig {

    @Bean
    CacheManager cacheManager(RedissonClient redissonClient) {
        Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
        // 创建一个名称为"testMap"的缓存,过期时间ttl为24分钟,同时最长空闲时maxIdleTime为12分钟。
        config.put("userCache", new CacheConfig(20*1000, 15*1000));

        return new RedissonSpringCacheManager(redissonClient, config);
    }

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值