1.Redis基础

1.1简介

Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的API

他通常被称为数据结构服务器,因为值(value)可以是字符串(String),哈希(Hash),列表(list),集合(sets)和有序集合(sorted sets)等类型。

Redis与其他Key-Value 缓存产品有以下三个特点:

  1. Redis支持数据持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
  2. Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
  3. Redis支持数据的备份,即master-slave模式的数据备份

优势

  1. 性能极高 - Redis能读的速度是110000次/s,写的速度是81000次/s。
  2. 丰富的数据类型 - Redis支持二进制案例的Strings,Lists,Hashes,Sets 及Ordered Sets数据类型操作。
  3. 原子 - Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  4. 丰富的特性 - Redis还支持 publish/subscribe,通知,key过期等等特性。

1.2数据类型

1.2.1 String(字符串)

string 是redis 最基本的类型,你可以理解成与Memcached 一模一样的类型,一个key 对应一个 value。
string类型是二进制安全的。意思是redis的string 可以包含任何数据。比如jpg 图片或者序列化的对象。
string类型是Redis 最基本的数据类型,string 类型最大能存储512MB。

  1. redis 127.0.0.1:6379> SET runoob "laowang"
  2. OK
  3. redis 127.0.0.1:6379> GET runoob
  4. "laowang"

1.2.2 Hash(哈希)

Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象。
每个hash可以存储 2^32 -1 键值对(40多亿)。

  1. redis 127.0.0.1:6379> HMSET runoob field1 "Hello" field2 "World"
  2. "OK"
  3. redis 127.0.0.1:6379> HGET runoob field1
  4. "Hello"
  5. redis 127.0.0.1:6379> HGET runoob field2
  6. "World"

1.2.3 List(列表)

Redis 列表市简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
列表最多可以存储 2^ 32 - 1 元素(4294967295,每个列表可存储40多亿)。

  1. redis 127.0.0.1:6379> lpush runoob redis
  2. (integer) 1
  3. redis 127.0.0.1:6379> lpush runoob mongodb
  4. (integer) 2
  5. redis 127.0.0.1:6379> lpush runoob rabitmq
  6. (integer) 3
  7. redis 127.0.0.1:6379> lrange runoob 0 10
  8. 1) "rabitmq"
  9. 2) "mongodb"
  10. 3) "redis"

1.2.4 Set(集合)

Redis 的 Set 是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

sadd 命令:添加一个string元素到key 对应的set集合中,成功返回1,如果元素已经在集合中返回0

集合中最大的成员数为 2 ^32 - 1(4294967295,每个集合可存储40多亿个成员)。

  1. redis 127.0.0.1:6379> DEL runoob
  2. redis 127.0.0.1:6379> sadd runoob redis
  3. (integer) 1
  4. redis 127.0.0.1:6379> sadd runoob mongodb
  5. (integer) 1
  6. redis 127.0.0.1:6379> sadd runoob rabitmq
  7. (integer) 1
  8. redis 127.0.0.1:6379> sadd runoob rabitmq
  9. (integer) 0
  10. redis 127.0.0.1:6379> smembers runoob
  11. 1) "redis"
  12. 2) "rabitmq"
  13. 3) "mongodb"

1.2.5 zset(sorted set:有序集合)

Redis zset和 set 一样也是string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

zadd命令:添加元素到集合,元素在集合中存在则更新对应的score

  1. redis 127.0.0.1:6379> zadd runoob 0 redis
  2. (integer) 1
  3. redis 127.0.0.1:6379> zadd runoob 0 mongodb
  4. (integer) 1
  5. redis 127.0.0.1:6379> zadd runoob 0 rabitmq
  6. (integer) 1
  7. redis 127.0.0.1:6379> zadd runoob 0 rabitmq
  8. (integer) 0
  9. redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000
  10. 1) "mongodb"
  11. 2) "rabitmq"
  12. 3) "redis"

2.Redis深入:带着问题出发?

2.1如何让你设计一个KV数据库,该如何设计

对于这个问题的思考,将有助于我们从整体架构上去学习Redis。

假设现在我们已经设计好了一个KV数据库,首先如果我们要使用,是不是得有入口,我们是通过动态链接库还是通过网络socket对外提供访问入口,这就涉及到了访问模块。Redis就是通过访问模块访问KV数据库之后,我们的数据存储在哪里?为了保证访问的高性能,我们选择存储在内存中,这又需要有存储模块。存在内存中的数据,虽然访问速度快,但存在的问题就是断电后,无法恢复数据,所以我们还需要支持持久化操作。

有了存储模块,我们还需要考虑,数据是以什么样的形式存储?怎样设计才能让数据操作更优,这就涉及到了,数据类型的支持,索引模块。索引的作用是让键值数据库根据key找到相应的value 的存储位置,进而执行操作。

有了以上模块的