Redis

Redis是一个基于内存 的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件

官网: Redis - The Real-time Data PlatformDevelopers love Redis. Unlock the full potential of the Redis database with Redis Enterprise and start building blazing fast apps.https://redis.io 中文网: Redis中文网https://www.redis.net.cn/

简介

Redis是一种开源的、基于内存的键值对存储系统,具有高性能、丰富的数据类型和持久化等特点。它主要用于缓存服务器,同时也可作为消息中间件和Session共享等。具体如下:

  1. 性能优势:Redis全称为Remote Dictionary Server,是一款开源的基于内存的键值对存储系统,其主要被用作高性能缓存服务器使用。由于其基于内存的方式,免去了磁盘I/O速度的影响,使得其读写性能极高,能够支持每秒数十万次的读写操作。这使得Redis成为处理高并发请求的理想选择,尤其是在需要快速响应的场景中,如缓存、会话管理、排行榜等。
  2. 数据类型:Redis独特的键值对模型支持丰富的数据结构类型,包括字符串、哈希、列表、集合和有序集合。这些数据类型为开发者提供了灵活的数据操作能力,使Redis可以适应各种不同的应用场景。例如,利用有序集合可以实现排行榜功能,而原子性的自增操作则可以用于计数器和限速器。
  3. 持久化机制:Redis支持两种持久化方式,即RDB(快照)和AOF(只追加文件)。RDB通过定期将内存中的数据快照保存到磁盘实现数据持久化,而AOF则是记录每次写操作命令,以日志形式保存。这种持久化机制在突然断电等异常情况下能保证数据不丢失,提高了数据安全性。
  4. 应用场景:Redis不仅可以作为缓存系统,还可用于会话存储、实时分析、地理空间数据索引等场景。例如,在分布式系统中,利用Redis存储session信息,可以避免频繁登陆操作,提高用户体验。同时,Redis的发布/订阅模式使其可以作为简单的消息队列使用。
  5. 主从复制: Redis支持主从复制,可以通过从节点备份数据或分担读请求,从而提高数据的可用性和系统的伸缩性。主从复制不仅增强了数据的安全性,还实现了数据的备份和故障转移。

Redis服务启停

Redis服务的启动与停止可以通过多种方式进行操作,具体方法取决于安装方式和操作系统环境。在Linux系统中,常用的启停命令包括使用初始化脚本、配置文件和命令行工具等。以下是对各种启停方法的详细分析:

初始化脚本启动 :如果通过apt-getyum包管理器安装Redis,可以使用初始化脚本来管理服务。常见的命令如下:

  • 启动:/etc/init.d/redis-server start
  • 停止:/etc/init.d/redis-server stop
  • 重启:/etc/init.d/redis-server restart

配置文件启动 :进入Redis的安装目录,运行redis-server命令并指定配置文件。例如:

  • ./redis-server /etc/redis/6379.conf
  • 若需要以后台模式运行,可以添加--daemonize yes选项。

命令行工具启动 :直接使用redis-server启动Redis,例如:

  • ./redis-server --port 6380(无密码启动)
  • ./redis-server .../redis.conf(已设置访问密码启动)

客户端命令关闭 :使用redis-cli工具执行shutdown命令来安全停止Redis。例如:

  • redis-cli -h 127.0.0.1 -p 6379 shutdown
  • 如果设置了密码,需添加-a password选项。

强制进程关闭 :如果正常关闭命令无效,可以使用kill -9 PID命令强制结束Redis进程。首先查询Redis的PID:

  • ps aux | grep redis找到PID,然后执行kill -9 PID

Redis数据类型

