Redis简介
Redis是完全开源的,遵守BSD协议,是一个高性能的key-value数据库。
Redis与其他key-value缓存产品有以下三个特点:
-
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
-
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
-
Redis支持数据的备份,即master-slave模式的数据备份
Redis优势
-
性能极高 - Redis能读的速度是110000次/s,写的速度是81000次/s。
-
丰富的数据类型 = Redis支持二进制案例的strings,lists,hashes ,sets及Ordered Sets数据类型操作。
-
原子性 - Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的,多个操作也是支持事物,即原子性,通过MULTI和EXEC指令包起来。
-
丰富的特性 - Redis还支持publish/subscribe,通知,key过期等等特性。
Redis与其他key-value存储有什么不同?
-
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
-
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
Redis数据类型
启动客户端后有时候中文会乱码
要在 redis-cli 后面加上 --raw :redis-cli --raw
后Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
string(字符串)
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
Hash(哈希)
Redis hash是一个键值(key=>value)对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
List(列表)
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
lpush lrange 开始位,结束位。
set(集合)
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1) 。
sadd命令:添加一个string元素到key对应的set集合中,成功返回1,如果元素已经在集合中返回0。
添加元素:sadd 集合名称 元素
查看元素:smembers 集合名称
如果一个元素添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。
zset(sorted set :有序集合)
Redis zset和set一样也是string类型元素的集合,且不允许重复的元素。
不同的是每个元素都会关联一个double类型的分数。Redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的。但是分数(soure)可以重复。
zadd命令:添加元素到集合,元素在集合中存在则更新对应soure
zadd 集合名称 分数 元素
zrangebyscore 集合名称 起始位置 结束位置
Redis命令
启动客户端命令:redis-cli
Redis键相关基本命令:
1 | |
---|---|
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 |
Redis字符串命令:
1 | |
---|---|
2 | |
3 | |
4 | |
5 | |
6 | [MGET key1 |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | [MSET key value |
13 | [MSETNX key value |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 |
Redis hash命令:
1 | [HDEL key field1 |
---|---|
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | [HMGET key field1 |
10 | [HMSET key field1 value1 |
11 | |
12 | |
13 | |
14 |
Redis列表(List)
1 | [BLPOP key1 |
---|---|
2 | [BRPOP key1 |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | [LPUSH key value1 |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | [RPUSH key value1 |
17 |
Redis集合(Set)
1 | [SADD key member1 |
---|---|
2 | |
3 | [SDIFF key1 |
4 | [SDIFFSTORE destination key1 |
5 | [SINTER key1 |
6 | [SINTERSTORE destination key1 |
7 | |
8 | |
9 | |
10 | |
11 | [SRANDMEMBER key |
12 | [SREM key member1 |
13 | [SUNION key1 |
14 | [SUNIONSTORE destination key1 |
15 |
Redis 有序集合(sorted set)
1 | [ZADD key score1 member1 |
---|---|
2 | |
3 | |
4 | |
5 | [ZINTERSTORE destination numkeys key |
6 | |
7 | [ZRANGE key start stop |
8 | [ZRANGEBYLEX key min max |
9 | |
10 | |
11 | [ZREM key member |
12 | |
13 | |
14 | |
15 | [ZREVRANGE key start stop |
16 | [ZREVRANGEBYSCORE key max min |
17 | |
18 | |
19 | [ZUNIONSTORE destination numkeys key |
20 |
Redis HyperLogLog 命令
1 | [PFADD key element |
---|---|
2 | [PFCOUNT key |
3 | [PFMERGE destkey sourcekey |
Redis连接命令
1 | |
---|---|
2 | |
3 | |
4 | |
5 |
Redis 事务
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
-
批量操作在发送 EXEC 命令前被放入队列缓存。
-
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
-
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事物从开始到执行会经历以下三个阶段:
-
开始事物。
-
命令入队。
-
执行事务。
事务的相关命令:
1 | |
---|---|
2 | |
3 | |
4 | |
5 | [WATCH key |
Redis客户端连接
Redis通过监听一个TCP端口或者Unix socket的方式来接收来自客户端的连接,当一个留连接建立后,Redis内部会进行以下一些操作:
-
首先,客户端socket会被设置为非阻塞模式,因为Redis在网络事件处理上采用的是非阻塞多路复用模型
-
然后为这个socket设置TCP_NODELAY属性,禁用Nagle算法
-
然后创建一个可读的文件事件用于监听这个客户端socket的数据发送
客户端命令:
1 | CLIENT LIST | 返回连接到 redis 服务的客户端列表 |
---|---|---|
2 | CLIENT SETNAME | 设置当前连接的名称 |
3 | CLIENT GETNAME | 获取通过 CLIENT SETNAME 命令设置的服务名称 |
4 | CLIENT PAUSE | 挂起客户端连接,指定挂起的时间以毫秒计 |
5 | CLIENT KILL | 关闭客户端连接 |
Redis管道技术
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:
-
客户端向服务端发送一个查询请求,并监听socket返回,通常是以阻塞模式,等待服务端响应。
-
服务端处理命令,并将结果返回给客户端。
Redis管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
管道技术最显著的优势是提高了Redis服务的性能。
Redis分区
分区是分割数据到过个Redis实例的处理过程,因此每个 实例只保存key的一个子集。
分区的优势
-
通过利用多台计算机内存的和值,允许我们构造更大的数据库。
-
通过多核和多台计算机,允许我们扩展计算能力;通过多台计算机和网络适配器,允许我们扩展网络带宽
分区的不足
Redis的一些特性到分区方面表现的不是很好:
-
涉及多个key的操作通常是不被支持的。举例来说话,当两个set映射到不同的Redis实例上时,你就不能对这两个set执行交集操作。
-
涉及多个key的Redis事务不能使用。
-
当使用分区时,数据处理较为复杂,比如你需要处理多个rdb/aof文件,并且从多个实例和主机备份持久化文件。
-
增加或删除容量也比较复杂。Redis集群大多数支持在运行时增加、删除节点的透明数据平衡的能力,但是类似于客户端分区,代理等其他系统则不支持这项特性,然而,一种叫做presharding的技术对此是有帮助的。
分区类型
Redis 有两种类型分区。 假设有4个Redis实例 R0,R1,R2,R3,和类似user:1,user:2这样的表示用户的多个key,对既定的key有多种不同方式来选择这个key存放在哪个实例中。也就是说,有不同的系统来映射某个key到某个Redis服务。
范围分区
最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。
比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对Redis来说并非是好的方法。
另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:
-
用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数。
-
对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。
-