Redis

WuTong 2024-6-18 23 6/18

Redis

Redis具有十大基础类型

Redis具有十大基础类型,分别是:Strings、Lists、Sets、Hashes、Sorted sets、Streams、Geospatial、HyperLogLog、Bitmaps、Bitfields

redis字符串(string)

String(字符串) 官网地址:Redis Strings | Docs

string是redis最基本的类型,一个key对应一个value。

string类型是二进制安全的,意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象。

string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。

根据字符串的格式不同,又可以分为3类:

string:普通字符串

int:整数类型,可以做自增、自减操作

float:浮点类型,可以做自增、自减操作

不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。

String类型的常见命令

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

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

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

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

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

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

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

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

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

redis列表(List)

List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。

你可以添加一个元素到列表的头部(左边)或者尾部(右边)

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

1.有序

2.元素可以重复

3.插入和删除快

4.查询速度一般

常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

它的底层实际是个双端链表,最多可以包含 2^32-1 个元素(4294967295,每个列表超过40亿个元素)

List类型的常见命令

List的常见命令有:

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

LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil

RPUSH key element..:向列表右侧插入一个或多个元素RPOP key:移除并返回列表右侧的第一个元素

LRANGE key starend:返回一段角标范围内的所有元素

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

redis哈希表(Hash)

Redis hash 是一个 string 类型的 field(字段)和 value(值)的映射表,hash 特别适合用于存储对象。

Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构。

String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便。

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

Redis 中每个 hash 可以存储 2^32-1 键值对(40多亿)

Hash类型的常见命令

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中的所有的fieldHVALS:获取一个hash类型的key中的所有的value

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

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

redis集合(Set)

Set(集合)

Redis 的 Set 是 string 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是 intset 或者hashtable。

Redis 中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O (1)。

集合中最大的成员数为 2^32-1(4294967295,每个集合可存储40多亿个成员)。

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

1.无序

2.元素不可重复

3.查找快

4.支持交集、并集、差集等功能

Set类型的常见命令

String的常见命令有:

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

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

SCARD key:返回set中元素的个数

SISMEMBER keymember:判断一个元素是否存在于set中

SMEMBERS:获取set中的所有元素

SINTER key1 key2..:求key1与key2的交集

SDIFF key1 key2.:求key1与key2的差集

redis有序集合(ZSet)

zset(sorted set:有序集合)

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

zset集合是通过哈希表实现的,所以添加,删除,査找的复杂度都是 O(1)。 集合中最大的成员数为 2^32-1。

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

1.可排序

2.元素不重复

3.查询速度快

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

Sortedset类型的常见命令

Sortedset的常见命令有:

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

ZREM key member:删除sorted set中的一个指定元素

ZSCORE key member:获取sorted set中的指定元素的score值

ZRANK key member:获取sorted set 中的指定元素的排名

ZCARD key:获取sorted set中的元素个数

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

ZINCRBY keyincrement member:让sorted set中的指定元素自增,步长为指定的increment值

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

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

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

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

redis地理空间(GEO)

Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,包括

添加地理位置的坐标。

获取地理位置的坐标。

计算两个位置之间的距离。

根据用户给定的经纬度坐标来获取指定范围内的地理位置集合

redis基数统计(HyperLogLog)

HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

redis位图(bitmap)

Bit arrays (or simply bitmaps,我们可以称之为 位图)

由许许多多的小格子组成,每一个格子里面只能放1或者0,用它来判断YIN状态说的专业点,每一个个小格子就是一个个bit。

由0和1状态表现的二进制位的bit数组。

redis位域(bitfield)

通过bitield命令可以一次性操作多个比特位域(指的是连续的多个比特位),它会执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应操作的执行结果。

说白了就是通过bitfield命令我们可以一次性对多个比特位域进行操作。

redis流(Stream)

Redis Stream 是 Redis 5.0 版本新增加的数据结构。

Redis stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅(pub/sub)来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。

简单来说发布订阅(pub/sub)可以分发消息,但无法记录历史消息。

而 Redis stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

Redis常用命令

