Redis使用教程

一.安装Redis

windows版本

  • windows版本直接解压即可使用

Linux版本

  1. gcc安装

    #安装gcc
    yum install gcc-c++
    #升级gcc
    #第一步
    yum install centos-release-scl
    #第二步
    yum install devtoolset-7-gcc*
    #第三步
    scl enable devtoolset-7 bash
    
    
  2. 下载Redis

    wget https://github.com/redis/redis/archive/7.2.3.tar.gz
    
  3. 切换到想要安装的目录

    #创建安装目录
    mkdir /usr/local/redis
    #将安装包移动到指定位置
    mv 7.2.3.tar.gz /usr/local/redis/
    
  4. 解压

    tar -zxvf 7.2.3.tar.gz
    
  5. 编译安装

    #进入解压目录
    cd redis-7.2.3/
    #编译安装
    make && make install
    
  6. 修改配置文件允许外网连接

    • 允许外界访问

    • 不限制外网连接的IP

二.启动Redis

windows版本

  1. 切换到redis解压后的目录

  2. 进入cmd

  3. 指定配置文件启动

    redis-server.exe redis.windows.conf
    

linux版本

  • 修改配置文件,开启后台运行

  • 指定配置文件启动,后台启动

    redis-server /usr/local/redis/redis-6.2.14/redis.conf
    

三.使用Redis

windows版本

  • 默认端口是6379

    redis-cli.exe -h 127.0.0.1 -p 6379
    

Linux版本

  • 使用redis客户端指定ip和端口进行连接

    redis-cli -h 127.0.0.1 -p 6379
    

  • 停止redis

    redis-cli -h 127.0.0.1 -p 6379 shutdown
    

  • 修改redis监听的端口

选择数据库

  • 默认redis有16个数据库,默认使用的是0号数据库
  • 可以通过修改配置文件更改数据库的数量
  • 使用select可以选择使用的数据库
#使用0号数据库
select 0
#使用15号数据库
seelct 15

四.Redis中的数据类型

  • 在Redis中是按照键值对的形式进行存储

  • 键的数据类型只能是字符串

  • 值的类型可以是字符串、列表、集合、哈希表

  • 查看数据类型的方式

    #语法
    type 键
    #例如
    type name
    

字符串类型的使用

  • 一次添加一对键值对

    #语法格式
    set 键 值
    #例如
    set name yangyi
    
  • 一次获取一个值

    #语法
    get 键
    #例如
    get name
    

  • 一次添加多对键值对

    #语法
    mset 键1 值1 键2 值2 ...
    #例如
    mset age 20 salary 10000
    
  • 一次获取多个值

    #语法
    mget 键1 键2
    #例如
    mget name age salary
    

  • 删除一对键值对

    #语法
    del 键1 键2
    #支持一次删除多个
    #例如
    del name
    del age salary
    

  • 设置数据的过期时间

    • 添加数据时指定过期时间

      #语法
      set 键 EX 秒
      set 键 PX 毫秒
      #例如
      #设置数据10秒后过期
      set data1 EX 10
      #设置数据10000毫秒后过期
      set data2 PX 10000
      

    • 给已经添加的数据指定过期时间

    #语法
    expire 键 秒
    #例如
    #设置数据10秒后过期
    expire name 10
    

  • 查看数据的过期时间

    • 返回-2表示已经过期
    • 返回-1表示不会过期
    • 返回其他正整数表示距离过期的时间
    #语法
    #单位为秒
    ttl 键
    #单位为毫秒
    pttl 键
    #例如
    ttl name
    
  • 将设置过期时间的数据,设置为永不过期

    #语法
    persist 键
    #例如
    persist name
    

  • 使用特定格式字符串存放对象的信息

    #语法
    set user:name
    

  • 获取所有的键

    keys *
    

  • 随机获取一个键

    randomkey
    
  • 查询一个键是否已经存在数据库

    #语法
    exists 键
    #例如
    exists name
    
  • 将数据库中的一个键值对移动到另一个数据库

    #语法
    move 键 数据库序号
    #例如
    #将当前数据库的name键值对移动到1号数据库
    move name 1
    
  • 修改一个键为另一个键

    #语法
    #使用这种会直接进行操作,如果目标键已经存在了,就会覆盖
    rename 源键 目标键
    #使用这种方式操作前会进行检查,如果目标键已经存在,就不会进行操作
    renamex 源键 目标键
    #例如
    rename age number
    renamex age salary
    
  • 对数字字符串进行自增自减

    #语法
    #等价于 a = a + 1
    incr 键
    #等价于b = b + 数字字符串n
    incrby 键 数字字符串n
    #等价于 c = c - 1
    decr 键
    

列表类型的使用

  • redis中的列表是一个双端队列

  • 添加数据

    • 在左边添加数据
    #语法
    lpush 键 值序列...
    #例如
    lpush list 100 200 300
    
    • 在右边添加数据
    #语法
    rpush 键 值序列...
    #例如
    rpush list 1 2 3 4
    
  • 取出数据

    • 从左边开始取出数据
    #语法
    lpop 键
    #例如
    lpop list
    
    • 从右边开始取出数据
    #语法
    rpop 键
    #例如
    rpop list
    
    • 按照下标取出数据
    #语法
    lindex 键 下标
    #例如
    lindex list 0
    
    • 按照下标序列取出数据
    #语法
    lrange 键 开始下标 结束下标
    #例如
    #从第一个取到最后一个
    lrange list 0 -1
    
  • 删除数据

    • 从左边开始删除数据
    #语法
    lpop 键 值的个数
    #例如,默认删除一个
    lpop list 2
    
    • 从右边开始删除数据
    #语法
    rpop 键 值的个数
    #例如
    rpop list
    
    • 删除最后一个值加入到另一个键值对中
    #语法
    rpoplpush 源键 目标键
    #例如
    rpoplpush list1 list2
    
  • 获取列表的长度

    #语法
    llen 键
    #例如
    llen list
    
  • 阻塞操作

    #语法,阻塞时间单位为秒
    blpop 键 阻塞时间
    #例如
    #取出list列表中的最后一个值,如果没有就最多等待10秒,在10秒内list列表中可以取最后一个值,就执行操作,否则取消操作
    blpop list 10
    

集合类型的使用

  • redis中有两种集合类型,一种是无须的集合set,一种是有序集合zset
set无序集合
  • 添加数据

    #语法
    sadd 键 值1 值2...
    #例如
    sadd set 1 2 3 4
    
  • 查看一个集合中有多少数据

    #语法
    scard 键
    #例如
    sacrd set1
    
  • 查看集合是否含有指定值

    #语法
    sismember 键 值
    #例如
    sismember set1 1
    
  • 获取集合中的所有数据

    #语法
    smembers 键
    #例如
    smembers set1
    
  • 随机删除集合的一个数据

    #语法
    spop 键
    #例如
    spop set1
    
  • 删除集合中指定的数据

    #语法
    srem 键 值
    #例如
    srem set1 1 
    
  • 求集合间的差集

    #语法
    sdiff 键1 键2
    #例如
    sdiff set1 set2
    
  • 求集合间的交集

    #语法
    sinter 键1 键2
    #例如
    sinter set1 set2
    
  • 求集合间的并集

    #语法
    sunion 键1 键2
    #例如
    sunion set1 set2
    
  • 将差集保存到指定集合

    #语法
    sdiffstore 目标键 源键1 源键2
    #例如
    sdiffstore set3 set1 set2
    
  • 将交集保存到指定集合

    #语法
    sinterstore 目标键 源键1 源键2
    #例如
    sinterstore set3 set1 set2
    
  • 将并集保存到指定集合中

    #语法
    sunionstore 目标键 源键1 源键2
    #例如
    sunionstore set3 set1 set2
    
  • 移动集合中的值到另一个集合

    #语法
    smove 源键 目标键 值
    #例如
    #将set1中的值1移动的set2中
    smove set1 set2 1
    
zset有序集合
  • 在添加值的时候指定一个分数,在集合值就会按照分数进行排序,也可以按照分数区间获取值

  • 有序集合里只能放数字字符串,不能放其他的

  • 添加数据

    #语法
    zadd 键 值 分数
    #例如
    zadd zset1 1 10 2 5
    
  • 查看有多少数据

    #语法
    zcard 键
    #例如
    zcard zset1 
    
  • 获取数据的分数

    #语法
    zrange 键 开始下标 结束下标
    #例如
    zrange zset1 0 -1
    
  • 删除数据

    #语法
    zrem 键 值
    #例如
    zrem zset1 yangyi
    
  • 通过分数段查看数据

    #语法
    zrangebyscore 键 开始分数 结束分数 
    #例如
    zrangebyscore zset1 5 10 
    
  • 统计分数段内的数据量

    #语法
    zcount 键 开始分数 结束分数
    #例如
    zcount zset1 5 10
    
  • 根据数据的排名,根据分数排序的排名

    #语法
    zrank 键 值
    #例如
    zrank zset1 yangyi
    

哈希表类型的使用

  • redis中的哈希表相当于HashMap<String,HashMap<String,String>>,一个哈希表中套了一个哈希表,不过这两个嵌套的哈希表的键和值都是字符串

  • 添加数据

    #语法
    hset 键 属性 值
    #例如
    hset user name yangyi age 20 salary 10000
    

  • 删除属性数据

    #语法
    hdel 键 属性
    #例如
    hdel user name
    
  • 取出数据

    • 取出单个属性值

      #语法
      hget 键 属性
      #例如
      hget user name
      
    • 取出所有属性和值

    #语法
    hgetall 键
    #例如
    hgetall user
    
    • 取出所有值
    #语法
    hvals 键
    #例如
    hvals user
    
  • 判断属性数据是否存在

    #语法
    hexists 键 属性
    #例如
    hexists user name
    
  • 获取一个哈希键值对的长度

    #语法
    hlen 键
    #例如
    hlen user
    

常用命令汇总