Redis 支持多种数据类型,包括字符串(String)、列表(List)、集合(Set)、有序集合(Sorted Set)、哈希(Hash)、位图(Bitmaps)、超日志(HyperLogLogs)和地理空间(Geospatial)等。这些数据类型各自具有独特的特点和使用场景,具体如下:

  1. 字符串(String):字符串是Redis最基本的数据类型,可以存储字符串、整数或浮点数,甚至是二进制数据。常用操作包括SET(设置键值对)、GET(获取键值)、INCR(自增键值)、APPEND(追加值)等。这种类型常用于缓存对象、分布式锁和计数器等场景。例如,可以将整个JSON字符串或图片作为字符串存储在Redis中。
  2. 列表(List):列表是一个双向链表,可以快速地从列表的头部或尾部插入或删除元素。常用命令包括LPUSH(从左侧插入)、RPUSH(从右侧插入)、LPOP(从左侧移除并返回元素)、RPOP(从右侧移除并返回元素)和LRANGE(获取指定范围的元素)等。列表适用于实现队列和栈,广泛应用于消息队列和时间线存储等。
  3. 集合(Set):集合是一个无序且不重复的字符串集合。它通过哈希表实现,添加、删除和查找的时间复杂度均为O(1)。常用命令包括SADD(添加元素)、SREM(移除元素)、SMEMBERS(获取所有元素)和SISMEMBER(判断元素是否在集合中)。集合常用于去重、社交网络中的好友推荐以及共同关注某类标签的用户。
  4. 有序集合(Sorted Set):有序集合类似于集合,但每个元素都有一个分数(score),根据这个分数进行排序。常用命令包括ZADD(添加元素和分数)、ZREM(移除元素)、ZRANGE(按分数范围获取元素)和ZCARD(获取集合大小)。适用于排行榜和时间线排序。
  5. 哈希(Hash):哈希包含键值对的集合,适合存储对象。每个哈希可以存储2^32-1个键值对。常用命令包括HSET(设置键值对)、HGET(获取键值)、HMGET(批量获取多个键值)和HDEL(删除一个或多个键值对)。哈希特别适用于存储用户信息、配置信息和其他对象类型的数据。
  6. 位图(Bitmaps):位图是基于字符串类型的数据结构,通过字符串的每一位来表示一个布尔值。操作命令包括SETBIT(设置特定位的值)、GETBIT(获取特定位的值)和BITCOUNT(统计指定范围内位值为1的个数)。位图非常适合用于需要大量标记的场景,如用户在线状态、活跃用户统计等。
  7. 超日志(HyperLogLog):超日志用于基数统计,即估算一个集合中的唯一元素数量。常用命令包括PFADD(添加元素到HyperLogLog)、PFCOUNT(统计唯一元素数量)等。这种数据类型适合于大数据集的基数统计,如网站UV统计。
  8. 地理空间(Geospatial):地理空间类型专门用于存储地理位置信息。常用命令包括GEOADD(添加地理位置)、GEODIST(计算两个位置之间的距离)、GEORADIUS(获取指定范围内的地理位置)。地理空间适用于物流跟踪、附近的人/物查询等场景。

Redis常用命令

字符串操作命令

SET:设置指定 key 的值。如果 key 已存在,则覆盖原有值。

  • 用法:SET key value
  • 示例:SET name "Redis tutorial" - 设置键 name 的值为 "Redis tutorial"

GET:获取并返回指定 key 的值。如果 key 不存在,返回 nil。

  • 用法:GET key
  • 示例:GET name - 获取键 name 的值,返回 "Redis tutorial"

MGET:一次性获取多个 key 的值。

  • 用法:MGET key1 key2 ...
  • 示例:MGET name description category - 获取 namedescriptioncategory 三个键的值。

APPEND:将给定的 value 追加到该 key 原来值的末尾。

  • 用法:APPEND key value
  • 示例:APPEND name " world" - 在 name 的值后面追加 " world",变为 "Redis tutorial world"

INCR:将 key 中储存的数字值增一。

  • 用法:INCR key
  • 示例:INCR pageviews - 假设 pageviews 当前为 5,执行后变为 6。

DECR:将 key 中储存的数字值减一。

  • 用法:DECR key
  • 示例:DECR inventory - 假设 inventory 当前为 10,执行后变为 9。

INCRBY:将 key 所储存的值加上指定的增量值。

  • 用法:INCRBY key increment
  • 示例:INCRBY score 5 - 假设 score 当前为 10,执行后变为 15。

DECRBY:将 key 所储存的值减去指定的减量值。

  • 用法:DECRBY key decrement
  • 示例:DECRBY balance 20 - 假设 balance 当前为 100,执行后变为 80。

GETRANGE:获取并返回指定 key 的字符串值中由 start 和 end 索引限定的子字符串部分。

  • 用法:GETRANGE key start end
  • 示例:GETRANGE content 0 9 - 获取 content 的值从索引 0 到索引 9 的子字符串。

SETRANGE:用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。

  • 用法:SETRANGE key offset value
  • 示例:SETRANGE title 5 "Example" - 假设 title 当前为 "Hello World",执行后变为 "Hello Example"。

哈希操作命令

HSET:设置哈希表中指定字段的值。

  • 用法:HSET key field value
  • 示例代码:HSET user:1 "name" "Tom" - 设置 user:1 中的 "name" 字段值为 "Tom"
  • 示例:HSET user:1 "age" 25 - 设置 user:1 中的 "age" 字段值为 25

HGET:获取哈希表中指定字段的值。

  • 用法:HGET key field
  • 示例代码:HGET user:1 "name" - 获取 user:1 中的 "name" 字段值。
  • 示例:HGET user:1 "age" - 获取 user:1 中的 "age" 字段值。

HMSET:同时设置哈希表中多个字段的值。

  • 用法:HMSET key field1 value1 field2 value2 ...
  • 示例代码:HMSET user:1 "name" "Tom" "age" 25 "occupation" "engineer" - 设置 user:1 中的多个字段。
  • 示例:HMSET user:2 "name" "Jerry" "age" 22 "occupation" "student" - 设置 user:2 中的多个字段。

HMGET:获取哈希表中多个字段的值。

  • 用法:HMGET key field1 field2 ...
  • 示例代码:HMGET user:1 "name" "age" - 获取 user:1 中的 "name""age" 字段值。
  • 示例:HMGET user:2 "name" "occupation" - 获取 user:2 中的 "name""occupation" 字段值。

HGETALL:获取哈希表中所有字段及其值。

  • 用法:HGETALL key
  • 示例代码:HGETALL user:1 - 获取 user:1 中的所有字段和值。
  • 示例:HGETALL user:2 - 获取 user:2 中的所有字段和值。

HDEL:删除哈希表中的指定字段。

  • 用法:HDEL key field1 field2 ...
  • 示例代码:HDEL user:1 "age" - 删除 user:1 中的 "age" 字段。
  • 示例:HDEL user:2 "occupation" - 删除 user:2 中的 "occupation" 字段。

HLEN:获取哈希表中字段的数量。

  • 用法:HLEN key
  • 示例代码:HLEN user:1 - 获取 user:1 中的字段数量。
  • 示例:HLEN user:2 - 获取 user:2 中的字段数量。

HEXISTS:检查哈希表中是否存在指定的字段。

  • 用法:HEXISTS key field
  • 示例代码:HEXISTS user:1 "name" - 检查 user:1 中是否存在 "name" 字段。
  • 示例:HEXISTS user:2 "email" - 检查 user:2 中是否存在 "email" 字段。

HKEYS:获取哈希表中所有的字段。

  • 用法:HKEYS key
  • 示例代码:HKEYS user:1 - 获取 user:1 中的所有字段。
  • 示例:HKEYS user:2 - 获取 user:2 中的所有字段。

HVALS:获取哈希表中所有字段的值。

  • 用法:HVALS key
  • 示例代码:HVALS user:1 - 获取 user:1 中所有字段的值。
  • 示例:HVALS user:2 - 获取 user:2 中所有字段的值。

列表操作命令

LPUSH:在列表头部插入一个或多个元素。

  • 用法:LPUSH key value1 value2 ...
  • 示例代码:LPUSH mylist "apple" "banana" "cherry" - 将三个元素依次插入到名为 mylist 的列表头部。

RPUSH:在列表尾部插入一个或多个元素。

  • 用法:RPUSH key value1 value2 ...
  • 示例代码:RPUSH mylist "apple" "banana" "cherry" - 将三个元素依次插入到名为 mylist 的列表尾部。

