279665

初识Redis

Redis是一个键值型NoSQL数据库

  • 键值型:键值型指Redis中存储的数据都是以Key-Value键值对的形式存储,可以是字符串、数值甚至Json
  • NoSQL则是相对于传统关系型数据库而言,有很大差异的一种数据库

NoSQL数据库

NoSql可以翻译做Not Only Sql(不仅仅是SQL),或者是No Sql(非Sql的)数据库。是相对于传统关系型数据库而言,有很大差异的一种特殊的数据库,因此也称之为非关系型数据库

结构化与非结构化

传统关系型数据库是结构化数据,创建表时有严格的约束信息,如字段名,字段类型,这些约束必须遵循。
而NoSQL数据库则是非结构化数据,没有严格的约束信息,可以是键值型,文档型,甚至是图格式

关联与非关联

传统数据库的表与表之间存在关联关系,例如外键约束,而NoSQL数据库则不存在关联关系,数据之间没有约束,维护关系要么考业务逻辑,要么靠数据之间耦合

查询方式

传统的数据库必须基于SQL语句来做查询,语法较为统一

1
SELECT * FROM user WHERE id = 1

而NoSQL数据库则没有SQL语句,查询方式根据不同的数据库而不同。
1
2
3
Redis:  get user:1
MongoDB: db.user.find({_id: 1})
elasticsearch: GET http://localhost:9200/users/1

事务

传统关系型数据库能满足事务的ACID原则(原子性、一致性、独立性及持久性)
而非关系型数据库汪汪不支持事务,或者不能要个保证ACID的特性,只能实现基本的一致性

总结

SQLNoSQL
数据结构结构化(Structured)非结构化
数据关联关联的(Relational)无关联的
查询方式SQL查询非SQL
事务特性ACIDBASE
存储方式磁盘内存
扩展性垂直水平

*存储方式

  • 关系型数据库基于磁盘进行存储,会有大量的磁盘IO,对性能有一定影响
  • 非关系型数据库,操作更多的是依赖于内存来操作,内存的读写速度非常快,性能自然会好一些
    • 扩展性
  • 关系型数据库集群模式一般是主从,主从数据一致,起到数据备份的作用,称为垂直扩展
  • 非关系型数据库可以将数据拆分,存储在不同机器上,可以保存海量数据,解决内存大小有限的问题。称为水平扩展
  • 关系型数据库因为表之间存在关联关系,如果做水平扩展会给数据查询带来很多麻烦

认识Redis

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

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

Redis官网:https://redis.io/

下载Redis

检查gcc环境

Redis是基于C语言编写的,因此首先需要安装Redis需要gcc依赖:

  • 检查是否安装了gcc
    1
    gcc --version
  • 如果未安装则需要安装gcc
    1
    yum install -y gcc tcl

下载Redis

  1. 进入要安装的文件夹
1
cd /usr/local/src
  1. 下载并解压redis
    1
    2
    wget https://download.redis.io/releases/redis-7.2.0.tar.gz
    tar -zxvf redis-7.2.0.tar.gz
  2. 进入redis安装目录
    1
    cd redis-7.2.0
  3. 编译并安装
    1
    make && make install
  4. 查看是否安装成功
    1
    2
    cd /usr/local/bin
    ll
  5. 可以在任意目录下运行redis
    该目录已经默认配置到环境变量,因此可以在任意目录下运行这些命令。其中:
  • redis-cli:是redis提供的命令行客户端
  • redis-server:是redis的服务端启动脚本
  • redis-sentinel:是redis的哨兵启动脚本

启动Redis

redis的启动方式有很多种,例如:

  • 默认启动
  • 指定配置启动
  • 开机自启

默认启动

安装完成后,在任意目录输入redis-server命令即可启动Redis:

1
redis-server

这种启动方式属于前台启动,会阻塞整个会话窗口,窗口关闭则redis也会关闭。

指定配置启动

如果要让Redis以后台方式启动,则必须修改Redis配置文件,就在之前解压的redis安装包下(/usr/local/src/redis-7.2.0),名字叫redis.conf:
先将这个配置文件备份一份:

1
cp redis.conf redis.conf.bck

然后修改redis.conf文件中的一些配置:
1
2
3
4
5
6
# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
# 密码,设置后访问Redis必须输入密码
requirepass 123321

Redis的其它常见配置:

