首页 > 数据库 >Redis(1)_Redis的基本认识

Redis(1)_Redis的基本认识

时间:2024-04-23 11:56:01浏览次数:26  
标签:基本 name 认识 Redis key 类型 序列化 String

初识Redis

特征

  • 键值(key-value)型,value支持多种不同数据结构,功能丰富
  • 单线程,每个命令具备原子性
  • 低延迟,速度快(基于内存、IO多路复用、良好的编码)
  • 支持数据持久化
  • 支持主从集群、分片集群
  • 支持多语言客户端

Redis命令

数据结构

  • Redis为了方便学习,将操作不同数据类型的命令做了分组
  • 官网

通用命令

  • KEYS:查看复合模版的所有key,不建议在生产环境设备上使用
  • DEL:删除一个指定的key
  • EXISTS:判断key是否存在
  • EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
  • TTL:查看一个KEY的剩余有效期

通过help[command]可以查看一个命令的具体用法

String类型

String类型,也就是字符串类型,是Redis中最简单的存储类型

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

  • string:普通字符串
  • int:整数类型,可以做自增、自减操作
  • float:浮点类型,可以做自增、自减操作

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类型的键值对,并且指定有效期

Key的层级结构

如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:

KEY VALUE
hanyang:user:1
hanyang:product:1

Hash类型

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

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

KEY VALUE
hanyang:user:1
hanyang:user:2

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

KEY VALUE
field value
hanyang:user:1 name Jack
age 21
hanyang:user:2 name Rose
age 18

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
  • HINCRBY:让一个hash类型key的字段值自增并指定步长
  • HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行

List类型

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

特征也与LinkedList类似:

  • 有序
  • 元素可以重复
  • 插入和删除快
  • 查询速度一般

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

List的常见命令有:

  • LPUSH key element ... :向列表左侧插入一个或多个元素
  • LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
  • RPUSH key element ... :向列表右侧插入一个或多个元素
  • RPOP key:移除并返回列表右侧的第一个元素
  • LRANGE key star end:返回一段角标范围内的所有元素
  • BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

如何利用List结构模拟一个栈?

  • 入口和出口在同一边

如何利用List结构模拟一个队列?

  • 入口和出口在不同边

如何利用List结构模拟一个阻塞队列?

  • 入口和出口在不同边
  • 出队时采用BLPOP或BRPOP

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 ... :求key1与key2的交集
  • SDIFF key1 key2 ... :求key1与key2的差集
  • SUNION key1 key2 ..:求key1和key2的并集

SortedSet类型

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

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 key increment member:让sorted set中的指定元素自增,步长为指定的increment值
  • ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
  • ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
  • ZDIFF.ZINTER.ZUNION:求差集.交集.并集

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

  • 升序获取sorted set 中的指定元素的排名:ZRANK key member
  • 降序获取sorted set 中的指定元素的排名:ZREVRANK key memeber

Redis的Java客户端

Jedis

  1. 引入依赖
<!--jedis-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.0</version>
</dependency>
<!--单元测试-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
</dependency>
  1. 建立连接
private Jedis jedis;

@BeforeEach
void setUp(){
    //1. 建立连接
    jedis = new Jedis("192.168.190.129", 6379);
    //2. 设置密码
    jedis.auth("123321");
    //3. 选择库
    jedis.select(0);
}
  1. 测试
@Test
void testString(){
    //存入数据
    String result = jedis.set("name", "renkelin");
    System.out.println("result = " + result);
    //获取数据
    String name = jedis.get("name");
    System.out.println("name = " + name);
}

@Test
void testHash(){
    //插入hash数据
    jedis.hset("user:1", "name", "Jack");
    jedis.hset("user:1", "age", "18");

    //获取
    Map<String, String> map = jedis.hgetAll("user:1");
    System.out.println(map);
}
  1. 释放资源
@AfterEach
void tearDown(){
    if(jedis != null){
        jedis.close();
    }
}

Jedis连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗

package com.hanyang.jedis.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * ClassName: JedisConnectionFactory
 * Package: com.hanyang.jedis.util
 * Description:
 *
 * @Author: renkelin
 * @Create: 2023/7/3 - 23:16
 * @Version: v1.0
 */
public class JedisConnectionFactory {
    private static final JedisPool jedisPool;

    static {
        //配置连接池
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(8);
        config.setMaxIdle(8);
        config.setMinIdle(0);
        //创建连接池对象
        jedisPool = new JedisPool(config, "192.168.190.129", 6379, 1000, "123321");
    }

    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

SpringDataRedis

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

  • 官网
  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK.JSON.字符串.Spring对象的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作

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

RedisTemplate

  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>
  1. 配置文件
spring:
  redis:
    host: 192.168.190.129
    port: 6379
    password: 123321
    lettuce:
      pool:
        max-active: 8  #最大连接
        max-idle: 8   #最大空闲连接
        min-idle: 0   #最小空闲连接
        max-wait: 100ms #连接等待时间
  1. 注入RedisTemplate
@Autowired
private RedisTemplate redisTemplate;
  1. 编写测试
@Test
void testString() {
    //写入一条String数据
    redisTemplate.opsForValue().set("name", "汉阳");
    //获取String数据
    Object name = redisTemplate.opsForValue().get("name");
    System.out.println("name = " + name);
}

数据序列化器

自定义RedisTemplate的序列化方式

package com.hanyang.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import sun.net.www.content.text.Generic;

/**
 * ClassName: RedisConfig
 * Package: com.hanyang.redis.config
 * Description:
 *
 * @Author: renkelin
 * @Create: 2023/7/3 - 23:53
 * @Version: v1.0
 */
@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;
    }
}

