SONiC (4) - redis的介绍以及应用
接下来在正式进入SONiC的开发和学习中,大家首先要掌握的是redis 的使用,因为SONiC中的数据交互都是通过redis进行的,那我们必须学会怎样在redis中进行读写,并知道它的基本的工作原理。
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
1. 阅读本文章前,需要了解的知识
需要了解基本的数据结构,例如以下几种:
- String: 字符串
- Hash: 散列
- List: 列表
- Set: 集合
- Sorted Set: 有序集合
相关资源
Redis 官网:Redis - The Real-time Data Platform
源码地址:https://github.com/redis/redis
Redis 在线测试:http://try.redis.io/
Redis 命令参考:Redis 命令参考 — Redis 命令参考
2. Redis 简介
Redis(Remote Dictionary Server)是一个开源的内存数据库,遵守 BSD 协议,它提供了一个高性能的键值(key-value)存储系统,常用于缓存、消息队列、会话存储等应用场景。
-
性能极高:Redis 以其极高的性能而著称,能够支持每秒数十万次的读写操作24。这使得Redis成为处理高并发请求的理想选择,尤其是在需要快速响应的场景中,如缓存、会话管理、排行榜等。
-
丰富的数据类型:Redis 不仅支持基本的键值存储,还提供了丰富的数据类型,包括字符串、列表、集合、哈希表、有序集合等。这些数据类型为开发者提供了灵活的数据操作能力,使得Redis可以适应各种不同的应用场景。
-
原子性操作:Redis 的所有操作都是原子性的,这意味着操作要么完全执行,要么完全不执行。这种特性对于确保数据的一致性和完整性至关重要,尤其是在高并发环境下处理事务时。
-
持久化:Redis 支持数据的持久化,可以将内存中的数据保存到磁盘中,以便在系统重启后恢复数据。这为 Redis 提供了数据安全性,确保数据不会因为系统故障而丢失。
-
支持发布/订阅模式:Redis 内置了发布/订阅模式(Pub/Sub),允许客户端之间通过消息传递进行通信。这使得 Redis 可以作为消息队列和实时数据传输的平台。
-
单线程模型:尽管 Redis 是单线程的,但它通过高效的事件驱动模型来处理并发请求,确保了高性能和低延迟。单线程模型也简化了并发控制的复杂性。
-
主从复制:Redis 支持主从复制,可以通过从节点来备份数据或分担读请求,提高数据的可用性和系统的伸缩性。
-
应用场景广泛:Redis 被广泛应用于各种场景,包括但不限于缓存系统、会话存储、排行榜、实时分析、地理空间数据索引等。
-
社区支持:Redis 拥有一个活跃的开发者社区,提供了大量的文档、教程和第三方库,这为开发者提供了强大的支持和丰富的资源。
-
跨平台兼容性:Redis 可以在多种操作系统上运行,包括 Linux、macOS 和 Windows,这使得它能够在不同的技术栈中灵活部署。
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 是单线程的,但它通过高效的事件驱动模型来处理并发请求,确保了高性能和低延迟。
redis 的安装和配置不是我们关心的内容,因为我们的redis已经在SONiC中安装和配置好,想了解的同学自行在网上查阅即可
3. Redis 数据类型
Redis 主要支持以下几种数据类型:
- string(字符串): 基本的数据存储单元,可以存储字符串、整数或者浮点数。
- hash(哈希):一个键值对集合,可以存储多个字段。
- list(列表):一个简单的列表,可以存储一系列的字符串元素。
- set(集合):一个无序集合,可以存储不重复的字符串元素。
- zset(sorted set:有序集合): 类似于集合,但是每个元素都有一个分数(score)与之关联。
- 位图(Bitmaps):基于字符串类型,可以对每个位进行操作。
- 超日志(HyperLogLogs):用于基数统计,可以估算集合中的唯一元素数量。
- 地理空间(Geospatial):用于存储地理位置信息。
- 发布/订阅(Pub/Sub):一种消息通信模式,允许客户端订阅消息通道,并接收发布到该通道的消息。
- 流(Streams):用于消息队列和日志存储,支持消息的持久化和时间排序。
- 模块(Modules):Redis 支持动态加载模块,可以扩展 Redis 的功能。
3.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
:将值追加到键的值之后。127.0.0.1:6379> SET runoob "haohaoxuexi" OK 127.0.0.1:6379> get runoob "haohaoxuexi" 127.0.0.1:6379> SET runoob "haohaoxuexi" OK 127.0.0.1:6379> GET RUNOOB (nil) 127.0.0.1:6379> GET runoob "haohaoxuexi" 127.0.0.1:6379> ]
3.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
:删除哈希表中的一个或多个字段。
127.0.0.1:6379> HSET runoob
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> HSET runoob field "Hello" field "World"
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379>
这里大家可以看到报错了,那是因为我们前面已经设置了runoob 字段,那我们需要删除它
127.0.0.1:6379> DEL runoob
(integer) 1
127.0.0.1:6379> HSET runoob field "Hello" field "World"
(integer) 1
127.0.0.1:6379> GET runoob field
(error) ERR wrong number of arguments for 'get' command
127.0.0.1:6379> HGET runoob field
"World"
127.0.0.1:6379> HSET runoob field1 "Hello" field2 "World"
(integer) 2
127.0.0.1:6379> HGET runoob field1
"Hello"
127.0.0.1:6379> HGET runoob field2
"World"
127.0.0.1:6379>
3.3 List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
列表最多可以存储 2^32 - 1 个元素。
常用命令
LPUSH key value
:将值插入到列表头部。RPUSH key value
:将值插入到列表尾部。LPOP key
:移出并获取列表的第一个元素。RPOP key
:移出并获取列表的最后一个元素。LRANGE key start stop
:获取列表在指定范围内的元素。
127.0.0.1:6379> DEl runoob
(integer) 1
127.0.0.1:6379> lpush runoob redis
(integer) 1
127.0.0.1:6379> lpush runoob redis2
(integer) 2
127.0.0.1:6379> lpush runoob redis3
(integer) 3
127.0.0.1:6379> lrange runoob 0 8
1) "redis3"
2) "redis2"
3) "redis"
127.0.0.1:6379>
3.4 Set(集合)
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
常用命令
SADD key value
:向集合添加一个或多个成员。SREM key value
:移除集合中的一个或多个成员。SMEMBERS key
:返回集合中的所有成员。SISMEMBER key value
:判断值是否是集合的成员。
sadd 命令
添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0。
127.0.0.1:6379> DEL runoob
(integer) 1
127.0.0.1:6379> sadd runoob redis1
(integer) 1
127.0.0.1:6379> sadd runoob redis2
(integer) 1
127.0.0.1:6379> sadd runoob redis3
(integer) 1
127.0.0.1:6379> smembers runoob
1) "redis3"
2) "redis2"
3) "redis1"
127.0.0.1:6379>
3.5 zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
常用命令
ZADD key score value
:向有序集合添加一个或多个成员,或更新已存在成员的分数。ZRANGE key start stop [WITHSCORES]
:返回指定范围内的成员。ZREM key value
:移除有序集合中的一个或多个成员。ZSCORE key value
:返回有序集合中,成员的分数值。
zadd 命令
添加元素到集合,元素在集合中存在则更新对应score
zadd key score member
127.0.0.1:6379> DEL runoob
(integer) 1
127.0.0.1:6379> zadd runoob 0 redis1
(integer) 1
127.0.0.1:6379> zadd runoob 0 redis2
(integer) 1
127.0.0.1:6379> zadd runoob 0 redis3
(integer) 1
127.0.0.1:6379> zrange runoob0 8
(error) ERR wrong number of arguments for 'zrange' command
127.0.0.1:6379> zrange runoob 0 8
1) "redis1"
2) "redis2"
3) "redis3"
127.0.0.1:6379>
其他高级数据类似
HyperLogLog
- 用于基数估计算法的数据结构。
- 常用于统计唯一值的近似值。
Bitmaps
- 位数组,可以对字符串进行位操作。
- 常用于实现布隆过滤器等位操作。
Geospatial Indexes
- 处理地理空间数据,支持地理空间索引和半径查询。
Streams
-
- 日志数据类型,支持时间序列数据。
- 用于消息队列和实时数据处理
-
4. Redis 发布订阅
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
实例
以下实例演示了发布订阅是如何工作的,需要开启两个 redis-cli 客户端。
在我们实例中我们创建了订阅频道名为 runoobChat:
第一个 redis-cli 客户端
127.0.0.1:6379> SUBSCRIBE runoobchat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "runoobchat"
3) (integer) 1
1) "message"
2) "runoobchat"
3) "hello world"
第二个 redis-cli 客户端
127.0.0.1:6379> PUBLISH runoobchat "hello world"
(integer) 1
127.0.0.1:6379>
Redis 发布订阅命令
下表列出了 redis 发布订阅常用命令:
序号 | 命令及描述 |
---|---|
1 | PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道。 |
2 | PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态。 |
3 | PUBLISH channel message 将信息发送到指定的频道。 |
4 | PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。 |
5 | SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息。 |
6 | UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。 |
这就是redis 的常用的基本命令,可以先做基本的了解,后面会有大量redis 的操作,更多的命令和操作大家可以在前面给出的链接中学习和操作