1
2
3
4
5
6
7
8
9
10
# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
1
2
3
4
# 进入redis安装目录 
cd /usr/local/src/redis-7.2.0
# 启动(后面指定配置文件)
redis-server redis.conf
1
ps -ef | grep redis
1
2
3
# 利用redis-cli来执行 shutdown 命令,即可停止 Redis 服务,
# 因为之前配置了密码,因此需要通过 -u 来指定密码
redis-cli -u 123321 shutdown

开机自启

我们也可以通过配置来实现开机自启。
PS:需要先将前面的Redis进程杀死,否则会启动失败。

1
2
3
4
#查看当前进程
ps -ef | grep redis
#杀死某进程
kill -9 进程号

首先,新建一个系统服务文件
1
vi /etc/systemd/system/redis.service
1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
#第一个参数为redis服务所在位置 第二个参数为redis配置文件所在位置
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target

接着重载系统:
1
systemctl daemon-reload

就能使用以下这组命令来操作redis了
1
2
3
4
5
6
7
8
# 启动redis
systemctl start redis
# 停止redis
systemctl stop redis
# 重启redis
systemctl restart redis
# 查看redis状态
systemctl status redis

执行以下命令,实现开机自启
1
systemctl enable redis

Redis桌面客户端

安装完Redis后,我们可以使用Redis客户端来实现对数据的CRUD。
Redis客户端包括:

  • 命令行客户端
  • 图形化桌面客户端
  • 编程客户端

命令行客户端

Redis安装完成后就自带了Redis命令行客户端,可以使用redis-cli命令来连接Redis服务器。
使用方式:redis-cli [options] [commonds]

1
redis-cli -h 127.0.0.1 -p 6379

常见的options有:

  • -h 127.0.0.1:指定要连接的redis节点的IP地址,默认是127.0.0.1
  • -p 6379:指定要连接的redis节点的端口,默认是6379
  • -a 123321:指定redis的访问密码

其中的commonds就是Redis的操作命令,例如:

  • ping:与redis服务端做心跳测试,服务端正常会返回pong
    不指定commond时,会进入redis-cli的交互控制台:

图形化桌面客户端

Redis官方没有提供Windows版本的图形化桌面客户端,但Github上有大神编写了Redis的Windows版本的图形化客户端
不过该仓库提供的为源码,需要自己编译。
在下面这个仓库可以找到安装包:https://github.com/lework/RedisDesktopManager-Windows/releases

建立连接
通过点击左上角连接到Redis服务器按钮,弹出连接对话框:


填写完基本信息后,点击测试连接按钮,测试连接是否成功。
如果连接失败,关闭Linux防火墙后尝试再次连接。
1
systemctl stop firewalld

Redis的Java客户端

在Redis官网中提供了各种语言的客户端,地址:https://redis.io/docs/clients/


推荐使用的Java客户端包括:

  • Jedis和Letter:这两个主要提供了Redis命令对应的API,方便我们直接操作Redis,SpringDataRedis又对这两种做了抽象和封装,故后期我们使用SpringDataRedis来操作Redis。
  • Redission:在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map,Queue等,而且支持跨进程的同步机制:Lock、Semaphore等来,比较适合用来实现特殊的功能需求

Jedis快速入门

  1. 创建项目后,引入Jedis依赖
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!--jedis-->
    <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.0</version>
    </dependency>
    <!--单元测试-->
    <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
    </dependency>
  2. 建立连接
    新建单元测试类,在测试类运行前连接jedis
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private Jedis jedis;

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Test
    void testString() {
    // 存入数据
    String result = jedis.set("name", "虎哥");
    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", "21");

    // 获取
    Map<String, String> map = jedis.hgetAll("user:1");
    System.out.println(map);
    }
  4. 关闭连接

    1
    2
    3
    4
    5
    6
    @AfterEach
    void tearDown() {
    if (jedis != null) {
    jedis.close();
    }
    }

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class JedisConnectionFactory {
private static JedisPool jedisPool;
static {
// 配置连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(8);
poolConfig.setMaxIdle(8);
poolConfig.setMinIdle(0);
poolConfig.setMaxWaitMillis(1000);
// 创建连接池对象,参数:连接池配置、服务端ip、服务端端口、超时时间、密码
jedisPool = new JedisPool(poolConfig, "192.168.150.101", 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封装到了不同的类型中:

SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单。
首先,新建一个maven项目,然后按照下面步骤执行:

  1. 引入依赖
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.7</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.heima</groupId>
    <artifactId>redis-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redis-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
    <java.version>1.8</java.version>
    </properties>
    <dependencies>
    <!--redis依赖-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--common-pool-->
    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    </dependency>
    <!--Jackson依赖-->
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    </dependency>
    <!--Lombok依赖-->
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    </dependency>
    <!--Springboot起步依赖-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <excludes>
    <exclude>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    </exclude>
    </excludes>
    </configuration>
    </plugin>
    </plugins>
    </build>

    </project>
  2. 配置Redis连接信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    spring:
    redis:
    host: 192.168.150.101
    port: 6379
    password: 123321
    lettuce:
    pool:
    max-active: 8
    max-idle: 8
    min-idle: 0
    max-wait: 100ms
  3. 注入RedisTemplate
    因为使用的是SpringBoot,所以直接自动装配注入就好了
    1
    2
    3
    4
    5
    @SpringBootTest
    class RedisDemoApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    }
  4. 测试
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @SpringBootTest
    class RedisStringTests {

    @Autowired
    private RedisTemplate edisTemplate;

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

Redis入门

Redis是典型的key-value数据库,其中key是字符串类型,value可以是多种不同的数据类型

Redis通用命令

通用命令有以下几个

命令描述
KEYs pattern查找所有符合给定模式(pattern)的key
EXISTs key检查给定key是否存在
TYPE key返回key所储存的值的类型
TTL key返回给定key的剩余生存时间(TTL, time to live),以秒为单位
DEL key该命令用于key存在时删除key
  • KEYS:查看符合模板的所有key

    • 不建议在生产环境设备上使用,因为Redis是单线程的,执行查询的*时候会阻塞其他命令,当数据量很大的时候,使用KEYS进行模糊查询,效率很差
  • DEL:删除一个指定的key

    • 也可以删除多个key,DEL name age,会将name和age都删掉
  • EXISTS:判断key是否存在
    • EXISTS name,如果存在返回1,不存在返回0
  • EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
    • EXPIRE name 20,给name设置20秒有效期,到期自动删除
  • TTL:查看一个key的剩余有效期(Time-To-Live)
    • TTL name,查看name的剩余有效期,如果未设置有效期,则返回-1

String类型

String类型,也就是字符串类型,是Redis中最简单的存储类型,value是字符串类型,根据字符串格式不同,又可以分为三种

  • string: 普通字符串
  • int: 整数
  • float: 浮点数

不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同,字符串类型的最大空间不能超过512M

String的常用命令

  • 格式:SET key value [EX seconds | PX milliseconds] [NX|XX]
  • 功能:SET 除了可以直接将 key 的值设为 value 外,还可以指定一些参数。
    • EX seconds:为当前 key 设置过期时间,单位秒。等价于 SETEX 命令。
    • PX milliseconds:为当前 key 设置过期时间,单位毫秒。等价于 PSETEX 命令。
    • NX:指定的 key 不存在才会设置成功,用于添加指定的 key。等价于 SETNX 命令。
    • XX:指定的 key 必须存在才会设置成功,用于更新指定 key 的 value。
  • 说明:如果 value 字符串中带有空格,则该字符串需要使用双引号或单引号引起来,否 则会认为 set 命令的参数数量不正确,报错。
  • 格式:MSET/MSETNX key value [key value …]
  • 功能:同时设置一个或多个 key-value 对。
  • 说明:如果某个给定 key 已经存在,那么MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用MSETNX命令:它只会在所有给定 key 都不存在的情况下进行设置操作。MSET/MSETNX 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况不可能发生。该命令永不失败
  • 格式:MGET key [key …]
  • 功能:返回所有(一个或多个)给定 key 的值。
  • 说明:如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。 因此,该命令永不失败。
  • 格式:INCRBY key increment 或 DECRBY key decrement
  • 功能:将 key 中存储的数字值增加/减少指定的数值,这个数值只能是整数,可以是负数,但不能是小数。
  • 说明:如果 key 不存在,那么 key 的值会先被初始化为 0,然后再执行增/减操作。如果值不能表示为数字,那么返回一个错误提示。如果执行正确,则返回增/减后的值。
  • 格式:INCRBYFLOAT key increment
  • 功能:为 key 中所储存的值加上浮点数增量 increment 。
  • 说明:与之前的说明相同。没有 decrbyfloat 命令,但 increment 为负数可以实现减操作效果。
  • 格式:STRLEN key
  • 功能:返回 key 所储存的字符串值的长度。
  • 说明:当 key 储存的不是字符串值时,返回一个错误。

String类型典型场景

Value 为 String 类型的应用场景很多,这里仅举这种典型应用场景的例子:
(1) 数据缓存
Redis 作为数据缓存层,MySQL 作为数据存储层。应用服务器首先从 Redis 中获取数据,如果缓存层中没有,则从 MySQL 中获取后先存入缓存层再返回给应用服务器。
(2) 计数器
在 Redis 中写入一个 value 为数值型的 key 作为平台计数器视频播放计数器等。每个有效客户端访问一次,或视频每播放一次,都是直接修改 Redis 中的计数器,然后再以异步方式持久化到其它数据源中,例如持久化到 MySQL。
(3) 共享 Session
对于一个分布式应用系统,如果将类似用户登录信息这样的Session 数据保存在提供登录服务的服务器中,那么如果用户再次提交像收藏、支付等请求时可能会出现问题:在提供收藏、支付等服务的服务器中并没有该用户的 Session 数据,从而导致该用户需要重新登录。
此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从 Redis 中查找相应的 Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。这样就不会引发“重新登录”问题。
(4) 限速器
现在很多平台为了防止 DoS(Denial of Service,拒绝服务)攻击,一般都会限制一个 IP 的访问次数,如不能在一秒内访问超过 n 次。而 Redis 可以结合 key 的过期时间与 incr 命令来完成限速
功能,充当限速器。

1
2
3
4
5
6
7
8
9
// 客户端每提交一次请求,都会执行下面的代码
// 等价于 set 192.168.192.55 1 ex 60 nx
// 指定新 ip 作为 key 的缓存过期时间为 60 秒
Boolean isExists = redis.set(ip, 1, “EX 60”, “NX”);
if(isExists != null || redis.incr(ip) <= 5) {
// 通过
} else {
// 限流
}

Hash型Value操作

Redis 存储数据的 Value 可以是一个Hash类型。Hash 类型也称为 Hash 表字典等。
Hash 表就是一个映射表 Map,也是由键-值对构成,为了与整体的 key 进行区分,这里的键称为 field,值称为 value。注意,Redis 的 Hash 表中的 field-value 对均为 String 类型。

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

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不存在,否则不执行
  • 格式:HSET key field value
    • 功能:将哈希表 key 中的域 field 的值设为 value 。
    • 说明:如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。如果域 field 已经存在于哈希表中,旧值将被覆盖。如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1 。如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0 。
  • 格式:HGET key field
  • 功能:返回哈希表 key 中给定域 field 的值。
  • 说明:当给定域不存在或是给定 key 不存在时,返回 nil 。
  • 格式:HMSET key field value [field value …]
  • 功能:同时将多个 field-value (域-值)对设置到哈希表 key 中。
  • 说明:此命令会覆盖哈希表 key 中已存在的域。如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。
  • 格式:HMGET key field [field …]
  • 功能:按照给出顺序返回哈希表 key 中,一个或多个给定域的值。
  • 说明:如果给定的域不存在或是给定 key 不存在,那么返回一个 nil 值。
  • 格式:HGETALL key
  • 功能:返回哈希表 key 中,所有的域和值。
  • 说明:在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
  • 格式:HSETNX key field value
  • 功能:将哈希表 key 中的域 field 的值设为 value ,当且仅当域 field 不存在。
  • 说明:若域 field 已经存在,该操作无效。如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。
  • 格式:HDEL key field [field …]
  • 功能:删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
  • 说明:返回被成功删除的域的数量,不包括被忽略的域。
  • 格式:HEXISTS key field
  • 功能:查看哈希表 key 中,给定域 field 是否存在。
  • 说明:返回 1 表示存在,返回 0 表示不存在。
  • 格式:HINCRBY key field increment
  • 功能:为哈希表 key 中的域 field 的值加上增量 increment,hincrby 命令只能增加整数值,而 hincrbyfloat 可以增加小数值。 。
  • 说明:增量也可以为负数,相当于对给定域进行减法操作。如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。

应用场景

Hash 型 Value 非常适合存储对象数据。key 为对象名称,value 为描述对象属性的 Map,
对对象属性的修改在 Redis 中就可直接完成。其不像 String 型 Value 存储对象,那个对象是序列化过的,例如序列化为JSON 串,对对象属性值的修改需要先反序列化为对象后再修改,
修改后再序列化为 JSON 串后写入到 Redis。

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