「Redis」redis简介、安装、数据结构的介绍
Redis简介
Redis 是一个速度非常快的非关系型数据库(non-relational database),它可以存储键(key)和五种不同类型的值(value)之间的映射(mapping),可基于内存存储亦可持久化到硬盘的日志型,Key-Value 数据库。
Redis与其他数据库的对比
Redis 属于 NoSQL,它不使用表,也不会预定义数据模式或强制用户对 Redis 的各种数据进行关联。
NoSQL(Not Only SQL)
意指“不仅仅是SQL”,其泛指非关系型数据库,主要分为四类:键值(Key-Value)存储数据库,列存储数据库,文档型数据库,图形(Graph)数据库。
Redis 也经常与高性能键值缓存服务器 memcached 做比较:两者均可用于存储键值映射,性能相差也甚少,但 Redis 能存储除普通字符串值之外的四种数据结构,而 memcached 只能存储普通的字符串值。
这些不同使得 Redis 能够解决更为广泛的问题,而且既能作为主数据库使用,也可以作为辅助数据库使用。
我们通过一张表来对比常用的数据库与缓存服务器:
名称 | 类型 | 数据存储选项 | 查询类型 | 附加功能 |
Redis | 基于内存的非关系型数据库 | 字符串、列表、集合、哈希、有序集合 | 针对数据类型有专属命令,另有批量操作和不完全的事务支持 | 发布与订阅、复制、持久化、脚本扩展 |
memcached | 基于内存的键值缓存 | 键值映射 | 创建、读取、更新、删除等 | 多线程支持 |
MySQL | 关系型数据库 | 数据表、视图等 | 查询、插入、更新、删除、内置函数、自定义存储过程等 | 支持 ACID 性质、复制等 |
MongoDB | 基于硬盘的非关系型文档存储数据库 | 无 schema 的 BSON 文档 | 创建、读取、更新、删除、条件查询等 | 复制、分片、空间索引等 |
Redis的特性
由于 Redis 是内存型数据库,在使用之前就要考虑当服务器被关闭时,服务器存储的数据是否能保留。Redis 拥有两种不同形式的持久化方法,都可以用紧凑的格式将数据写入硬盘:
- RDB 持久化
- 在指定的时间间隔内生成数据集的时间点快照
- AOF 持久化
- 记录服务器执行的所有写操作命令
- 新命令会被追加到文件的末尾
- 在服务器启动时,通过重新执行这些命令还原数据集
除此之外,为了扩展 Redis 的读性能,并为 Redis 提供故障转移支持,Redis 实现了主从复制特性:
- 执行复制的从服务器连接主服务器
- 接收主服务器发送的初始副本
- 接收主服务器执行的所有写命令
- 在从服务器上执行所有写命令,实时更新数据库
- 读命令可以向任意一个从服务器发送
Redis安装
linux环境下安装
获取安装make
等构建工具:
sudo apt-get update sudo apt-get install make gcc python-dev
接着需要 从官网下载最新稳定版本的redis源码,解压源码,编译、安装并启动Redis。然后下载并安装Python语言的Redis客户端库
~:$ wget -q http://download.redis.io/releases/redis-5.0.0.tar.gz # 下载 ~:$ tar -xzf redis-5.0.0.tar.gz ~:$ cd redis-5.0.0 ~/redis-5.0.0:$ make # 注意观察安装消息,最后不应该产生任何错误(`Error`) ~/redis-5.0.0:$ sudo make install # 启动 Redis 服务器,注意通过日志确认 Redis 顺利启动 ~/redis-5.0.0:$ redis-server redis.conf
除了上述的启动方式外,还可以通过Redis默认的配置在后台启动
redis-server &
在安装完 Redis
并启动了 redis-server
后,我们可以使用redis-cli
控制台与 Redis
进行交互,其启动方式是在终端中输入:
$ redis-cli
其会默认连接本机 6379
端口启动的 Redis
服务器,接下来你可以使用它来体验 Redis
各种数据结构和其命令的使用。
至于Python语言的Redis客户端,可以通过一个名为setuptools
的辅助包更方便的下载和安装 :
~:$ sudo python -m easy_install redis hiredis
这里的 redis
包为 Python
提供了连接 Redis
的接口,hiredis
包则是可选的,它是一个使用 C 语言编写的高性能Redis
客户端。
Redis数据结构
Redis 的五种数据结构分别是:
- 字符串(
STRING
) - 列表(
LIST
) - 集合(
SET
) - 哈希(
HASH
) - 有序集合(
ZSET
)
ZSET
可以说是Redis特有的数据结构。
结构类型 | 存储的值 |
STRING (字符串 | 字符串、整数或浮点数 |
LIST (列表 | 一个链表,上面的每个节点都是一个字符串 |
SET (集合 | 包含若干个字符串的无序集合,且集合中的元素都是唯一的 |
HASH (哈希 | 包含键值对的无序散列表 |
ZSET (有序集合 | 成员中的字符串与分值的有序映射,其排序由分值决定 |
字符串
STRING
的命令有GET
(获取值)、SET
(设置值)、DEL
(删除值)。
命令格式:
GET key SET key value [expiration EX seconds|PX ,illiseconds] [NX|XX] DEL key [key ...]
案例:
redis-cli 127.0.0.1:6379> set hello redis OK redis-cli 127.0.0.1:6379> get hello "redis" redis-cli 127.0.0.1:6379> del hello (integer) 1 redis-cli 127.0.0.1:6379> get hello # 尝试获取不存在的键时会得到一个 nil (nil)
列表
Redis 中的列表是一个“链表”,所以其操作和大多数的编程语言相似。
主要有LPUSH
、RPUSH
、LPOP
、RPOP
、LRANGE
、LRANGE
方法。
命令格式:
LPUSH key value [value ...] # 将元素推入列表的左侧 RPUSH key value [value ...] # 将元素推入列表的右侧 LPOP key # 从列表的左侧弹出元素 RPOP 右侧弹出 LINDEX key index # 获取指定位置上的元素 下标从0开始 LRANGE key start end # 获取指定范围的全部元素
举例:
redis 127.0.0.1:6379> rpush testlist item (integer) 1 redis 127.0.0.1:6379> rpush testlist item2 (integer) 2 redis 127.0.0.1:6379> rpush testlist item (integer) 3 redis 127.0.0.1:6379> lrange testlist 0 -1 1) "item" 2) "item2" 3) "item" redis 127.0.0.1:6379> lindex testlist 1 "item2" redis 127.0.0.1:6379> lpop testlist "item" redis 127.0.0.1:6379> lrange testlist 0 -1 1) "item2" 2) "item"
上述例子可以看出:在列表中,元素可以重复出现。
集合
集合和列表的区别就在于:列表可以存储多个相同的字符串,而集合通过散列表来保证存储的字符串都是各不相同的(这些散列表只有键,而没有对应的值
集合是无序的。
主要有SADD
、SMEMBER
、SISMEMBER
、SREM
方法。
格式:
# sadd key member [member ...] 添加成功返回(integer) 1,否则返回0 sadd testset string # 添加string元素 # smembers key smembers testset # 返回所有元素 # sismember key member sismember testset string # 判断元素是否存在testset中 # srem key member [member ...] srem testset string # 删除元素 string
举例:
redis 127.0.0.1:6379> sadd testset item (integer) 1 redis 127.0.0.1:6379> sadd testset item2 (integer) 1 redis 127.0.0.1:6379> sadd testset item (integer) 0 redis 127.0.0.1:6379> smembers testset 1) "item" 2) "item2" redis 127.0.0.1:6379> sismember testset item3 (integer) 0 redis 127.0.0.1:6379> sismember testset item (integer) 1 redis 127.0.0.1:6379> srem testset item2 (integer) 1 redis 127.0.0.1:6379> srem testset item2 (integer) 0 redis 127.0.0.1:6379> smembers testset 1) "item"
当集合中包含的元素非常多时,SMEMBERS
命令的执行速度会很慢,所以慎用。
哈希
哈希可以存储多个键值对之间的映射。和字符串一样,哈希存储的值既可以是字符串又可以是数字值,并且可以对数字值进行自增/自减操作。
主要有HSET
、HGETALL
、HGET
、HDEL
方法。
格式:
# hset 插入 field:域名 ,如果不存在则创建,存在则更新 hset key field value # 获取该哈希的所有域-值对 hgetall key # 获取哈希中的某一个域 hget key value # 删除某一个域 hdel key field [field ...]
举例:
redis 127.0.0.1:6379> hset testhash key1 value1 (integer) 1 redis 127.0.0.1:6379> hset testhash key2 value2 (integer) 1 redis 127.0.0.1:6379> hset testhash key1 newvalue (integer) 0 redis 127.0.0.1:6379> hgetall testhash 1) "key1" 2) "newvalue" 3) "key2" 4) "value2" redis 127.0.0.1:6379> hdel testhash key2 (integer) 1 redis 127.0.0.1:6379> hget testhash key1 "newvalue" redis 127.0.0.1:6379> hgetall testhash 1) "key1" 2) "newvalue"
有序集合
有序集合和哈希一样,也是存储键值对。
只是有序集合的键被称为成员(member
),每个成员都是唯一的,有序集合的值则被称为分值(score
),这个分值必须为浮点数。所以有序集合既可以通过成员访问元素,也可以通过分值来排序元素。
主要有ZADD
、ZREM
、ZRANGE
、ZRANGEBYSCORE
方法。
格式:
# 将带有指定分值的成员添加到有序集合中 ZADD key [NX|XX] [CH] [INCR] score member [score member ...] # 根据分值有序排列后的集合获取到指定范围的元素 ZRANGE key start stop [WITHSCORES] # 获取指定分值范围内的元素 ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] # 从有序集合中删除指定成员 ZREM key member [member ...]
举例:
redis 127.0.0.1:6379> zadd testzset 100 member1 (integer) 1 redis 127.0.0.1:6379> zadd testzset 200 member0 (integer) 1 redis 127.0.0.1:6379> zrange testzset 0 -1 withscores 1) "member1" 2) "100" 3) "member0" 4) "200" redis 127.0.0.1:6379> zrangebyscore testzset 0 150 withscores 1) "member1" 2) "100" redis 127.0.0.1:6379> zrem testzset member1 (integer) 1 redis 127.0.0.1:6379> zrange testzset 0 -1 withscores 1) "member0" 2) "200"