LPOP:移除并返回列表的第一个元素。

  • 用法:LPOP key
  • 示例代码:LPOP mylist - 移除并返回名为 mylist 的列表的第一个元素。

RPOP:移除并返回列表的最后一个元素。

  • 用法:RPOP key
  • 示例代码:RPOP mylist - 移除并返回名为 mylist 的列表的最后一个元素。

LLEN:获取列表的长度。

  • 用法:LLEN key
  • 示例代码:LLEN mylist - 获取名为 mylist 的列表的长度。

LINDEX:根据索引获取列表中的元素。

  • 用法:LINDEX key index
  • 示例代码:LINDEX mylist 0 - 获取名为 mylist 的列表中第一个元素的值。

LRANGE:获取列表指定范围内的元素。

  • 用法:LRANGE key start stop
  • 示例代码:LRANGE mylist 0 2 - 获取名为 mylist 的列表中前三个元素的值。

LREM:移除列表中指定数量的某个元素。

  • 用法:LREM key count value
  • 示例代码:LREM mylist 2 "apple" - 从名为 mylist 的列表中移除两个值为 "apple" 的元素。

LSET:设置列表中指定索引位置的元素值。

  • 用法:LSET key index value
  • 示例代码:LSET mylist 1 "orange" - 将名为 mylist 的列表中第二个元素的值设置为 "orange"

LINSERT:在列表中的某个元素之前或之后插入一个新元素。

  • 用法:LINSERT key BEFORE|AFTER pivot value
  • 示例代码:LINSERT mylist BEFORE "banana" "kiwi" - 在名为 mylist 的列表中,在值为 "banana" 的元素之前插入一个新的元素 "kiwi"

集合操作命令

SADD:向集合中添加一个或多个元素。

  • 用法:SADD key member1 member2 ...
  • 示例代码:SADD myset "apple" "banana" "cherry" - 将三个元素添加到名为 myset 的集合中。

SREM:从集合中移除一个或多个元素。

  • 用法:SREM key member1 member2 ...
  • 示例代码:SREM myset "banana" "cherry" - 从名为 myset 的集合中移除两个元素。

SISMEMBER:检查元素是否存在于集合中。

  • 用法:SISMEMBER key member
  • 示例代码:SISMEMBER myset "apple" - 检查名为 myset 的集合中是否包含元素 "apple"

SMEMBERS:获取集合中的所有成员。

  • 用法:SMEMBERS key
  • 示例代码:SMEMBERS myset - 获取名为 myset 的集合中的所有成员。

SCARD:获取集合的成员数量。

  • 用法:SCARD key
  • 示例代码:SCARD myset - 获取名为 myset 的集合的成员数量。

SDIFF:返回第一个集合与其他集合的差集。

  • 用法:SDIFF key1 key2 ...
  • 示例代码:SDIFF myset1 myset2 - 返回名为 myset1 的集合与名为 myset2 的集合的差集。

SINTER:返回多个集合的交集。

  • 用法:SINTER key1 key2 ...
  • 示例代码:SINTER myset1 myset2 - 返回名为 myset1myset2 的集合的交集。

SUNION:返回多个集合的并集。

  • 用法:SUNION key1 key2 ...
  • 示例代码:SUNION myset1 myset2 - 返回名为 myset1myset2 的集合的并集。

SRANDMEMBER:随机返回集合中的一个或多个成员。

  • 用法:SRANDMEMBER key [count]
  • 示例代码:SRANDMEMBER myset 2 - 从名为 myset 的集合中随机返回两个成员。

有序集合操作命令

ZADD:向有序集合中添加一个或多个成员,每个成员都有一个分数。

  • 用法:ZADD key score1 member1 [score2 member2 ...]
  • 示例代码:ZADD myzset 1 "apple" 2 "banana" 3 "cherry" - 将三个元素添加到名为 myzset 的有序集合中,并分别设置它们的分数为 1、2 和 3。

ZREM:从有序集合中移除一个或多个成员。

  • 用法:ZREM key member1 [member2 ...]
  • 示例代码:ZREM myzset "banana" "cherry" - 从名为 myzset 的有序集合中移除两个元素。