官网手册:Commands | Docs (redis.io)

命令不区分大小写,但是key区分大小写。

帮助命令:help @类型

keys * 查看当前库中所有的key。

exists key 判断某个key是否存在。

type key 查看你的key是什么类型。

del key 删除指定的key数据。

unlink key 非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后续的异步中操作。

ttl key 查看还有多少秒过期,-1表示永不过期,-2表示已经过期。

expire key 秒数 为给定的key设置过期时间。

move key dbindex 【0-15】 将当前数据库的key移动到给定的数据库db中。

select dbindex 切换数据库【0-15】,默认为0。

dbsize 查看当前数据库key的数量。

flushdb 清空当前数据库key的数量。

flushall 通杀全部库。

Redis的key允许有多个单词形成层级结构

Redis的key允许有多个单词形成层级结构,多个单词之间用 ":" 隔开,格式如下:

项目名:业务名:类型:id

这个格式并非固定,也可以根据自己的需求来删除或添加词条。

例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:

user相关的key:heima:user:1

product相关的key:heima:product:1

Redis的Java客户端

Redis

Jedis

Jedis的官网地址:https://github.com/redis/iedis,我们先来个快速入门:

1.引入依赖:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.0</version>
</dependency>

2.建立连接

private Jedis jedis;
@BeforeEach
void setUp(){
    //建立连接
    jedis = new Jedis("192.168.150.101",6379);
    // 设置密码
    jedis.auth("123321");
    // 选择库
    jedis.select(0);
}

3.测试string

@Test
void teststring(){
    // 插入数据,方法名称就是redis命令名称,非常简单
    String result =jedis.set("name"","张三”);
    System.out.println("result="u+ result);
    // 获取数据
    String name = jedis.get("name");
    System.out.println("name = " + name);
}

4.释放资源

@AfterEach
void tearDown(){
    // 释放资源
    if(jedis != null)jedis.close();
}

Jedis连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。

public class JedisConnectionFactory{
    private static final JedisPool jedisPool;

    static{
        JedisPoolConfig jedisPoolConfig= new JedisPoolConfig();
        // 最大连接
        iedisPoolConfig.setMaxTotal(8):
        // 最大空闲连接
        jedisPoolConfig.setMaxIdle(8);
        // 最小空闲连接
        jedisPoolConfig.setMinIdle(0):
        // 设置最长等待时间,ms
        jedisPoolConfig.setMaxWaitMillis(200);
        jedisPool = new JedisPool(iedisPoolconfig,"192.168.150.101".6379.1000,“123321”);
    }

    // 获取Jedis对象
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

SpringDataRedis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis官网地址:Spring Data Redis

1.提供了对不同Redis客户端的整合(Lettuce和Jedis)提供了RedisTemplate统一API来操作Redis

2.支持Redis的发布订阅模型

3.支持Redis哨兵和Redis集群

4.支持基于Lettuce的响应式编程

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

6.支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

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

SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单:

1.引入依赖

<!--Redis依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--连接池依赖-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2.配置文件

spring:
    redis:
        host: 192.168.150.101
        port: 6379
        password: 123321
        lettuce:
            pool:
                max-active: 8 # 最大连接
                max-idle: 8 # 最大空闲连接
                min-idle: 0 # 最小空闲连接
                max-wait: 100 # 连接等待时间

3.注入RedisTemplate

@Autowired
private RedisTemplate redisTemplate;

4.编写测试

@SpringBootTest
public class RedisTest{
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void teststring(){
        // 插入一条string类型数据
        redisTemplate.opsForValue().set("name","李四");
        // 读取一条string类型数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = "+ name);
    }
}

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

1.可读性差。

2.内存占用较大。

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

@Configuration
public class RedisConfig{
    @Bean
    public RedisTemplate<String, 0bject> redisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostExceptionf
    {
        //创建Template
        RedisTemplate<String, Object>redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
        // key和 hashKey采用 strinq序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value和 hashValue采用 JSON序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;   
    }
}
- THE END -

WuTong

6月18日11:32

最后修改:2024年6月18日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论