Redis是免费的,遵循BSD协议的一个高性能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的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
BSD协议:
BSD开源协议是一个给于使用者很大*的协议。可以*的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。当你发布使用了BSD协议的代码,或者以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:
- 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
- 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
- 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。
BSD代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销 售,因此是对商业集成很友好的协议。
很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者 二次开发。
事务:
A想要从自己的帐户中转1000块钱到B的帐户里。那个从A开始转帐,到转帐结束的这一个过程,称之为一个事务。在这个事务里,要做如下操作:
- 从A的帐户中减去1000块钱。如果A的帐户原来有3000块钱,现在就变成2000块钱了。
- 在B的帐户里加1000块钱。如果B的帐户如果原来有2000块钱,现在则变成3000块钱了。
如果在A的帐户已经减去了1000块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时B的帐户里还没有增加1000块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到A的帐户还没减1000块的状态,B的帐户的原来的状态。此时A的帐户仍然有3000块,B的帐户仍然有2000块。
我们把这种要么一起成功(A帐户成功减少1000,同时B帐户成功增加1000),要么一起失败(A帐户回到原来状态,B帐户也回到原来状态)的操作叫原子性操作。
如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫==原子性。==
Redis数据类型:
1.String:
string是redis最基本的类型,一个key对应一个value,string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
112.74.60.22:1994> set username 'xxz' ex 10
OK
112.74.60.22:1994> ttl username
(integer) 4
112.74.60.22:1994> get username
(nil)
ex表示保存的最大时间,超过过期时间数据不再被保存
string类型是Redis最基本的数据类型,一个键最大能存储==512MB==。
2.Hash:
Redis hash是一个键值(key=>value)对集合。
Redis hash是一个string类型的field和value的==映射表==,hash特别适合用于存储对象。
==直接存储键值对==
redis> HMSET myhash field1 "Hello" field2 "World"
"OK"
redis> HGET myhash field1
"Hello"
redis> HGET myhash field2
"World"
以上实例中 hash数据类型存储了包含用户脚本信息的用户对象。 实例中我们使用了 Redis HMSET, HGETALL 命令,user:1 为键值。
每个 hash 可以存储 232 -1 键值对(40多亿)。
3.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 10
1) "rabitmq"
2) "mongodb"
3) "redis"
每个列表可存储40多亿
4.Set无序集合:
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)
sadd 命令:
redis 127.0.0.1:6379> sadd mylist redis
(integer) 1
redis 127.0.0.1:6379> sadd mylist mongodb
(integer) 1
redis 127.0.0.1:6379> sadd mylist rabitmq (integer) 1
redis 127.0.0.1:6379> sadd mylist rabitmq (integer) 0
redis 127.0.0.1:6379> smembers mylist
1) "redis"
2) "rabitmq"
3) "mongodb"
集合里面的元素是无法重复的,也是无序的
zset:有序集合
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
redis 127.0.0.1:6379> zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq (integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq (integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000
1) "mongodb"
2) "rabitmq"
3) "redis"
Redis配置:
进入redis.conf,更改端口:port ****
,
bind 192.168.1.100 10.0.0.1
bind 10.7.189.51 本机id地址,通过ipconfig查看
requirepass ****** 端口设置密码
启动redis服务:redis-server --port **** &
启动客户端:redis-cli -h ***** -p ****
设置用户密码:进入客户端CONFIG SET requirepass secret_password
,清空密码:CONFIG SET requirepass ''
master: 查看从机:
info replication
redis.conf:bind 0.0.0.0 ****(私网地址)
slave:
成为slave:
redis.conf:slaveof <masterip> <masterport> # 从机,表示是谁的从机
masterauth xxz199439 # 密码
哨兵:sentinel.conf
port 26379
一个master也可以绑定多个哨兵,防止哨兵宕机
成为哨兵:sentinel monitor mymaster 127.0.0.1 6379 1
多个哨兵也只能写1
设置密码:
sentinel auth-pass mymaster xxz199439
mymaster5s内没有响应就判定宕机,选举一个slave当master
sentinel down-after-milliseconds mymaster 5000
判定如果master宕机后3分钟内恢复就会变成slave:
sentinel failover-timeout mymaster 180000
启动哨兵: redis-server sentinel.conf –sentinel
哨兵会自动改写redis.conf配置文件
启动后Running in sentinel mode
负载均衡:在企业里面,一主三从这四台电脑只是一个单独的节点,例如有abcde五个节点,由这五个节点做成一个集群,客户端在链接服务器的时候不会链接到单独的某个节点,而是链接到一个负载均衡,由它通过负载均衡算法分配任务到某个节点上。
redis.Redis(host=’负载均衡的IP地址’),硬件负载均衡:F5/A10,非硬件:Nginx、LVS。为了避免负载均衡单点故障,激活双活Keeplived配置,Keeplived相当于哨兵
publish/subscribe/:
1.发布者:
root@iZwz95n8068u7vek4jhextZ:~/redis-3.0.2# redis-cli -h **** -p ****
112.74.60.22:1994> AUTH *****
OK
112.74.60.22:1994> publish channel 'hello'
(integer) 0
112.74.60.22:1994> publish channel 'hello'
(integer) 1
112.74.60.22:1994> publish channel 'hello'
(integer) 2
112.74.60.22:1994>
在foo频道上发布消息’hello’,下面显示订阅这个频道的客户端有多少个,
结构的 pubsub_channels 属性是一个字典,这个字典就用于保存订阅频道的信息
发布者将储订阅频道的信息通过哈希{key(频道):value(订阅者)}的方式存储在结构的pubsub_channels
中,通过 pubsub_channels
字典, 程序只要检查某个频道是否为字典的键, 就可以知道该频道是否正在被客户端订阅; 只要取出某个键的值, 就可以得到所有订阅该频道的客户端的信息。
2.订阅者:
112.74.60.22:1994> SUBSCRIBE channel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "foo"
3) (integer) 1
1) "message"
2) "channel"
3) "hello"
(integer) 1 表示该客户端只订阅了一个频道,同一个客户端可以接受多个客户端的消息,订阅者将订阅的数据保存在redisServer.pubsub_patterns中。
redisServer.pubsub_patterns 属性是一个链表,链表中保存着所有和模式相关的信息:
struct redisServer {
// ...
list *pubsub_patterns;
// ...
};
链表中的每个节点都包含一个 redis.h/pubsubPattern 结构:
typedef struct pubsubPattern {
redisClient *client;
robj *pattern;
} pubsubPattern;
client 属性保存着订阅模式的客户端,而 pattern 属性则保存着被订阅的模式。
每当调用 PSUBSCRIBE 命令订阅一个模式时, 程序就创建一个包含客户端信息和被订阅模式的 pubsubPattern 结构, 并将该结构添加到 redisServer.pubsub_patterns 链表中。