ZSCORE:获取有序集合中指定成员的分数。

  • 用法:ZSCORE key member
  • 示例代码:ZSCORE myzset "apple" - 获取名为 myzset 的有序集合中元素 "apple" 的分数。

ZRANK:返回有序集合中指定成员的排名(按分数从小到大排序)。

  • 用法:ZRANK key member
  • 示例代码:ZRANK myzset "apple" - 获取名为 myzset 的有序集合中元素 "apple" 的排名。

ZREVRANK:返回有序集合中指定成员的逆序排名(按分数从大到小排序)。

  • 用法:ZREVRANK key member
  • 示例代码:ZREVRANK myzset "apple" - 获取名为 myzset 的有序集合中元素 "apple" 的逆序排名。

ZRANGE:返回有序集合中指定排名范围内的成员。

  • 用法:ZRANGE key start stop [WITHSCORES]
  • 示例代码:ZRANGE myzset 0 2 WITHSCORES - 获取名为 myzset 的有序集合中排名在 0 到 2 之间的成员及其分数。

ZREVRANGE:返回有序集合中指定逆序排名范围内的成员。

  • 用法:ZREVRANGE key start stop [WITHSCORES]
  • 示例代码:ZREVRANGE myzset 0 2 WITHSCORES - 获取名为 myzset 的有序集合中逆序排名在 0 到 2 之间的成员及其分数。

ZCARD:获取有序集合的成员数量。

  • 用法:ZCARD key
  • 示例代码:ZCARD myzset - 获取名为 myzset 的有序集合的成员数量。

ZCOUNT:返回有序集合中分数在指定区间内的成员数量。

  • 用法:ZCOUNT key min max
  • 示例代码:ZCOUNT myzset 1 3 - 获取名为 myzset 的有序集合中分数在 1 到 3 之间的成员数量。

通用命令

GET:根据键获取值。

  • 用法:GET key
  • 示例代码:GET mykey - 获取名为 mykey 的键对应的值。

SET:设置键值对。

  • 用法:SET key value
  • 示例代码:SET mykey "Hello, Redis!" - 设置名为 mykey 的键的值为 "Hello, Redis!"

KEYS:获取所有符合模式的键。

  • 用法:KEYS pattern
  • 示例代码:KEYS *mykey* - 获取所有包含 mykey 的键。

EXISTS:检查键是否存在。

  • 用法:EXISTS key [key ...]
  • 示例代码:EXISTS mykey - 检查名为 mykey 的键是否存在。

DEL:删除一个或多个键。

  • 用法:DEL key [key ...]
  • 示例代码:DEL mykey - 删除名为 mykey 的键。

EXPIRE:为键设置过期时间。

  • 用法:EXPIRE key seconds
  • 示例代码:EXPIRE mykey 3600 - 设置名为 mykey 的键在 3600 秒后过期。

TTL:获取键的剩余过期时间。

  • 用法:TTL key
  • 示例代码:TTL mykey - 获取名为 mykey 的键的剩余过期时间。

TYPE:获取键的数据类型。

  • 用法:TYPE key
  • 示例代码:TYPE mykey - 获取名为 mykey 的键对应的数据类型。

PING:用于测试与Redis的连接是否畅通。

  • 用法:PING
  • 示例代码:PING - 如果连接正常,返回结果为:PONG

Spring Data Redis

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。

网址:Spring Data RedisLevel up your Java code and explore what Spring can do for you.https://spring.io/projects/spring-data-redis

集成

  • 添加依赖 :在项目的 pom.xml 文件中添加 spring-boot-starter-data-redis 依赖,这是整合 Redis 到 Spring Boot 项目的第一步。如果选择 Lettuce 作为 Redis 客户端,还需添加 lettuce-core 依赖;若选择 Jedis,则需添加 jedis 依赖。

  • 配置连接 :修改 application.propertiesapplication.yml 配置文件,填入 Redis 服务器的连接信息,包括主机名、端口号以及其他相关配置。例如:

    java 复制代码
    spring.redis.host=localhost
    spring.redis.port=6379
    spring.redis.password= # 如果设置了密码,则填写密码
    spring.redis.database=0 # Redis数据库索引(默认为0)
  • 选择客户端:Spring Data Redis 支持 Lettuce 和 Jedis 作为 Redis 客户端。Lettuce 基于 Netty 构建,支持非阻塞式 I/O,是 Spring Boot 2.x 中的默认客户端。Jedis 是一个老牌的 Redis 客户端,依然在一些场景中得到广泛应用。开发者可以根据需求选择合适的客户端。

