Redis基础

一、Redis介绍

Redis诞生于2009年,全称是Remote Dictionary Server远程词典服务器,是一个基于内存的键值型NoSQL数据库。

特征:

  1. 键值(Key-Value)型,Value支持多种不同的数据结构,功能丰富。
  2. NoSQL,数据存储灵活。
  3. 单线程,每个命令具有原子性。
  4. 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
  5. 支持数据持久化。
  6. 支持主从集群、分片集群。
  7. 支持多语言客户端。

二、认识NoSQL

NoSQL(Not Only SQL):非关系型数据库,数据存储灵活,有键值、文档等多种模型。读写快、易扩展,适合大数据、高并发场景。

SQL与NoSQL对比

SQLNoSQL
数据结构结构化非结构化
数据关联关联的无关联的
查询方式SQL查询非SQL
事务特性ACIDBASE
存储方式磁盘内存
扩展性垂直水平
使用场景
  1. 数据结构稳定。
  2. 相关业务对数据安全性、一致性要求较高。
  1. 数据结构不固定
  2. 相关业务对数据安全性、一致性要求不高
  3. 对性能要求高。
例子
  1. MySQL
  1. Redis:键值类型
  2. MongoDB:文档类型
  3. HBase:列类型
  4. Neo4J:Graph类型
  • 存储方式
    1. 关系型数据库基于磁盘进行存储,会有大量的磁盘IO,对性能有一定影响
    2. 非关系型数据库,他们的操作更多的是依赖于内存来操作,内存的读写速度会非常快,性能自然会好一些
  • 扩展性
    1. 关系型数据库集群模式一般是主从,主从数据一致,起到数据备份的作用,称为垂直扩展。
    2. 非关系型数据库可以将数据拆分,存储在不同机器上,可以保存海量数据,解决内存大小有限的问题。称为水平扩展。
    3. 关系型数据库因为表之间存在关联关系,如果做水平扩展会给数据查询带来很多麻烦

三、Redis常见数据类型及命令

Redis 常见数据类型有 String、Hash、List、Set、Sorted Set 。String 就是字符串,比如存用户信息;Hash 适合存对象,比如用户资料;List 可当队列,实现消息排队;Set 能去重,比如统计在线用户;Sorted Set 带排序,像排行榜场景。

1、String类型

String类型的常见命令:

    •    SET:添加或者修改已经存在的一个String类型的键值对

    •    GET:根据key获取String类型的value

    •    MSET:批量添加多个String类型的键值对

    •    MGET:根据多个key获取多个String类型的value

    •    INCR:让一个整型的key自增1

    •    INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2

    •    INCRBYFLOAT:让一个浮点类型的数字自增并指定步长

    •    SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行

    •    SETEX:添加一个String类型的键值对,并且指定有效期

2、Hash类型

Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构。
String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便:

 KEYVALUE
heima:user:1{name:"Jack", age:21}
heima:user:2 {name:"Rose", age:18}

Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:

 KEYVALUE
fieldvalue
heima:user:1nameJack
age21
heima:user:2nameRose
age18

Hash类型的常见命令:

    •    HSET key field value:添加或者修改hash类型key的field的值

    •    HGET key field:获取一个hash类型key的field的值

    •    HMSET:批量添加多个hash类型key的field的值

    •    HMGET:批量获取多个hash类型key的field的值

    •    HGETALL:获取一个hash类型的key中的所有的field和value

    •    HKEYS:获取一个hash类型的key中的所有的field

    •    HVALS:获取一个hash类型的key中的所有的value

    •    HINCRBY:让一个hash类型key的字段值自增并指定步长

    •    HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行

3、List类型

Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。特征也与LinkedList类似:

    •    有序

    •    元素可以重复

    •    插入和删除快

    •    查询速度一般

List类型常见命令有:

    •    LPUSH key element ...:向列表左侧插入一个或多个元素

    •    RPUSH key element ...:向列表右侧插入一个或多个元素

    •    LPOP key:移除并返回列表左侧的第一个元素

    •    RPOP key:移除并返回列表右侧的第一个元素

    •    LRANGE key start end:返回列表中指定范围内的元素,start、end 从 0 开始,-1 表示最后一个元素

    •    BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

4、Set类型

Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:

    •    无序

    •    元素不可重复

    •    查找快

    •    支持交集、并集、差集等功能

Set类型常见命令:

    •    SADD key member ... :向Set中添加一个或多个元素

    •    SREM key member ... :移除Set中的指定元素

    •    SCARD key :返回Set中元素的个数

    •    SISMEMBER key member:判断一个元素是否存在于Set中

    •    SMEMBERS:获取Set中的所有元素

    •    SINTER key1 key2 ... :求多个Set的交集

    •    SUNION key1 key2 ... :求多个Set的并集

    •    SDIFF key1 key2 ... :求两个Set的差集

