redis(Remote Dictionary Server)是一个由Salvatore Sanfilippo写的key-value存储系统,属于nosql的一种。Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String),哈希(Map),列表(list),集合(sets)和 有序集合(sorted sets)等类型。
String:字符串类型是redis中的最基本的类型
Hash:hash类型存储的数据分为三个部分,键key、字段field、值value
结构类似于:{stu:{name laowang age 20 sex man}}
List:类似于python中的列表,其中存储的值是可以重复出现的。
0、lrange:返回存储在 key 的list里指定范围内的元素。 start 和 end 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1。偏移量也可以是负数,表示偏移量是从list尾部开始计数。 例如, -1 表示列表的最后一个元素,-2 是倒数第二个,以此类推。
1、lpush和rpush
lpush:将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么会创建一个空的列表然后再进行 push 操作。 当 key 保存的不是一个列表,那么会返回一个错误。
rpush:向存于 key 的列表的尾部插入所有指定的值。如果 key 不存在,那么会创建一个空的列表然后再进行 push 操作。 当 key 保存的不是一个列表,那么会返回一个错误。
2、lpop和rpop
lpop:移除并返回可以对应的list的第一个元素。当key不存在时返回nil
rpop:移除并返回key对应的列表的最后一个元素。当key不存在时返回nil
3、blpop:阻塞式列表的弹出原语。 它是命令 LPOP 的阻塞版本,这是因为当给定列表内没有任何元素可供弹出的时候, 连接将被 BLPOP 命令阻塞。 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。
4、brpop:BRPOP 和 BLPOP 基本是完全一样的,除了它们一个是从尾部弹出元素,而另一个是从头部弹出元素。
5、lindex:返回元素的索引 index 在key对应的list中存储的具体内容。 下标是从0开始索引的,所以 0 是表示第一个元素, 1 表示第二个元素,并以此类推。 负数索引用于指定从列表尾部开始索引的元素。在这种方法下,-1 表示最后一个元素,-2 表示倒数第二个元素,并以此往前推。当 key 位置的值不是一个列表的时候,会返回一个error。
6、LINSERT key BEFORE|AFTER pivot value:把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。当 key 不存在时,这个list会被看作是空list,任何操作都不会发生。当 key 存在,但保存的不是一个list的时候,会返回error。
7、llen:返回存储在 key 里的list的长度。 如果 key 不存在,那么就被看作是空list,并且返回长度为 0。 当存储在 key 里的值不是一个list的话,会返回error。
8、lpushx和rpushx:只有当 key 已经存在并且存着一个 list 的时候,在这个 key 下面的 list 的头部或尾部插入 value。 与 LPUSH 相反,当 key 不存在的时候不会进行任何操作。
9、lrem:从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作:
count > 0: 从头往尾移除值为 value 的元素。
count < 0: 从尾往头移除值为 value 的元素。
count = 0: 移除所有值为 value 的元素。
10、LSET key index value:设置 index 位置的list元素的值为 value。当index超出范围时会返回一个error。
11、LTRIM key start stop:只保留key对应的list中从start到stop的元素,其余元素全部剪切掉。
Set:类似于python中的set集合,存储的的数据不可重复出现,但不保证顺序
0、smembers:返回key集合的所有元素。
1、sadd:添加一个或多个指定的member元素到集合的 key中.指定的一个或者多个元素member 如果已经在集合key中存在则忽略.如果集合key 不存在,则新建集合key,并添加member元素到集合key中.如果key 的类型不是集合则返回错误.
2、scard:集合的基数(元素的数量),如果key不存在,则返回 0.
3、sdiff:返回一个集合与给定集合的差集元素。注意这里是有顺序的,比如sdiff myset2 myset3 ,会返回在myset2中有,而myset3中没有的元素,sdiff myset3 myset2 则会返回myset3中有而myset2中没有的元素,交换顺序得到的结果是不一样的。
4、sdiffstore destination key1 key2 ....:与sdiff类似,不同之处在于会将key1和key2的差集结果放在destination中,如果destination已经存在, 则将其覆盖重写。
5、sinter:返回指定所有的集合的成员的交集.。
6、sinterstore destination key [key ...]:与sinter类似,不同之处在于会将key1和key2的交集结果放在destination中,如果destination已经存在, 则将其覆盖重写。
7、sismember:返回成员 member 是否是存储的集合 key的成员。
8、smove source destination member:将member从source集合移动到destination集合中.。如果source 集合不存在或者不包含指定的元素,这smove命令不执行任何操作并且返回0。否则对象将会从source集合中移除,并添加到destination集合中去,如果destination集合已经存在该元素,则smove命令仅将该元素充source集合中移除.。如果source 和destination不是集合类型,则返回错误。相当于从source中剪切指定元素,再粘贴到destination中,如果destination中已经存在了,则只会保留一个。
9、srandmember key [count]:随机返回key集合中的特定个数的元素。
如果count是整数且小于集合中元素个数,返回含有 count 个不同的元素的数组;
如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素;
当count是负数,则会返回一个包含count的绝对值的个数元素的数组,如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况。
10、srem:在key集合中移除指定的元素. 如果指定的元素不是key集合中的元素则忽略 如果key集合不存在则被视为一个空的集合,该命令返回0。如果key的类型不是一个集合,则返回错误.
11、scan:scan命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程。当scan命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。
12、sunion:返回给定的多个集合的并集中的所有成员。
13、sunionstore destination key [key ...]:与sunion类似,不同之处在于会将key1和key2的并集结果放在destination中,如果destination已经存在, 则将其覆盖重写。
Sorted Set:在集合的基础上加入score控制存储顺序
1、zadd:将所有指定成员添加到键为key有序集合(sorted set)里面。 添加时可以指定多个分数/成员(score/member)对。
如果指定添加的成员已经是有序集合里面的成员,则会更新改成员的分数(scrore)并更新到正确的排序位置;
如果key不存在,将会创建一个新的有序集合(sorted set)并将分数/成员(score/member)对添加到有序集合,就像原来存在一个空的有序集合一样;
如果key存在,但是类型不是有序集合,将会返回一个错误应答。
分数值是一个双精度的浮点型数字字符串。+inf和-inf都是有效值。
zset的操作跟之前的list,set,string等的操作相似,这里不再具体列举。
发布订阅
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
主从复制:
redis中也有类似于mongodb中的主从复制机制,一个master可以拥有多个slave,一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构。比如,将ip为192.168.1.10的机器作为主服务器,将ip为192.168.1.11的机器作为从服务器
下面模拟一下redis中的主从复制:
第一步:建立文件环境:
node1:port 6001 master
node2:port 6002 slave
node3:port 6003 slave
第二步:修改配置文件(数据库位置,日志文件位置,端口号,从机要设置slaveof,如果有安全验证需设置免密登录,)
port ****
dir /home/yuxiuxiu/node1/db/
logfile /home/yuxiuxiu/node1/log/redis.log
第三步:实现哨兵监听:
redis中没有像mongodb中那样的直接的在集群中检测主机宕机并自动选举新的主机的机制,要想实现检测主机的运行状态,在主机宕机的时候产生新的主机,需要借助sentinel机制,它是一种哨兵监听机制,需要我们另外配置文件来手动执行,实际上在现实工作中,哨兵可能有很多个,当一定数量的哨兵同时检测到直接宕机,才会采取行动产生新的主机,另一方面也防止sentinel哨兵出现宕机的情况。这里我们设置两个哨兵来协同工作,下面先来配置一下sentinel文件:
两个哨兵的配置文件只需保证端口号不同。
先运行三个服务器,再运行哨兵:
运行三个服务器:
sudo redis-server ./node1/redis.conf
sudo redis-server ./node2/redis.conf
sudo redis-server ./node3/redis.conf
再f分别运行两个哨兵:
sudo redis-server ./sentinel.conf --sentinel
再来连接三个客服端,我们看到主机正常运行,可以get和set,两个从机只可以get,不可以set:
我们可以看到两个哨兵同时监听了主机的6001端口:
现在我们把主机kill掉:
看到哨兵自动更换了监听对象,原本不可以进行set操作的服务器,在成为新的主机之后,可以进行set操作,端口号为6003的从机依然无法进行set操作:
这里需要说明的是,主机宕机时,sentinel机制会自动修改其配置文件,在原来的主机修复之后,原来的这个主机并不会夺回主机的地位。
与python交互
当我们用Redis和StrictRedis创建连接时,其实内部实现并没有主动给我创建一个连接,我们获得的连接是连接池提供的连接,这个连接由连接池管理,所以我们无需关注连接是否需要主动释放关闭的问题。另外连接池有自己的关闭连接的接口,一旦调用该接口,所有连接都将被关闭,连接池的操作不需要程序员管理,系统redis模块自动管理好了。
具体函数参照: