一、Redis概述
1. Redis简介
1.1 简介
Redis(Remote Dictionary Server)是一个开源的内存数据库,遵守 BSD 协议,它提供了一个高性能的键值(key-value)存储系统,常用于缓存、消息队列、会话存储等应用场景。
- 性能极高:Redis 以其极高的性能而著称,能够支持每秒数十万次的读写操作。这使得Redis成为处理高并发请求的理想选择,尤其是在需要快速响应的场景中,如缓存、会话管理、排行榜等。
- 丰富的数据类型:Redis 不仅支持基本的键值存储,还提供了丰富的数据类型,包括字符串、列表、集合、哈希表、有序集合等。这些数据类型为开发者提供了灵活的数据操作能力,使得Redis可以适应各种不同的应用场景。
- 原子性操作:Redis 的所有操作都是原子性的,这意味着操作要么完全执行,要么完全不执行。这种特性对于确保数据的一致性和完整性至关重要,尤其是在高并发环境下处理事务时。
- 持久化:Redis 支持数据的持久化,可以将内存中的数据保存到磁盘中,以便在系统重启后恢复数据。这为 Redis 提供了数据安全性,确保数据不会因为系统故障而丢失。
- 支持发布/订阅模式:Redis 内置了发布/订阅模式(Pub/Sub),允许客户端之间通过消息传递进行通信。这使得 Redis 可以作为消息队列和实时数据传输的平台。
- 单线程模型:尽管 Redis 是单线程的,但它通过高效的事件驱动模型来处理并发请求,确保了高性能和低延迟。单线程模型也简化了并发控制的复杂性。
- 主从复制:Redis 支持主从复制,可以通过从节点来备份数据或分担读请求,提高数据的可用性和系统的伸缩性。
- 应用场景广泛:Redis 被广泛应用于各种场景,包括但不限于缓存系统、会话存储、排行榜、实时分析、地理空间数据索引等。
- 社区支持:Redis 拥有一个活跃的开发者社区,提供了大量的文档、教程和第三方库,这为开发者提供了强大的支持和丰富的资源。
- 跨平台兼容性:Redis 可以在多种操作系统上运行,包括 Linux、macOS 和 Windows,这使得它能够在不同的技术栈中灵活部署。
1.2 Redis 与其他 key-value 存储有什么不同?
Redis 与其他 key-value 存储系统的主要区别在于其提供了丰富的数据类型、高性能的读写能力、原子性操作、持久化机制、以及丰富的特性集。
以下是 Redis 的一些独特之处:
- 丰富的数据类型:Redis 不仅仅支持简单的 key-value 类型的数据,还提供了 list、set、zset(有序集合)、hash 等数据结构的存储。这些数据类型可以更好地满足特定的业务需求,使得 Redis 可以用于更广泛的应用场景。
- 高性能的读写能力:Redis 能读的速度是 110000次/s,写的速度是 81000次/s。这种高性能主要得益于 Redis 将数据存储在内存中,从而显著提高了数据的访问速度。
- 原子性操作:Redis 的所有操作都是原子性的,这意味着操作要么完全执行,要么完全不执行。这种特性对于确保数据的一致性和完整性非常重要。
- 持久化机制:Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,以便在系统重启后能够再次加载使用。这为 Redis 提供了数据安全性,确保数据不会因为系统故障而丢失。
- 丰富的特性集:Redis 还支持 publish/subscribe(发布/订阅)模式、通知、key 过期等高级特性。这些特性使得 Redis 可以用于消息队列、实时数据分析等复杂的应用场景。
- 主从复制和高可用性:Redis 支持 master-slave 模式的数据备份,提供了数据的备份和主从复制功能,增强了数据的可用性和容错性。
- 支持 Lua 脚本:Redis 支持使用 Lua 脚本来编写复杂的操作,这些脚本可以在服务器端执行,提供了更多的灵活性和强大的功能。
- 单线程模型:尽管 Redis 是单线程的,但它通过高效的事件驱动模型来处理并发请求,确保了高性能和低延迟。
2. Redis安装
下载链接:https://github.com/tporadowski/redis/releases
下载zip后,解压到文件夹中,并加入环境变量中。
启动server
redis-server.exe redis.windows.conf
启动客户端
redis-cli.exe -h 127.0.0.1 -p 6379
3. Redis配置
Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf (Windows 名为 redis.windows.conf)。
可以通过 CONFIG 命令查看或设置配置项。
语法
Redis CONFIG 命令格式如下:
CONFIG GET CONFIG_SETTING_NAME
使用 * 号获取所有配置项。
编辑配置
可以通过修改 redis.conf 文件或使用 CONFIG set 命令来修改配置。
语法
CONFIG SET 命令基本语法:
CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
4. Redis数据类型
Redis 主要支持以下几种数据类型:
- string(字符串): 基本的数据存储单元,可以存储字符串、整数或者浮点数。
- hash(哈希): 一个键值对集合,可以存储多个字段。
- list(列表): 一个简单的列表,可以存储一系列的字符串元素。
- set(集合): 一个无序集合,可以存储不重复的字符串元素。
- zset(sorted set:有序集合) : 类似于集合,但是每个元素都有一个分数(score)与之关联。
- 位图(Bitmaps):基于字符串类型,可以对每个位进行操作。
- 超日志(HyperLogLogs):用于基数统计,可以估算集合中的唯一元素数量。
- 地理空间(Geospatial):用于存储地理位置信息。
- 发布/订阅(Pub/Sub):一种消息通信模式,允许客户端订阅消息通道,并接收发布到该通道的消息。
- 流(Streams):用于消息队列和日志存储,支持消息的持久化和时间排序。
- 模块(Modules):Redis 支持动态加载模块,可以扩展 Redis 的功能。
4.1 String
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据,比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
常用命令
- SET key value:设置键的值。
- GET key:获取键的值。
- INCR key:将键的值加 1。
- DECR key:将键的值减 1。
- APPEND key value:将值追加到键的值之后。
实例:
set username aircl
get username
注意:一个键最大能存储 512MB。
4.2 Hash
Redis hash 是一个键值(key=>value)对集合,类似于一个小型的 NoSQL 数据库。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
每个哈希最多可以存储 2^32 - 1 个键值对。
常用命令
- HSET key field value:设置哈希表中字段的值。
- HGET key field:获取哈希表中字段的值。
- HGETALL key:获取哈希表中所有字段和值。
- HDEL key field:删除哈希表中的一个或多个字段。
实例:
hset user field1 aircl field2 24
hget user field1
hget user field2
4.3 List
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
列表最多可以存储 2^32 - 1 个元素。
常用命令
- LPUSH key value:将值插入到列表头部。
- RPUSH key value:将值插入到列表尾部。
- LPOP key:移出并获取列表的第一个元素。
- RPOP key:移出并获取列表的最后一个元素。
- LRANGE key start stop:获取列表在指定范围内的元素。
实例:
lpush testList first
rpush testList second
lrange testList 0 10
4.4 Set
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
常用命令
- SADD key value:向集合添加一个或多个成员。
- SREM key value:移除集合中的一个或多个成员。
- SMEMBERS key:返回集合中的所有成员。
- SISMEMBER key value:判断值是否是集合的成员。
实例:
sadd testSet elem1
sadd testSet elem2
sadd testSet elem2
smembers testSet
注意:以上实例中 elem2 添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。
集合中最大的成员数为 2^32 - 1(4294967295, 每个集合可存储40多亿个成员)。
4.5 ZSet
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
常用命令
- ZADD key score value:向有序集合添加一个或多个成员,或更新已存在成员的分数。
- ZRANGE key start stop [WITHSCORES]:返回指定范围内的成员。
- ZREM key value:移除有序集合中的一个或多个成员。
- ZSCORE key value:返回有序集合中,成员的分数值。
实例:
zadd testZSet 1 first
zadd testZSet 2 second
zadd testZSet 0 zero
zrange testZSet 0 10
4.6 其他高级数据类似
HyperLogLog
用于基数估计算法的数据结构。
常用于统计唯一值的近似值。
Bitmaps
位数组,可以对字符串进行位操作。
常用于实现布隆过滤器等位操作。
Geospatial Indexes
处理地理空间数据,支持地理空间索引和半径查询。
Streams
日志数据类型,支持时间序列数据。
用于消息队列和实时数据处理。
二、Redis 命令
1. Redis键
Redis 键命令用于管理 redis 的键。
语法
Redis 键命令的基本语法如下:
COMMAND KEY_NAME
实例:
SET runoobkey redis
DEL runoobkey
在以上实例中 DEL 是一个命令, runoobkey 是一个键。 如果键被删除成功,命令执行后输出 (integer) 1,否则将输出 (integer) 0
Redis keys 命令
- DEL key
Redis DEL 命令用于删除已存在的键。不存在的 key 会被忽略。
redis> SET w3ckey redis
OK
redis> DEL w3ckey
(integer) 1
- DUMP key
Redis DUMP 命令用于序列化给定 key ,并返回被序列化的值。
redis> SET greeting "hello, dumping world!"
OK
redis> DUMP greeting
"\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"redis> DUMP not-exists-key
(nil)
- EXISTS key
Redis EXISTS 命令用于检查给定 key 是否存在。
redis> set runoob-new-key newkey
OK
redis> EXISTS runoob-new-key
(integer) 1
- EXPIRE key seconds
Redis Expire 命令用于设置 key 的过期时间,key 过期后将不再可用。单位以秒计。
redis> SET runooobkey redis
OK
redis> EXPIRE runooobkey 60
(integer) 1
- EXPIREAT key timestamp
Redis Expireat 命令用于以 UNIX 时间戳(unix timestamp)格式设置 key 的过期时间。key 过期后将不再可用。
redis> SET runoobkey redis
OK
redis> EXPIREAT runoobkey 1293840000
(integer) 1
redis> EXISTS runoobkey
(integer) 0
- PEXPIRE key milliseconds
Redis PEXPIRE 命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。
redis> SET mykey "Hello"
"OK"
redis> PEXPIRE mykey 1500
(integer) 1
redis> TTL mykey
(integer) 1
redis> PTTL mykey
(integer) 1498
redis>
- PEXPIREAT key milliseconds-timestamp
Redis PEXPIREAT 命令用于设置 key 的过期时间,以毫秒计。key 过期后将不再可用。
redis> SET runoobkey redis
OK
redis> PEXPIREAT runoobkey 1555555555005
(integer) 1
- KEYS pattern
Redis Keys 命令用于查找所有符合给定模式 pattern 的 key 。
首先创建一些 key,并赋上对应值:
redis> SET runoob1 redis
OK
redis> SET runoob2 mysql
OK
redis> SET runoob3 mongodb
OK
查找以 runoob 为开头的 key:
redis> KEYS runoob*
1) "runoob3"
2) "runoob1"
3) "runoob2"
获取 redis 中所有的 key 可用使用 *。
redis> KEYS *
1) "runoob3"
2) "runoob1"
3) "runoob2"
- MOVE key db
Redis MOVE 命令用于将当前数据库的 key 移动到给定的数据库 db 当中。
# key 存在于当前数据库
redis> SELECT 0 # redis默认使用数据库 0,为了清晰起见,这里再显式指定一次。
OK
redis> SET song "secret base - Zone"
OK
redis> MOVE song 1 # 将 song 移动到数据库 1
(integer) 1
redis> EXISTS song # song 已经被移走
(integer) 0
redis> SELECT 1 # 使用数据库 1
OK
redis:1> EXISTS song # 证实 song 被移到了数据库 1 (注意命令提示符变成了"redis:1",表明正在使用数据库 1)
(integer) 1# 当 key 不存在的时候
redis:1> EXISTS fake_key
(integer) 0
redis:1> MOVE fake_key 0 # 试图从数据库 1 移动一个不存在的 key 到数据库 0,失败
(integer) 0
redis:1> select 0 # 使用数据库0
OK
redis> EXISTS fake_key # 证实 fake_key 不存在
(integer) 0# 当源数据库和目标数据库有相同的 key 时
redis> SELECT 0 # 使用数据库0
OK
redis> SET favorite_fruit "banana"
OK
redis> SELECT 1 # 使用数据库1
OK
redis:1> SET favorite_fruit "apple"
OK
redis:1> SELECT 0 # 使用数据库0,并试图将 favorite_fruit 移动到数据库 1
OK
redis> MOVE favorite_fruit 1 # 因为两个数据库有相同的 key,MOVE 失败
(integer) 0
redis> GET favorite_fruit # 数据库 0 的 favorite_fruit 没变
"banana"
redis> SELECT 1
OK
redis:1> GET favorite_fruit # 数据库 1 的 favorite_fruit 也是
"apple"
- PERSIST key
Redis PERSIST 命令用于移除给定 key 的过期时间,使得 key 永不过期。
redis> SET mykey "Hello"
OK
redis> EXPIRE mykey 10 # 为 key 设置生存时间
(integer) 1
redis> TTL mykey
(integer) 10
redis> PERSIST mykey # 移除 key 的生存时间
(integer) 1
redis> TTL mykey
(integer) -1
- PTTL key
Redis Pttl 命令以毫秒为单位返回 key 的剩余过期时间。
返回值
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以毫秒为单位,返回 key 的剩余生存时间。
注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。
# 不存在的 key
redis> FLUSHDB
OK
redis> PTTL key
(integer) -2# key 存在,但没有设置剩余生存时间
redis> SET key value
OK
redis> PTTL key
(integer) -1# 有剩余生存时间的 key
redis> PEXPIRE key 10086
(integer) 1
redis> PTTL key
(integer) 6179
- TTL key
Redis TTL 命令以秒为单位返回 key 的剩余过期时间。
返回值
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。
注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。
# 不存在的 key
redis> FLUSHDB
OK
redis> TTL key
(integer) -2# key 存在,但没有设置剩余生存时间
redis> SET key value
OK
redis> TTL key
(integer) -1# 有剩余生存时间的 key
redis> EXPIRE key 10086
(integer) 1
redis> TTL key
(integer) 10084
- RANDOMKEY
Redis RANDOMKEY 命令从当前数据库中随机返回一个 key 。
# 数据库不为空
redis> MSET fruit "apple" drink "beer" food "cookies" # 设置多个 key
OK
redis> RANDOMKEY
"fruit"
redis> RANDOMKEY
"food"
redis> KEYS * # 查看数据库内所有key,证明 RANDOMKEY 并不删除 key
1) "food"
2) "drink"
3) "fruit"# 数据库为空
redis> FLUSHDB # 删除当前数据库所有 key
OK
redis> RANDOMKEY
(nil)
- RENAME key newkey
Redis Rename 命令用于修改 key 的名称 。
# key 存在且 newkey 不存在
redis> SET message "hello world"
OK
redis> RENAME message greeting
OK
redis> EXISTS message # message 不复存在
(integer) 0
redis> EXISTS greeting # greeting 取而代之
(integer) 1# 当 key 不存在时,返回错误redis> RENAME fake_key never_exists
(error) ERR no such key# newkey 已存在时, RENAME 会覆盖旧 newkey
redis> SET pc "lenovo"
OK
redis> SET personal_computer "dell"
OK
redis> RENAME pc personal_computer
OK
redis> GET pc
(nil)
redis> GET personal_computer # 原来的值 dell 被覆盖了
"lenovo"
- RENAMENX key newkey
Redis Renamenx 命令用于在新的 key 不存在时修改 key 的名称 。
# newkey 不存在,改名成功
redis> SET player "MPlyaer"
OK
redis> EXISTS best_player
(integer) 0
redis> RENAMENX player best_player
(integer) 1# newkey存在时,失败
redis> SET animal "bear"
OK
redis> SET favorite_animal "butterfly"
OK
redis> RENAMENX animal favorite_animal
(integer) 0
redis> get animal
"bear"
redis> get favorite_animal
"butterfly"
- SCAN cursor [MATCH pattern] [COUNT count]
Redis Scan 命令用于迭代数据库中的数据库键。
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。
相关命令:
- SSCAN 命令用于迭代集合键中的元素。
- HSCAN 命令用于迭代哈希键中的键值对。
- ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。
redis> scan 0 # 使用 0 作为游标,开始新的迭代
1) "17" # 第一次迭代时返回的游标
2) 1) "key:12"2) "key:8"3) "key:4"4) "key:14"5) "key:16"6) "key:17"7) "key:15"8) "key:10"9) "key:3"10) "key:7"11) "key:1"
redis> scan 17 # 使用的是第一次迭代时返回的游标 17 开始新的迭代
1) "0"
2) 1) "key:5"2) "key:18"3) "key:0"4) "key:2"5) "key:19"6) "key:13"7) "key:6"8) "key:9"9) "key:11"
- TYPE key
Redis Type 命令用于返回 key 所储存的值的类型。
返回值
返回 key 的数据类型,数据类型有:
- none (key不存在)
- string (字符串)
- list (列表)
- set (集合)
- zset (有序集)
- hash (哈希表)
# 字符串
redis> SET weather "sunny"
OK
redis> TYPE weather
string# 列表
redis> LPUSH book_list "programming in scala"
(integer) 1
redis> TYPE book_list
list# 集合
redis> SADD pat "dog"
(integer) 1
redis> TYPE pat
set