5、Sorted Set类型

Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。
SortedSet具备下列特性:

    •    可排序

    •    元素不重复

    •    查询速度快

因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。

SortedSet类型常见命令:

    •    ZADD key score member:添加一个或多个元素到SortedSet,如果已经存在则更新其score值

    •    ZREM key member:删除SortedSet中的一个指定元素

    •    ZSCORE key member:获取SortedSet中的指定元素的score值

    •    ZINCRBY key increment member:让SortedSet中的指定元素的score值按increment值自增

    •    ZCARD key:获取SortedSet中的元素个数

    •    ZRANK key member:获取指定元素在SortedSet中的排名(默认从小到大排序)

    •    ZCOUNT key min max:统计score值在给定范围内的所有元素的个数

    •    ZRANGE key min max:按照score排序后,获取指定排名范围内的元素

    •    ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素

    •    ZDIFF、ZINTER、ZUNION:求差集、交集、并集

注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可。

四、Redis的java客户端及SpringDataRedis快速入门

1、Redis的几种客户端

    •    Jedis:以 Redis 命令作为方法名称,学习成本低,简单实用。不过 Jedis 实例是线程不安全的,多线程环境下得基于连接池来用。

    •    Lettuce:基于 Netty 实现,支持同步、异步和响应式编程方式,而且线程安全。还支持 Redis 的哨兵模式、集群模式和管道模式。

    •    Redisson:基于 Redis 实现的分布式、可伸缩的 Java 数据结构集合。有 Map、Queue、Lock、Semaphore、AtomicLong 这些强大功能。

    •    java-redis-client:一个很简单但很完整的 Java 客户端,不到 200 行代码,还没有依赖。

    •    vertx-redis-client:提供了异步 API 来和 Redis 数据结构服务器交互~

2、SpringDataRedis快速入门

2.1  什么是SpringDataRedis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis 。

    •    提供了对不同Redis客户端的整合(Lettuce和Jedis)

    •    提供了RedisTemplate统一API来操作Redis

    •    支持Redis的发布订阅模型

    •    支持Redis哨兵和Redis集群

    •    支持基于Lettuce的响应式编程

    •    支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化

    •    支持基于Redis的JDKCollection实现

2.2  RedisTemplate工具类

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:
API 返回值类型 说明 
redisTemplate.opsForValue() ValueOperations 操作String类型数据 
redisTemplate.opsForHash() sHashOperation 操作Hash类型数据 
redisTemplate.opsForList() ListOperations 操作List类型数据 
redisTemplate.opsForSet() SetOperations 操作Set类型数据 
redisTemplate.opsForZSet() ZSetOperations 操作SortedSet类型数据 
redisTemplate  通用的命令 

API返回值类型说明
redisTemplate.opsForValue()ValueOperations操作String类型数据
redisTemplate.opsForHash()HashOperations操作Hash类型数据 
redisTemplate.opsForList()ListOperations操作List类型数据 
redisTemplate.opsForSet()SetOperations操作Set类型数据
redisTemplate.opsForZSet()ZSetOperations操作SortedSet类型数据
redisTemplate通用的命令
2.2.1  自定义序列化

RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化。

JDK序列化的缺点:

  • 可读性差
  • 内存占用较大

因此,我们可以自定义RedisTemplate的序列化方式,代码如下

编写一个配置类:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer =
                new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }
}

这里采用了JSON序列化来代替默认的JDK序列化方式,将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。 

2.3  StringRedisTemplate

Spring 默认提供了一个 StringRedisTemplate 类,它的 key 和 value 的序列化方式默认就是 String 方式。省去了我们自定义 RedisTemplate 的过程:

@Autowired
private StringRedisTemplate stringRedisTemplate;
// JSON工具
private static final ObjectMapper mapper = new ObjectMapper();

@Test
void testStringTemplate() throws JsonProcessingException {
    // 准备对象
    User user = new User("虎哥", 18);
    // 手动序列化
    String json = mapper.writeValueAsString(user);
    // 写入一条数据到redis
    stringRedisTemplate.opsForValue().set("user:200", json);

    // 读取数据
    String val = stringRedisTemplate.opsForValue().get("user:200");
    // 反序列化
    User user1 = mapper.readValue(val, User.class);
    System.out.println("user1 = " + user1);
}

这里通过 StringRedisTemplate 实现了对象的存储和读取,借助 JSON 工具来做序列化和反序列化,很方便呢~

2.4 小结

RedisTemplate的两种序列化实践方案
方案一:

    1.    自定义RedisTemplate

    2.    修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

方案二:

    1.    使用StringRedisTemplate

    2.    写入Redis时,手动把对象序列化为JSON

    3.    读取Redis时,手动把读取到的JSON反序列化为对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值