Redis 键(key) 命令
命令描述
Redis Type 命令返回 key 所储存的值的类型。
Redis PEXPIREAT 命令设置 key 的过期时间亿以毫秒计。
Redis PEXPIREAT 命令设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
Redis Rename 命令修改 key 的名称
Redis PERSIST 命令移除 key 的过期时间,key 将持久保持。
Redis Move 命令将当前数据库的 key 移动到给定的数据库 db 当中。
Redis RANDOMKEY 命令从当前数据库中随机返回一个 key 。
Redis Dump 命令序列化给定 key ,并返回被序列化的值。
Redis TTL 命令以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
Redis Expire 命令seconds 为给定 key 设置过期时间。
Redis DEL 命令该命令用于在 key 存在是删除 key。
Redis Pttl 命令以毫秒为单位返回 key 的剩余的过期时间。
Redis Renamenx 命令仅当 newkey 不存在时,将 key 改名为 newkey 。
Redis EXISTS 命令检查给定 key 是否存在。
Redis Expireat 命令EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
Redis Keys 命令查找所有符合给定模式( pattern)的 key 。
Redis 列表(List) 命令
命令描述
Redis Lindex 命令通过索引获取列表中的元素
Redis Rpush 命令在列表中添加一个或多个值
Redis Lrange 命令获取列表指定范围内的元素
Redis Rpoplpush 命令移除列表的最后一个元素,并将该元素添加到另一个列表并返回
Redis Blpop 命令移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
Redis Brpop 命令移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
Redis Brpoplpush 命令从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
Redis Lrem 命令移除列表元素
Redis Llen 命令获取列表长度
Redis Ltrim 命令对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
Redis Lpop 命令移出并获取列表的第一个元素
Redis Lpushx 命令将一个或多个值插入到已存在的列表头部
Redis Linsert 命令在列表的元素前或者后插入元素
Redis Rpop 命令移除并获取列表最后一个元素
Redis Lset 命令通过索引设置列表元素的值
Redis Lpush 命令将一个或多个值插入到列表头部
Redis Rpushx 命令为已存在的列表添加值
Redis 集合(Set) 命令
命令描述
Redis Sunion 命令返回所有给定集合的并集
Redis Scard 命令获取集合的成员数
Redis Srandmember 命令返回集合中一个或多个随机数
Redis Smembers 命令返回集合中的所有成员
Redis Sinter 命令返回给定所有集合的交集
Redis Srem 命令移除集合中一个或多个成员
Redis Smove 命令将 member 元素从 source 集合移动到 destination 集合
Redis Sadd 命令向集合添加一个或多个成员
Redis Sismember 命令判断 member 元素是否是集合 key 的成员
Redis Sdiffstore 命令返回给定所有集合的差集并存储在 destination 中
Redis Sdiff 命令返回给定所有集合的差集
Redis Sscan 命令迭代集合中的元素
Redis Sinterstore 命令返回给定所有集合的交集并存储在 destination 中
Redis Sunionstore 命令所有给定集合的并集存储在 destination 集合中
Redis Spop 命令移除并返回集合中的一个随机元素
Redis 有序集合(sorted set) 命令
命令描述
Redis Zrevrank 命令返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
Redis Zlexcount 命令在有序集合中计算指定字典区间内成员数量
Redis Zunionstore 命令计算给定的一个或多个有序集的并集,并存储在新的 key 中
Redis Zremrangebyrank 命令移除有序集合中给定的排名区间的所有成员
Redis Zcard 命令获取有序集合的成员数
Redis Zrem 命令移除有序集合中的一个或多个成员
Redis Zinterstore 命令计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
Redis Zrank 命令返回有序集合中指定成员的索引
Redis Zincrby 命令有序集合中对指定成员的分数加上增量 increment
Redis Zrangebyscore 命令通过分数返回有序集合指定区间内的成员
Redis Zrangebylex 命令通过字典区间返回有序集合的成员
Redis Zscore 命令返回有序集中,成员的分数值
Redis Zremrangebyscore 命令移除有序集合中给定的分数区间的所有成员
Redis Zscan 命令迭代有序集合中的元素(包括元素成员和元素分值)
Redis Zrevrangebyscore 命令返回有序集中指定分数区间内的成员,分数从高到低排序
Redis Zremrangebylex 命令移除有序集合中给定的字典区间的所有成员
Redis Zrevrange 命令返回有序集中指定区间内的成员,通过索引,分数从高到底
Redis Zrange 命令通过索引区间返回有序集合成指定区间内的成员
Redis Zcount 命令计算在有序集合中指定区间分数的成员数
Redis Zadd 命令向有序集合添加一个或多个成员,或者更新已存在成员的分数
Redis 连接 命令
命令描述
Redis Echo 命令打印字符串
Redis Select 命令切换到指定的数据库
Redis Ping 命令查看服务是否运行
Redis Quit 命令关闭当前连接
Redis Auth 命令验证密码是否正确
Redis 服务器 命令
命令描述
Redis Client Pause 命令在指定时间内终止运行来自客户端的命令
Redis Debug Object 命令获取 key 的调试信息
Redis Flushdb 命令删除当前数据库的所有key
Redis Save 命令异步保存数据到硬盘
Redis Showlog 命令管理 redis 的慢日志
Redis Lastsave 命令返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示
Redis Config Get 命令获取指定配置参数的值
Redis Command 命令获取 Redis 命令详情数组
Redis Slaveof 命令将当前服务器转变为指定服务器的从属服务器(slave server)
Redis Debug Segfault 命令让 Redis 服务崩溃
Redis Flushall 命令删除所有数据库的所有key
Redis Dbsize 命令返回当前数据库的 key 的数量
Redis Bgrewriteaof 命令异步执行一个 AOF(AppendOnly File) 文件重写操作
Redis Cluster Slots 命令获取集群节点的映射数组
Redis Config Set 命令修改 redis 配置参数,无需重启
Redis Command Info 命令获取指定 Redis 命令描述的数组
Redis Shutdown 命令异步保存数据到硬盘,并关闭服务器
Redis Sync 命令用于复制功能(replication)的内部命令
Redis Client Kill 命令关闭客户端连接
Redis Role 命令返回主从实例所属的角色
Redis Monitor 命令实时打印出 Redis 服务器接收到的命令,调试用
Redis Command Getkeys 命令获取给定命令的所有键
Redis Client Getname 命令获取连接的名称
Redis Config Resetstat 命令重置 INFO 命令中的某些统计数据
Redis Command Count 命令获取 Redis 命令总数
Redis Time 命令返回当前服务器时间
Redis Info 命令获取 Redis 服务器的各种信息和统计数值
Redis Config rewrite 命令对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写
Redis Client List 命令获取连接到服务器的客户端连接列表
Redis Client Setname 命令设置当前连接的名称
Redis Bgsave 命令在后台异步保存当前数据库的数据到磁盘
Redis 脚本 命令
命令描述
Redis Script kill 命令杀死当前正在运行的 Lua 脚本。
Redis Script Load 命令将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。
Redis Eval 命令执行 Lua 脚本。
Redis Evalsha 命令执行 Lua 脚本。
Redis Script Exists 命令查看指定的脚本是否已经被保存在缓存当中。
Redis Script Flush 命令从脚本缓存中移除所有脚本。
Redis 事务 命令
命令描述
Redis Exec 命令执行所有事务块内的命令。
Redis Watch 命令监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
Redis Discard 命令取消事务,放弃执行事务块内的所有命令。
Redis Unwatch 命令取消 WATCH 命令对所有 key 的监视。
Redis Multi 命令标记一个事务块的开始。
Redis HyperLogLog 命令
命令描述
Redis Pgmerge 命令将多个 HyperLogLog 合并为一个 HyperLogLog
Redis Pfadd 命令添加指定元素到 HyperLogLog 中。
Redis Pfcount 命令返回给定 HyperLogLog 的基数估算值。
Redis 发布订阅 命令
命令描述
Redis Unsubscribe 命令指退订给定的频道。
Redis Subscribe 命令订阅给定的一个或多个频道的信息。
Redis Pubsub 命令查看订阅与发布系统状态。
Redis Punsubscribe 命令退订所有给定模式的频道。
Redis Publish 命令将信息发送到指定的频道。
Redis Psubscribe 命令订阅一个或多个符合给定模式的频道。
Redis 地理位置(geo) 命令
命令描述
Redis GEOHASH 命令返回一个或多个位置元素的 Geohash 表示
Redis GEOPOS 命令从key里返回所有给定位置元素的位置(经度和纬度)
Redis GEODIST 命令返回两个给定位置之间的距离
Redis GEORADIUS 命令以给定的经纬度为中心, 找出某一半径内的元素
Redis GEOADD 命令将指定的地理空间位置(纬度、经度、名称)添加到指定的key中
Redis GEORADIUSBYMEMBER 命令找出位于指定范围内的元素,中心点是由给定的位置元素决定