操作数据

  • 使用 RedisTemplateRedisTemplate 是 Spring Data Redis 提供的核心类,它提供了一组方法来执行 Redis 命令。例如,可以使用 opsForValue() 方法来操作 Redis 字符串(String),用 opsForList() 方法操作列表(List),以此类推。示例代码如下:

    java 复制代码
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    public void setAndGetString() {
        stringRedisTemplate.opsForValue().set("key", "value");
        String value = stringRedisTemplate.opsForValue().get("key");
        System.out.println("Retrieved value: " + value);
    }
  • 处理复杂数据结构 :对于哈希(Hash)等复杂数据结构,RedisTemplate 提供了相应的操作方法。例如,使用 opsForHash() 方法可以设置和获取哈希字段的值。此外,Spring Data Redis 还支持高级特性如事务、管道化命令和 Lua 脚本。

高级功能

  • 消息发布和订阅 :Redis 的消息发布/订阅功能允许实现消息传递系统。Spring Data Redis 通过 RedisPubSubTemplate 提供了对这一功能的直接支持。发布者使用 convertAndSend() 方法发布消息,而订阅者注册一个消息监听器来接收并处理这些消息。
  • 缓存抽象 :Spring Data Redis 提供了一套缓存抽象,使开发者能够轻松实现缓存逻辑。通过使用 @Cacheable 注解,可以标记那些需要被缓存的方法,从而在调用这些方法时自动返回缓存的结果而非执行实际计算。
  • 自定义序列化:为了更高效地处理 Java 对象与 Redis 数据类型之间的转换,Spring Data Redis 允许开发者自定义序列化策略。通过实现适当的序列化接口或类,可以控制对象的序列化和反序列化过程。

集群支持

  • 连接集群 :Spring Data Redis 支持连接到 Redis 集群。通过配置 RedisClusterConfiguration,可以创建一个连接到整个集群的 RedisClusterConnection 对象。之后,使用 RedisClusterCommands 可以执行集群特有的命令,例如 clusterGetAll
  • 哨兵模式 :在 Redis 集群环境中,Spring Data Redis 支持哨兵(Sentinel)模式以实现高可用性。通过配置 RedisSentinelConfiguration,可以创建一个连接到主节点的连接工厂,并在主节点不可用时自动切换到从节点。

响应式编程支持

  • ReactiveRedisTemplate :在响应式编程模型中,Spring Data Redis 提供了 ReactiveRedisTemplate,它利用非阻塞式 I/O 操作 Redis 数据库。这使得在处理大量并发操作时能保持较低的延迟和高吞吐量。
  • 流式 API :通过使用响应式 API,开发者可以利用 FluxMono 类型来执行流式查询和异步操作,这大大简化了对响应式编程模型的使用。
相关推荐
栗豆包6 分钟前
w118共享汽车管理系统
java·spring boot·后端·spring·tomcat·maven
夜半被帅醒12 分钟前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
万亿少女的梦16818 分钟前
基于Spring Boot的网络购物商城的设计与实现
java·spring boot·后端
不爱学习的啊Biao26 分钟前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
破 风36 分钟前
SpringBoot 集成 MongoDB
数据库·mongodb
Rverdoser1 小时前
MySQL-MVCC(多版本并发控制)
数据库·mysql
醒了就刷牙1 小时前
黑马Java面试教程_P9_MySQL
java·mysql·面试
m0_748233641 小时前
SQL数组常用函数记录(Map篇)
java·数据库·sql
dowhileprogramming1 小时前
Python 中的迭代器
linux·数据库·python
编程爱好者熊浪2 小时前
JAVA HTTP压缩数据
java