StringRedisTemplate

为了节省内存空间,并不会使用JSON序列化来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化

Spring默认提供了一个StringRedisTemplate类,省去了自定义RedisTemplate的过程

package com.hanyang;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

@SpringBootTest
class RedisStringTests {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    void testString() {
        //写入一条String数据
        stringRedisTemplate.opsForValue().set("name", "汉阳");
        //获取String数据
        Object name = stringRedisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
}

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

  • 方案一:
    • 自定义RedisTemplate
    • 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer
  • 方案二:
    • 使用StringRedisTemplate
    • 写入Redis时,手动把对象序列化为JSON
    • 读取Redis时,手动把读取到的JSON反序列化为对象

Hash结构操作

@SpringBootTest
class RedisStringTests {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    void testHash() {
        stringRedisTemplate.opsForHash().put("user:400", "name", "汉阳");
        stringRedisTemplate.opsForHash().put("user:400", "age", "21");

        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:400");
        System.out.println("entries = " + entries);
    }
}

标签:基本,name,认识,Redis,key,类型,序列化,String
From: https://www.cnblogs.com/TPwang/p/18152558

相关文章

  • 【Redis】Redis的操作命令(二)——Redis 字符串(String)
    常见的Redis字符串命令如下:命令说明例子SETkeyvalue设置指定key的值 GETkey获取指定key的值 GETRANGEkeystartend返回key中字符串值的子字符 GETRANGEmykey03 GETSETkeyvalue将给定key的值设为value,并返回key的旧值(oldvalu......
  • 认识一下JavaScrip中的元编程
    本文分享自华为云社区《元编程,使代码更具描述性、表达性和灵活性》,作者:叶一一。背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一......
  • markdown基本使用
    状态图声明状态```mermaidstateDiagram状态1```stateDiagram状态1状态描述```mermaidstateDiagramstate"状态描述性文字"as状态2``````mermaidstateDiagram状态3:状态3的文字描述```......
  • Flask基本用法
    Flask基本结构#引入Flask包,使得我们可以创建Flask应用实例fromflaskimportFlask#创建一个Flask应用实例。`__name__`是Python内置变量,它表示当前模块的名称。#在这里,`__name__`被传递给Flask构造函数,用于确定应用程序的基本目录(如静态文件和模板的查找路径),尤其是在......
  • 30 天精通 RxJS (28):Scheduler 基本观念
    不晓得读者们还记不记得,我们在前面的文章中有提到Scheduler是为了解决RxJS衍生的最后一个问题,而我们现在就在揭晓这个谜底。其实RxJS用久了之后就会发现Observable有一个优势是可以同时处理同步和非同步行为,但这个优势也带来了一个问题,就是我们常常会搞不清处现在的......
  • Redis在分布式架构中有哪些作用
    Redis在分布式架构中起到了多个关键作用,主要包括以下几点:数据缓存:Redis可以作为分布式系统的缓存层,存储热点数据或计算结果,从而减少对数据库的访问压力,提高系统的响应速度和吞吐量。通过将数据缓存在Redis中,系统可以更快地获取数据,减少网络延迟和数据库查询时间。会话管理:在分......
  • Linux系列教程——Linux基本权限、Linux特殊权限、LinuxACL控制、Linux输入输出
    @目录1Linux基本权限1.权限基本概述1.什么是权限?2.为什么要有权限?3.权限与用户之间的关系?4.权限中的rwx分别代表什么含义?2.权限设置示例1.为什么要设定权限,我们又如何修改一个文件的权限?2.使用chmod设定权限示例3.权限设置案例3.权限设置案例4.属主属组设置2Linux特殊权限1.特......
  • Redis系列之——持久化
    一持久化的作用1.1什么是持久化redis的所有数据保存在内存中,对数据的更新将异步的保存到硬盘上1.2持久化的实现方式快照:某时某刻数据的一个完成备份, -mysql的Dump-redis的RDB写日志:任何操作记录日志,要恢复数据,只要把日志重新走一遍即可 -mysql的Binlog-Hh......
  • docker安装redis
    下载最新的官方镜像dockerpullredis:latest在/app/redis下新建redis.conf:#开启密码验证(可选)requirepass123#允许redis外地连接,需要注释掉绑定的IP#bind127.0.0.1#关闭保护模式(可选)protected-modeno#注释掉daemonizeyes,或者配置成daemonizeno。因为该配......
  • Linux基础-01:Linux命令的基本格式
    2.1.1命令提示符在CentOS7操作系统中,Linux命令提示符就像是你与电脑交流的一个小标志,告诉你系统已经准备好接受你的指令了。它通常会显示在你打开的终端窗口或控制台的最前面。让我们来看一个示例:[root@node01~]$在这个示例中:root:是当前登录的用户名。@:分隔符号,没有特......