五.持久化

RDB

  • 保存数据文件的方式,恢复时直接读取文件就能完成恢复,恢复耗时短,但意外宕机时丢失数据多

    #直接前台执行保存程序
    save
    #后台执行保存程序
    bgsave
    
  • 在服务端目录下的dump.rdb文件数据持久化的数据文件

  • redis默认使用的RDB的持久化方式

  • 修改配置文件,更改触发自动保存的配置

AOF

  • 保存执行命令日志的形式,恢复时重新执行一遍日志文件,恢复耗时长,但意外宕机时丢失数据少

  • 日志保存在redis安装目录的appendonly.aof文件中

  • 保存日志的三种策略

    • always:每次执行写操作时都会保存一次
    • everysec:每一秒保存一次,默认使用这个策略
    • no:根据系统的调度保存一次,随机保存一次
  • 修改配置文件,使用AOF的持久化方式

    • 启用AOF

    • 指定保存日志的策略

  • redis有日志重写机制,会将冗余的指令,压缩为一条指令,并保证数据的一致性

    • 手动执行日志重写使用bgrewriteaof命令
  • 配置自动重写日志的触发条件

两种持久化方式对比

  • AOF:
    • 优点:存储速度快、消耗资源少、支持实时存储
    • 缺点:加载速度慢、数据体积大
  • RDB:
    • 优点:加载速度快、数据体积小
    • 缺点:存储速度慢大量消耗资源、会发生数据丢失

