今天和大家分享下 Redis 基础,后面准备基于此,来做一个简单的在线聊天室。
初识 Redis
众所周知,Redis 是一个高性能的内存 key-value 数据库。
它主要有三个有点:
- Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。
- Redis 支持数据的备份,即 master-slave 模式的数据备份。
Redis 支持的数据类型
Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
String
string 是 Redis 中最最基本的数据类型,一个 key 对应一个 value。
redis 127.0.0.1:6379> SET name "hello world" OK redis 127.0.0.1:6379> GET name "hello world"
Hash(哈希)
Redis hash 是一个键值( key => value )对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
redis 127.0.0.1:6379> HMSET myhash field1 "Hello" field2 "World" "OK" redis 127.0.0.1:6379> HGET myhash field1 "Hello" redis 127.0.0.1:6379> HGET myhash field2 "World"
List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。
redis 127.0.0.1:6379> lpush mylist redis (integer) 1 redis 127.0.0.1:6379> lpush mylist mongodb (integer) 2 redis 127.0.0.1:6379> lpush mylist rabitmq (integer) 3 redis 127.0.0.1:6379> lrange mylist 0 5 1) "rabitmq" 2) "mongodb" 3) "redis" redis 127.0.0.1:6379>
Set(集合)
Redis 的 Set 是 string 类型的无序集合。
redis 127.0.0.1:6379> sadd myset redis (integer) 1 redis 127.0.0.1:6379> sadd myset mongodb (integer) 1 redis 127.0.0.1:6379> sadd myset rabitmq (integer) 1 redis 127.0.0.1:6379> sadd myset rabitmq (integer) 0 redis 127.0.0.1:6379> smembers myset 1) "redis" 2) "rabitmq" 3) "mongodb"
zset(sorted set:有序集合)
Redis zset 和 set 一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。Redis 正是通过分数来为集合中的成员进行从小到大的排序。
zset 的成员是唯一的,但分数(score)却可以重复。
redis 127.0.0.1:6379> zadd myzset 2 redis (integer) 1 redis 127.0.0.1:6379> zadd myzset 0 mongodb (integer) 1 redis 127.0.0.1:6379> zadd myzset 1 rabitmq (integer) 1 redis 127.0.0.1:6379> zadd myzset 0 rabitmq (integer) 0 redis 127.0.0.1:6379> > ZRANGEBYSCORE myzset 0 1000 1) "mongodb" 2) "rabitmq" 3) "redis"
Redis 服务器命令
就如同上面所示,使用 Redis 客户端连接上 Redis 服务器之后,就可以执行相应的命令来操作 Redis 数据库了。
Redis 键(Key)命令
Redis 键命令用于管理 Redis 的键。
下面简单罗列了些键相关的基本命令
命令 | 描述 |
DEL key | 该命令用于在 key 存在时删除 key |
EXISTS key | 检查给定 key 是否存在 |
EXPIRE key seconds | 为给定 key 设置过期时间,以秒计 |
EXPIREAT key timestamp | EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp) |
TYPE key | 返回 key 所储存的值的类型 |
TTL key | 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live) |
RANDOMKEY | 从当前数据库中随机返回一个 key |
Redis 字符串(String) 命令
Redis 字符串数据类型的相关命令用于管理 Redis 字符串值。
下面简单罗列了些字符串相关的基本命令
命令 | 描述 |
SET key value | 设置指定 key 的值 |
GET key | 获取指定 key 的值 |
GETRANGE key start end | 返回 key 中字符串值的子字符 |
SETNX key value | 只有在 key 不存在时设置 key 的值 |
SETEX key seconds value | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位) |
STRLEN key | 返回 key 所储存的字符串值的长度 |
对于其他数据类型的命令,可以自行查看官方文档哈。
Redis 发布订阅
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 发布订阅命令
命令 | 描述 |
PSUBSCRIBE pattern [pattern …] | 订阅一个或多个符合给定模式的频道 |
PUBSUB subcommand [argument [argument …]] | 查看订阅与发布系统状态 |
PUBLISH channel message | 将信息发送到指定的频道 |
PUNSUBSCRIBE [pattern [pattern …]] | 退订所有给定模式的频道 |
SUBSCRIBE channel [channel …] | 订阅给定的一个或多个频道的信息 |
UNSUBSCRIBE [channel [channel …]] | 只退订给定的频道 |
Python 操作 Redis
如果现在没有 Redis 服务器,那么可以尝试用用 redislabs 这个在线免费服务器,只需要注册一个账号,就可以免费使用一个低配置的 Redis 服务器,挺方便的。
我这里就申请了一个:
下面使用 pip 来安装 Python 操作 Redis 的库
pip install redis
先简单的连接 Redis 服务器并设置一个 Key 来试试
import redis r = redis.Redis(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143, password='that is a secrty') r.set('name', 'zhangsan') # 添加 Key print(r.get('name')) # 获取 Key 的值
如果不出意外,在控制台就会打印 zhangsan 这个字符串啦。
下面我们主要来看看发布订阅的操作
在 sub_redis.py 文件中写入如下代码:
import redis if __name__ == "__main__": conn = redis.Redis(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143, password='that is a secrty') ps = conn.pubsub() ps.subscribe('chat') # 从 chat 订阅消息 for item in ps.listen(): # 监听状态:有消息发布了就拿过来 if item['type'] == 'message': print(item['channel']) print(item['data'])
运行 sub_redis.py 脚本,监听订阅的 channel
在文件 publish_redis.py 中写入如下代码:
import redis if __name__ == "__main__": number_list = ['300033', '300032', '300031', '300030'] signal = ['1', '-1', '1', '-1'] conn = redis.Redis(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143, password='that is a secrty') for i in range(len(number_list)): value_new = str(number_list[i]) + ' ' + str(signal[i]) conn.publish("chat", value_new)
每次执行 publish_redis.py 文件时,sub_redis.py 脚本的控制台都会输出接收到的信息
b'chat' b'Hello World' b'chat' b'300033 1' b'chat' b'300032 -1'