六.事务和锁

事务

  1. 开启事务

    mulpti
    
  2. 执行写入数据操作

    set a 100
    
  3. 提交事务

    exec
    
  4. 取消事务

    discard
    

  • 悲观锁:时刻认为别人会来抢占资源,禁止一切外来访问,直到释放锁,具有强烈的排他性质。

  • 乐观锁:并不认为会有人来抢占资源,所以会直接对数据进行操作,在操作时再去验证是否有其他人抢占资源。

  • 给一个键加锁

    #语法
    watch 键
    #例如
    watch a
    
  • 释放锁

    #语法
    unwatch 键
    #例如
    unwatch a
    

七.Java操作Redis

基本使用

  • 引入操作Redis的依赖
<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.0.0</version>
    </dependency>
</dependencies>
  • 连接到Redis数据库
public class App {
    public static void main(String[] args) {
        //获取Jedis对象
        try(Jedis jedis = new Jedis("192.168.79.88", 6379)){
            //添加数据
            jedis.set("name", "杨逸");
            //获取数据
            System.out.println("jedis.get(\"name\") = " + jedis.get("name"));

            jedis.lpush("list","1", "2", "3", "4", "5");
            System.out.println(jedis.lindex("list", 1));
            jedis.lrange("list",0,-1).forEach(System.out::println);
        }
    }
}
  • 调用方法执行操作

springboot中使用

  • 引入启动器
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • 修改配置文件
spring:
  redis:
  	#Redis服务器地址
    host: 192.168.10.3
    #端口
    port: 6379
    #使用几号数据库
    database: 0
  • 使用依赖提供的Redis模板类操作redis

    • 注入模板类
    @Service
    @Data
    @RequiredArgsConstructor
    public class RedisService {
        //使用构造器注入
        private final StringRedisTemplate redisTemplate;
    
    }
    
    • 测试
    @SpringBootTest
    class RedisServiceTest {
    
        @Resource
        private RedisService redisService;
    
        @Test
        public void testRedisService() {
            StringRedisTemplate redisTemplate = redisService.getRedisTemplate();
            //获取redis模板类中操作redis字符串数据的类
            ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
            //添加数据
            stringStringValueOperations.set("user:name","yangyi");
            //获取数据
            System.out.println("stringStringValueOperations.get(\"user:name\") = " + stringStringValueOperations.get("user:name"));
    
            //获取redis模板类中操作redis列表数据的类
            ListOperations<String, String> stringStringListOperations = redisTemplate.opsForList();
            //添加数据
            stringStringListOperations.rightPush("list1","100");
            stringStringListOperations.rightPush("list1","200");
            //获取数据
            stringStringListOperations.range("list1",0,-1).forEach(System.out::println);
    
        }
    }