Redis

Posted coolpale

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis相关的知识,希望对你有一定的参考价值。

第1章 redis缓存技术

 

1.1 Redis的定义

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010315日起,Redis的开发工作由VMware主持。从20135月开始,Redis的开发由Pivotal赞助。

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)list(链表)set(集合)zset(sorted set --有序集合)hash(哈希类型)。这些数据类型都支持push/popadd/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了JavaC/C++C#phpjavascriptPerlObject-CPythonRubyErlang等客户端,使用很方便。[1]

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

1.2 数据结构

redis提供五种数据类型:stringhashlistsetzset(sorted set)

1.2.1 string(字符串)

string是最简单的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。

redis采用结构sdshdrsds封装了字符串,字符串相关的操作实现在源文件sds.h/sds.c中。

数据结构定义如下:

typedefchar*sds;

structsdshdr{

longlen;

longfree;

charbuf[];

};

1.2.2 list(双向链表)

list是一个链表结构,主要功能是pushpop、获取一个范围的所有值等等。操作中key理解为链表的名字。

list的定义和实现在源文件adlist.h/adlist.c,相关的数据结构定义如下:

//list迭代器

typedefstructlistIter{

listNode*next;

intdirection;

}listIter;

//list数据结构

typedefstructlist{

listNode*head;

listNode*tail;

void*(*dup)(void*ptr);

void(*free)(void*ptr);

int(*match)(void*ptr,void*key);

unsignedintlen;

listIteriter;

}list;

1.2.3 dict(hash)

set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。

在源文件dict.h/dict.c中实现了hashtable的操作,数据结构的定义如下:

//dict中的元素项

typedefstructdictEntry{

void*key;

void*val;

structdictEntry*next;

}dictEntry;

//dict相关配置函数

typedefstructdictType{

unsignedint(*hashFunction)(constvoid*key);

void*(*keyDup)(void*privdata,constvoid*key);

void*(*valDup)(void*privdata,constvoid*obj);

int(*keyCompare)(void*privdata,constvoid*key1,constvoid*key2);

void(*keyDestructor)(void*privdata,void*key);

void(*valDestructor)(void*privdata,void*obj);

}dictType;

//dict定义

typedefstructdict{

dictEntry**table;

dictType*type;

unsignedlongsize;

unsignedlongsizemask;

unsignedlongused;

void*privdata;

}dict;

//dict迭代器

typedefstructdictIterator{

dict*ht;

intindex;

dictEntry*entry,*nextEntry;

}dictIterator;

dicttabledictEntry指针的数组,数组中每个成员为hash值相同元素的单向链表。set是在dict的基础上实现的,指定了key的比较函数为dictEncObjKeyCompare,若key相等则不再插入。

 

 

1.2.4 zset(排序set)

zsetset的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。

typedefstructzskiplistNode{

structzskiplistNode**forward;

structzskiplistNode*backward;

doublescore;

robj*obj;

}zskiplistNode;

typedefstructzskiplist{

structzskiplistNode*header,*tail;

unsignedlonglength;

intlevel;

}zskiplist;

typedefstructzset{

dict*dict;

zskiplist*zsl;

}zset;

zset利用dict维护key -> value的映射关系,用zsl(zskiplist)保存value的有序关系。zsl实际是叉数

不稳定的多叉树,每条链上的元素从根节点到叶子节点保持升序排序。

1.3 存储

redis使用了两种文件格式:全量数据和增量请求。

全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载;

增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行replay得到数据,序列化的操作包括SETRPUSHSADDZADD

redis的存储分为内存存储、磁盘存储和log文件三部分,配置文件中有三个参数对其进行配置。

save seconds updatessave配置,指出在多长时间内,有多少次更新操作,就将数据同步到数据文件。这个可以多个条件配合,比如默认配置文件中的设置,就设置了三个条件。

appendonly yes/no appendonly配置,指出是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面的save条件来同步的,所以有的数据会在一段时间内只存在于内存中。

appendfsync no/always/everysec appendfsync配置,no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次。

1.4 redismemcache的区别

Redis Memcache 都是基于内存的数据存储系统。Memcached是高性能分布式内存缓存服务;Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串、哈希 表、链表、等数据类型的相关操作。

1.4.1 数据操作不同

Redis支持服务器端的数据操作Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached

1.4.2 性能不同

性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

1、数据类型支持不同与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多。最为常用的数据类型主要由五种:StringHashListSetSorted Set

2、内存管理机制不同在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。

3、数据持久化支持Redis虽然是基于内存的存储系统,但是它本身是支持内存数据的持久化的,而且提供两种主要的持久化策略:RDB快照和AOF日志。而memcached是不支持数据持久化操作的。

4、集群管理的不同Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。Memcached本身并不支持分布式,只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能。

1.5 Redis安装部署3.2.10

wget   http://download.redis.io/releases/redis-3.2.10.tar.gz

上传至/usr/local

tar xzf  redis-3.2.10.tar.gz

mv  redis-3.2.10 redis

安装:

cd  redis

make

 

首先要设置环境变量,这里我们在.bash_profile中设置环境变量

[[email protected] ~]# cat .bash_profile

插入

export PATH=$PATH:/usr/local/redis/srcsrc/redis-server

 

source .bash_profile

启动:

src/redis-server

 

客户端连接测试:

src/redis-cli

redis> set foo bar

redis> get foo

 

 

vim /etc/redis/redis.conf

daemonize  yes

port 6379

appendonly  yes

logfile /var/log/redis.log

dbfilename dump.rdb

 

 

 

是否后台运行

默认端口

AOF日志开关是否打开

日志文件位置

RDB持久化数据文件

 

 

 

安全验证

 

bind 10.0.0.52

requirepass root

 

配置完成需要重启redis

开启以上验证,需要以下命令登录

redis-cli  -a root  -h 10.0.0.52 -p 6379

 

或者

 

redis-cli    -h 10.0.0.52 -p 6379

redis-cli> auth root

 

redis-cli -h 10.0.0.52  -a root shutdown

 

在线修改配置(不会修改配置文件,重启会失效):

 

 

redis启动脚本

redis

cp redis /etc/init.d/

chmod +x /etc/init.d/redis

service  redis status

 

1.6 Redis持久化设置

1.6.1 RDB*****

基础配置:

mkdir /data/redis

 

vim /etc/redis/redis.conf

save 900 1

save 300 10

save 60 10000

dbfilename dump.rdb

dir  /data/redis

 

扩展参数:

stop-writes-on-bgsave-error yes

rdbcompression  yes

rdbchecksum   yes

 

配置介绍如下:

 

 

 

900秒(15分钟)内有1个更改

300秒(5分钟)内有10个更改

60秒内有10000个更改

导出来的rdb文件名

rdb的放置路径

 

配置介绍如下:

后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致

导出的rdb文件是否压缩如果rdb的大小很大的话建议这么做

导入rbd恢复时数据时,要不要检验rdb的完整性验证版本是不是一致

 

1.6.2 AOF持久化配置***

 

基础配置:

appendonly yes/no

appendfsync always

或者

appendfsync everysec

或者

appendfsync no

 

扩展配置:

no-appendfsync-on-rewrite yes/no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

 

以上配置含义:

是否打开aof日志功能

1个命令,都立即同步到aof

 

每秒写1

 

写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof.

 

以上配置含义:

正在导出rdb快照的过程中,要不要停止同步aof

aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次。

aof文件,至少超过64M,重写

 

 

1.6.3 redis备份就是备份rdb持久化文件。

 

1.7 慢日志**

slowlog-log-slower-than 10000

*CONFIG SET slowlog-log-slower-than 100

*CONFIG SET slowlog-max-len?1000

CONFIG GET slow*

*SLOWLOG GET

SLOWLOG RESET

 

超过多少微秒

保存多少条慢日志

1.8 主从复制*****

搭建过程:

环境:

准备两个或两个以上redis实例

mkdir  -p  /data/{6380..6382}

 

vim /data/6380/redis.conf

port 6380

daemonize yes

pidfile /data/6380/redis.pid

loglevel notice

logfile "/data/6380/redis.log"

dbfilename dump.rdb

dir /data/6380

 

配置63816382节点

cp /data/6380/redis.conf   /data/6381/redis.conf

cp /data/6380/redis.conf   /data/6382/redis.conf

sed -i "s#6380#6381#g"  /data/6381/redis.conf

sed -i "s#6380#6382#g"  /data/6382/redis.conf

 

启动节点:

redis-server /data/6380/redis.conf

redis-server /data/6381/redis.conf

redis-server /data/6382/redis.conf

 

主从要求:

主节点:6380

从节点:63816382

 

开启主从:

登入63816382,命令行:

[[email protected] tmp]# redis-cli -p 6381

127.0.0.1:6381> SLAVEOF 127.0.0.1 6380

OK

[[email protected] tmp]# redis-cli -p 6382

127.0.0.1:6382> SLAVEOF 127.0.0.1 6380

OK

通过执行 SLAVEOF host port 命令,可以将当前服务器转变为指定服务器的从属服务器(slave server)

如果当前服务器已经是某个主服务器(master server)的从属服务器,那么执行 SLAVEOF host port 将使当前服务器停止对旧主服务器的同步,丢弃旧数据集,转而开始对新主服务器进行同步。

 

主从复制状态监控:

[[email protected] tmp]# redis-cli -p 6380

127.0.0.1:6380> info replication

# Replication

role:master

connected_slaves:2

slave0:ip=127.0.0.1,port=6381,state=online,offset=29,lag=1

slave1:ip=127.0.0.1,port=6382,state=online,offset=29,lag=0

master_repl_offset:29

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:2

repl_backlog_histlen:28

 

主从切换:

模拟故障:

停掉主节点

[[email protected] tmp]# redis-cli -p 6380

127.0.0.1:6380> shutdown

not connected>

从节点设置

[[email protected] tmp]# redis-cli -p 6381

127.0.0.1:6381> slaveof no one

OK

对一个从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。

利用『 SLAVEOF NO ONE 不会丢弃同步所得数据集』这个特性,可以在主服务器失败的时候,将从属服务器用作新的主服务器,从而实现无间断运行。

[[email protected] tmp]# redis-cli -p 6382

127.0.0.1:6382> slaveof 127.0.0.1 6381

OK

127.0.0.1:6382>

[[email protected] tmp]# redis-cli -p 6381

127.0.0.1:6381> info replication

# Replication

role:master

connected_slaves:1

slave0:ip=127.0.0.1,port=6382,state=online,offset=29,lag=0

master_repl_offset:29

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:2

repl_backlog_histlen:28

 

第2章 Redis Sentinel 主从复制故障自动转移

2.1  Sentinel介绍

2.1.1 主从复制的问题

Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:

 

一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。

扩展主节点的读能力,分担主节点读压力。

但是问题来了:

一旦主节点宕机,从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。

主节点的写能力受到单机的限制。

主节点的存储能力受到单机的限制。

第一个问题,我们接下来讲的Sentinel就可以解决。而后两个问题,Redis也给出了方案Redis Cluster

2.1.2 Redis Sentinel的高可用

Redis Sentinel是一个分布式架构,包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当发现节点不可达时,会对节点做下线标识。

如果被标识的是主节点,他还会选择和其他Sentinel节点进行协商,当大多数的Sentinel节点都认为主节点不可达时,他们会选举出一个Sentinel节点来完成自动故障转移工作,同时将这个变化通知给Redis应用方。

整个过程完全自动,不需要人工介入,所以可以很好解决Redis的高可用问题。

 

2.2 Sentinel部署

首先要把第一章1.8主从复制环境准备好,然后在部署Sentinel

 

mkdir /data/26380

 

配置文件内容:

vim /data/26380/sentinel.conf

port 26380

dir "/data/26380/"

logfile "26380.log"

sentinel monitor mymaster 127.0.0.1 6380 1

sentinel down-after-milliseconds mymaster 60000

 

 

注:sentinel monitor mymaster 127.0.0.1 6380 1设置为要跟从节点得数量有关,在生产中根据实际情况设置,如果从节点有3个建议设置成2,如果从节点有2个建议设置为1.

 

启动

redis-sentinel /data/26380/sertinel.conf &

 

登入:

redis-cli -p 26380

 

配置文件详解:

dir /var/redis/data/

logfile "26380.log"

//日志文件目录及名称

 

sentinel monitor mymaster 127.0.0.1 6380 2

// 当前Sentinel节点监控 127.0.0.1:6380 这个主节点

// 2代表判断主节点失败至少需要2Sentinel节点节点同意

// mymaster是主节点的别名

 

sentinel down-after-milliseconds mymaster 30000

//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达  30

 

sentinel parallel-syncs mymaster 1

//Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1

 

sentinel failover-timeout mymaster 180000

//故障转移超时时间为180000毫秒=180

 

sentinel auth-pass \ \ 

如果Sentinel监控的主节点配置了密码,可以通过sentinel auth-pass配置通过添加主节点的密码,防止Sentinel节点无法对主节点进行监控。

例如:sentinel auth-pass mymaster MySUPER--secret-0123passw0rd

 

sentinel notification-script \ \ 

在故障转移期间,当一些警告级别的Sentinel事件发生(指重要事件,如主观下线,客观下线等)时,会触发对应路径的脚本,想脚本发送相应的事件参数。

例如:sentinel notification-script mymaster /var/redis/notify.sh

 

sentinel client-reconfig-script \ \

在故障转移结束后,触发应对路径的脚本,并向脚本发送故障转移结果的参数。

例如:sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

2.2.1 故障切换转移

停掉主节点服务:

[[email protected] tmp]# redis-cli -p 6380

127.0.0.1:6380> shutdown

not connected>

 

查看6381,显示主节点指向6382

[[email protected] tmp]# redis-cli -p 6381

127.0.0.1:6381> INFO replication

# Replication

role:slave

master_host:127.0.0.1

master_port:6382

master_link_status:up

 

[[email protected] tmp]# redis-cli -p 6382

127.0.0.1:6382> INFO replication

# Replication

role:master

connected_slaves:1

slave0:ip=127.0.0.1,port=6381,state=online,offset=13058,lag=1

master_repl_offset:13058

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:2

repl_backlog_histlen:13057

 

6380服务恢复正常后会自动指向6382

开启6380服务:

[[email protected] tmp]# redis-server /data/6380/redis.conf

[[email protected] tmp]# redis-cli -p 6380

127.0.0.1:6380> INFO replication

# Replication

role:slave

master_host:127.0.0.1

master_port:6382

master_link_status:up

********省略若干行******

 

 

2.3 总结:

从上面的故障转移试验中,可以看出Redis Sentinel的以下几个功能。

监控:Sentinel节点会定期检测Redis数据节点和其余Sentinel节点是否可达。

通知:Sentinel节点会将故障转移通知给应用方。

主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系。

配置提供者:在Redis Sentinel结构中,客户端在初始化的时候连接的是Sentinel节点集合,从中获取主节点信息。

 

2.4 sentinel管理命令***

 

PING :返回 PONG

SENTINEL masters :列出所有被监视的主服务器

SENTINEL slaves <master name>

SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。

SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。

SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。

 

 

第3章 Redis分片技术

分片(Patitioning)就是将数据拆分到多个redis实例的过程,这样每个Redis实例将只包含完整数据的一部分。

3.1 Redis分片部署

EPEL源安装ruby支持

yum  install ruby rubygems -y

使用国内源

gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/

或者使用阿里源

gem sources -a http://mirrors.aliyun.com/rubygems/ 

gem sources --remove http://rubygems.org/

 

gem install redis -v 3.3.3

gem sources -l

 

创建目录

mkdir -p /data/{7000..7005}

 

创建配置文件:

vim /data/7000/redis.conf

 

port 7000

daemonize yes

pidfile /data/7000/redis.pid

loglevel notice

logfile "/data/7000/redis.log"

dbfilename dump.rdb

dir /data/7000

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

 

cp /data/7000/redis.conf  /data/7001/

cp /data/7000/redis.conf  /data/7002/

cp /data/7000/redis.conf  /data/7003/

cp /data/7000/redis.conf  /data/7004/

cp /data/7000/redis.conf  /data/7005/

sed -i "s#7000#7001#g"  /data/7001/redis.conf

sed -i "s#7000#7002#g"  /data/7002/redis.conf

sed -i "s#7000#7003#g"  /data/7003/redis.conf

sed -i "s#7000#7004#g"  /data/7004/redis.conf

sed -i "s#7000#7005#g"  /data/7005/redis.conf

 

启动所有节点

redis-server /data/7000/redis.conf

redis-server /data/7001/redis.conf

redis-server /data/7002/redis.conf

redis-server /data/7003/redis.conf

redis-server /data/7004/redis.conf

redis-server /data/7005/redis.conf

 

查看进程:

[[email protected] data]# ps -ef |grep redis

root       1552      1  0 18:37 ?        00:00:08 redis-server *:6381               

root       1558      1  0 18:37 ?        00:00:08 redis-server *:6382               

root       1883   1503  0 19:30 pts/0    00:00:08 redis-sentinel *:26380 [sentinel]       

root       1909      1  0 19:47 ?        00:00:02 redis-server *:6380               

root       1959      1  0 20:20 ?        00:00:00 redis-server *:7000 [cluster]     

root       1961      1  0 20:20 ?        00:00:00 redis-server *:7001 [cluster]     

root       1963      1  0 20:20 ?        00:00:00 redis-server *:7002 [cluster]     

root       1969      1  0 20:20 ?        00:00:00 redis-server *:7003 [cluster]     

root       1973      1  0 20:20 ?        00:00:00 redis-server *:7004 [cluster]     

root       1979      1  0 20:20 ?        00:00:00 redis-server *:7005 [cluster]     

root       1985   1503  0 20:20 pts/0    00:00:00 grep redis

 

 

redis-trib.rb用法:

[[email protected] ~]# redis-trib.rb

Usage: redis-trib <command> <options> <arguments ...>

 

  rebalance       host:port

                  --threshold <arg>

                  --pipeline <arg>

                  --simulate

                  --weight <arg>

                  --timeout <arg>

                  --use-empty-masters

                  --auto-weights

  call            host:port command arg arg .. arg

  reshard         host:port

                  --to <arg>

                  --pipeline <arg>

                  --from <arg>

                  --timeout <arg>

                  --yes

                  --slots <arg>

  create          host1:port1 ... hostN:portN

                  --replicas <arg>

  info            host:port

  help            (show this help)

  set-timeout     host:port milliseconds

  del-node        host:port node_id

  check           host:port

  add-node        new_host:new_port existing_host:existing_port

                  --slave

                  --master-id <arg>

  import          host:port

                  --copy

                  --from <arg>

                  --replace

  fix             host:port

                  --timeout <arg>

 

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

 

 

 

节点加入集群

[[email protected] data]# redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

create //表示创建集群功能

--replicas 1 //表示为每个主节点自动分配一个从节点.也就是自动分配三个主节点和三个从节点.

 

>>> Creating cluster

>>> Performing hash slots allocation on 6 nodes...

Using 3 masters:

127.0.0.1:7000

127.0.0.1:7001

127.0.0.1:7002

Adding replica 127.0.0.1:7003 to 127.0.0.1:7000

Adding replica 127.0.0.1:7004 to 127.0.0.1:7001

Adding replica 127.0.0.1:7005 to 127.0.0.1:7002

M: 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000

   slots:0-5460 (5461 slots) master

M: c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001

   slots:5461-10922 (5462 slots) master

M: dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002

   slots:10923-16383 (5461 slots) master

S: ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003

   replicates 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82

S: 43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004

   replicates c23746303396947204e49c38d7f3d52ade36f2f3

S: a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005

   replicates dc695ac6c7213817c6d00a5389ee9cd4be48ef1f

Can I set the above configuration? (type ‘yes‘ to accept): yes

我能设置上面的配置吗?

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join....

>>> Performing Cluster Check (using node 127.0.0.1:7000)

M: 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000

   slots:0-5460 (5461 slots) master

   1 additional replica(s)

M: dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002

   slots:10923-16383 (5461 slots) master

   1 additional replica(s)

M: c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001

   slots:5461-10922 (5462 slots) master

   1 additional replica(s)

S: a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005

   slots: (0 slots) slave

   replicates dc695ac6c7213817c6d00a5389ee9cd4be48ef1f

S: ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003

   slots: (0 slots) slave

   replicates 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82

S: 43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004

   slots: (0 slots) slave

   replicates c23746303396947204e49c38d7f3d52ade36f2f3

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

3.1.1 故障转移

查看cluster状态

[[email protected] ~]# redis-cli -p 7002 cluster nodes

dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002 myself,slave 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 0 0 3 connected

ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003 slave 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 0 1520608359451 13 connected

43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004 slave a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 0 1520608361464 14 connected

9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007 slave c23746303396947204e49c38d7f3d52ade36f2f3 0 1520608360961 15 connected

a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005 master - 0 1520608359953 14 connected 0-5429

c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001 master - 0 1520608360961 15 connected 5430-10729

4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000 master - 0 1520608360457 13 connected 10730-16383

查看进程:

[[email protected] ~]# ps -ef |grep redis

root       1552      1  0 18:37 ?        00:00:18 redis-server *:6381               

root       1558      1  0 18:37 ?        00:00:19 redis-server *:6382               

root       1883      1  0 19:30 ?        00:00:32 redis-sentinel *:26380 [sentinel]       

root       1909      1  0 19:47 ?        00:00:13 redis-server *:6380               

root       1959      1  0 20:20 ?        00:01:08 redis-server *:7000 [cluster]     

root       1961      1  0 20:20 ?        00:01:00 redis-server *:7001 [cluster]     

root       1969      1  0 20:20 ?        00:00:14 redis-server *:7003 [cluster]     

root       1973      1  0 20:20 ?        00:00:15 redis-server *:7004 [cluster]     

root       1979      1  0 20:20 ?        00:01:05 redis-server *:7005 [cluster]     

root       2080      1  0 21:01 ?        00:00:11 redis-server *:7002 [cluster]     

root       2166      1  0 21:28 ?        00:00:10 redis-server *:7007 [cluster]     

root       2315   2007  0 23:17 pts/1    00:00:00 grep redis

kill7000进程号

[[email protected] ~]# kill 1959

 

查看7000停掉后自动切换到7002

[[email protected] ~]# redis-cli -p 7002 cluster nodes

dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002 myself,master - 0 0 16 connected 10730-16383

ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003 slave dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 0 1520608659949 16 connected

43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004 slave a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 0 1520608660958 14 connected

9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007 slave c23746303396947204e49c38d7f3d52ade36f2f3 0 1520608661463 15 connected

a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005 master - 0 1520608659444 14 connected 0-5429

c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001 master - 0 1520608660454 15 connected 5430-10729

4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000 master,fail - 1520608648435 1520608646797 13 disconnected

 

 

3.1.2 增加新的主节点

当集群各个节点扛不住业务的需要时,我们可能需要往集群里添加新的节点以供业务的正常使用,现在介绍如何添加新节点.同上面一样的, 我们先创建两个实例目录,一个实例做为新节点的主实例,一个实例做为新节点的从实例.

创建目录

mkdir -p /data/{7006..7007}

 

创建配置文件:

vim /data/7006/redis.conf

 

port 7006

daemonize yes

pidfile /data/7006/redis.pid

loglevel notice

logfile "/data/7006/redis.log"

dbfilename dump.rdb

dir /data/7006

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

 

cp /data/7006/redis.conf  /data/7007/

sed -i "s#7006#7007#g"  /data/7007/redis.conf

 

启动所有节点

redis-server /data/7006/redis.conf

redis-server /data/7007/redis.conf

 

 

 

7006设置成为主节点:

[[email protected] ~]# redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

127.0.0.1:7000这个IP:PORT可以是集群里边儿任意一个主节点的IP和端口

 

从任何一个主节点里面划分部分slots7006

[[email protected] ~]# redis-trib.rb reshard 127.0.0.1:7006

>>> Performing Cluster Check (using node 127.0.0.1:7006)

********省略若干行*******

How many slots do you want to move (from 1 to 16384)? 要移动多少槽位过去

What is the receiving node ID? 此处填写接收节点ID7006的槽位

Please enter all the source node IDs.

  Type ‘all‘ to use all the nodes as source nodes for the hash slots.

  Type ‘done‘ once you entered all the source nodes IDs.

Source node #1:  此处填写源节点ID号可以指定从那个节点分配槽位给7006,也可以填all。如果填all 回车后直接运行; 如果指定从那个节点输入done点击回车

all //输入all表示从老的所有节点进行重分配,凑够4096slots给到新节点.也可以输入源节点id, 可以输入多个源节点id,最后输入done.就开始从你输入的源节点id的节点进行迁移了.

********省略若干行*******

 yes

 

7007设置成为7006的从节点:

首先要看一下7006从节点的id号:b316e00765983941a2f196710e58bdda3db0a9e1

[[email protected] ~]# redis-cli -p 7007

127.0.0.1:7007> CLUSTER REPLICATE  b316e00765983941a2f196710e58bdda3db0a9e1

OK

[[email protected] ~]# redis-cli -p 7007 cluster nodes

4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000 master - 0 1520604634240 10 connected 0-4095

c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001 master - 0 1520604636255 11 connected 4096-8191

9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007 myself,slave b316e00765983941a2f196710e58bdda3db0a9e1 0 0 1 connected

b316e00765983941a2f196710e58bdda3db0a9e1 127.0.0.1:7006 master - 0 1520604635751 12 connected 8192-12287

a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005 master - 0 1520604635751 9 connected 12288-16383

43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004 slave 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 0 1520604636255 10 connected

dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002 slave a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 0 1520604634742 9 connected

ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003 slave c23746303396947204e49c38d7f3d52ade36f2f3 0 1520604634742 11 connected

 

 

3.1.3 删除节点

要删除集群中的某个节点(:这里说的是集群中的主节点),首先必须确保这个节点没有拥有任何一个slots.我们现在来删除700这个节点.首先,我们要把7006这个节点上的slots全部迁移出去.

[[email protected] ~]#  redis-trib.rb  reshard 127.0.0.1:7006

>>> Performing Cluster Check (using node 127.0.0.1:7006)

M: b316e00765983941a2f196710e58bdda3db0a9e1 127.0.0.1:7006

   slots:8192-12287 (4096 slots) master

   1 additional replica(s)

M: c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001

   slots:4096-8191 (4096 slots) master

   1 additional replica(s)

S: dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002

   slots: (0 slots) slave

   replicates a1c455d0d547dbad70ae29d5b7f68069fd8a43e7

M: 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000

   slots:0-4095 (4096 slots) master

   1 additional replica(s)

S: 9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007

   slots: (0 slots) slave

   replicates b316e00765983941a2f196710e58bdda3db0a9e1

S: 43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004

   slots: (0 slots) slave

   replicates 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82

M: a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005

   slots:12288-16383 (4096 slots) master

   1 additional replica(s)

S: ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003

   slots: (0 slots) slave

   replicates c23746303396947204e49c38d7f3d52ade36f2f3

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

How many slots do you want to move (from 1 to 16384)? 16384

What is the receiving node ID? c23746303396947204e49c38d7f3d52ade36f2f3

Please enter all the source node IDs.

  Type ‘all‘ to use all the nodes as source nodes for the hash slots.

  Type ‘done‘ once you entered all the source nodes IDs.

Source node #1:b316e00765983941a2f196710e58bdda3db0a9e1

Source node #2:done

这里是将7006所有的slots移到7001

 

 

[[email protected] ~]# redis-trib.rb del-node 127.0.0.1:7006 b316e00765983941a2f196710e58bdda3db0a9e1

>>> Removing node b316e00765983941a2f196710e58bdda3db0a9e1 from cluster 127.0.0.1:7006

>>> Sending CLUSTER FORGET messages to the cluster...

>>> SHUTDOWN the node.

[[email protected] ~]# redis-cli -p 7002 cluster nodes

因为7006节点没有槽位,所以从节点会自动切换主节点(这里会默认签到添加7006主节点时指向的7000

 

3.1.4 重新分片

[[email protected] 7006]# redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7001

>>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7001

>>> Performing Cluster Check (using node 127.0.0.1:7001)

M: c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001

   slots:5430-10729 (5300 slots) master

   1 additional replica(s)

S: ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003

   slots: (0 slots) slave

   replicates dc695ac6c7213817c6d00a5389ee9cd4be48ef1f

S: 43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004

   slots: (0 slots) slave

   replicates a1c455d0d547dbad70ae29d5b7f68069fd8a43e7

M: dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002

   slots:10730-16383 (5654 slots) master

   2 additional replica(s)

S: 9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007

   slots: (0 slots) slave

   replicates c23746303396947204e49c38d7f3d52ade36f2f3

M: a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005

   slots:0-5429 (5430 slots) master

   1 additional replica(s)

S: 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000

   slots: (0 slots) slave

   replicates dc695ac6c7213817c6d00a5389ee9cd4be48ef1f

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

>>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.

[OK] New node added correctly.

 

[[email protected] 7006]# redis-trib.rb reshard 127.0.0.1:7006

>>> Performing Cluster Check (using node 127.0.0.1:7006)

M: 87281a0ed499316a692cab4e0f11c9888c44ab13 127.0.0.1:7006

   slots: (0 slots) master

   0 additional replica(s)

S: 43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004

   slots: (0 slots) slave

   replicates a1c455d0d547dbad70ae29d5b7f68069fd8a43e7

M: c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001

   slots:5430-10729 (5300 slots) master

   1 additional replica(s)

S: 4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000

   slots: (0 slots) slave

   replicates dc695ac6c7213817c6d00a5389ee9cd4be48ef1f

S: 9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007

   slots: (0 slots) slave

   replicates c23746303396947204e49c38d7f3d52ade36f2f3

M: a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005

   slots:0-5429 (5430 slots) master

   1 additional replica(s)

S: ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003

   slots: (0 slots) slave

   replicates dc695ac6c7213817c6d00a5389ee9cd4be48ef1f

M: dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002

   slots:10730-16383 (5654 slots) master

   2 additional replica(s)

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

How many slots do you want to move (from 1 to 16384)? 4096

What is the receiving node ID? 87281a0ed499316a692cab4e0f11c9888c44ab13

Please enter all the source node IDs.

  Type ‘all‘ to use all the nodes as source nodes for the hash slots.

  Type ‘done‘ once you entered all the source nodes IDs.

Source node #1:all

 

[[email protected] 7006]# redis-cli -p 7006 cluster nodes

43042fed29bc840e2fa3e0ae3cc52315cc4f2b9e 127.0.0.1:7004 slave a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 0 1520609776511 14 connected

c23746303396947204e49c38d7f3d52ade36f2f3 127.0.0.1:7001 master - 0 1520609777014 15 connected 6755-10729

87281a0ed499316a692cab4e0f11c9888c44ab13 127.0.0.1:7006 myself,master - 0 0 17 connected 0-1356 5430-6754 10730-12143

4c3e1494e4e6ef6736dc9ff05cfb57928ca63c82 127.0.0.1:7000 slave 87281a0ed499316a692cab4e0f11c9888c44ab13 0 1520609777520 17 connected

9e29060e3cb4393be318a417f59ea243472592dd 127.0.0.1:7007 slave c23746303396947204e49c38d7f3d52ade36f2f3 0 1520609777520 15 connected

a1c455d0d547dbad70ae29d5b7f68069fd8a43e7 127.0.0.1:7005 master - 0 1520609777014 14 connected 1357-5429

ac6daa393979c0ccff0c4f0669fc047fed93f791 127.0.0.1:7003 slave dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 0 1520609778024 16 connected

dc695ac6c7213817c6d00a5389ee9cd4be48ef1f 127.0.0.1:7002 master - 0 1520609778526 16 connected 12144-16383

7006slots槽位可以看出每个节点都平分槽位

 

 

第4章 redis操作命令

获取当前配置

CONFIG GET *

变更运行配置

CONFIG SET loglevel "notice"

 

----

KEYS * 查看KEY支持通配符

 

DEL删除给定的一个或多个key

 

EXISTS 检查是否存在

 

RENAME 变更KEY

 

SORT 键值排序,有非数字时报错

 

TYPE返回键所存储值的类型

 

DUMP RESTORE序例化与反序列化

 

EXPIRE\PEXPIRE 以秒\毫秒设定生存时间

 

TTL\PTTL 以秒\毫秒为单位返回生存时间

 

PERSIST 取消生存实现设置

 

RANDOMKEY 返回数据库中的任意键

 

 

4.1 string(字符串类型)

应用场景

常规计数:微博数,粉丝数等。

 

set mykey "test"    为键设置新值,并覆盖原有值

getset mycounter 0    设置值,取值同时进行,取以前值

setex mykey 10 "hello"   设置指定 Key 的过期时间为10,在存活时间可以获取value

或者

set mykey hello ex 10

setnx mykey "hello"    若该键不存在,则为键设置新值

mset key3  "zyx"  key4 "xyz"   批量设置键

 

del mykey   删除已有键

 

append mykey "hello"   若该键并不存在,返回当前 Value 的长度

               该键已经存在,返回追加后 Value的长度

incr mykey    值增加1,若该key不存在,创建key,初始值设为0,增加后结果为1

decrby  mykey  5    值减少5

setrange mykey 20 dd   把第2122个字节,替换为dd, 超过value长度,自动补0

 

查  

exists mykey      判断该键是否存在,存在返回 1,否则返回0

get mykey     获取Key对应的value

strlen mykey   获取指定 Key 的字符长度

ttl mykey      查看一下指定 Key 的剩余存活时间(秒数)

getrange mykey 1 20   获取第2到第20个字节,20超过value长度,则截取第2个和后面所有的

mget key3 key4    批量获取键

incr

incrby

decr

decrby

 

4.2 hash   ------->缓存数据库对象

hset myhash field1 "s"    

若字段field1不存在,创建该键及与其关联的Hashes, Hashes,keyfield1 ,并设values ,若存在会覆盖原value

hsetnx myhash field1 s    

若字段field1不存在,创建该键及与其关联的Hashes, Hashes,keyfield1 ,并设values, 若字段field1存在,则无效

hmset myhash field1 "hello" field2 "world    一次性设置多个字段

 

hdel myhash field1    删除 myhash 键中字段名为 field1 的字段

del myhash   删除键

 

改  

hincrby myhash field 1   给field的值加1

 

hget myhash field1    获取键值为 myhash,字段为 field1 的值

hlen myhash    获取myhash键的字段数量

hexists myhash field1      判断 myhash 键中是否存在字段名为 field1 的字段

hmget myhash field1 field2 field3   一次性获取多个字段

hgetall myhash    返回 myhash 键的所有字段及其值

hkeys myhash   获取myhash 键中所有字段的名字

hvals myhash   

 

---------------------

hmset

hmget

hetall

----------------------

 

4.3 LIST(列表)

应用场景

 

消息队列系统

 

比如sina微博:

Redis中我们的最新微博ID使用了常驻缓存,这是一直更新的。但是做了限制不能超过5000ID,因此获取ID的函数会一直询问Redis

只有在start/count参数超出了这个范围的时候,才需要去访问数据库。

系统不会像传统方式那样刷新缓存,Redis实例中的信息永远是一致的。

SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取很远的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了

 

lpush mykey a b   若key不存在,创建该键及与其关联的List,依次插入a ,b, 若List类型的key存在,则插入value

lpushx mykey2 e   若key不存在,此命令无效, 若key存在,则插入value

linsert mykey before a a1   在 a 的前面插入新元素 a1

linsert mykey after e e2    在e 的后面插入新元素 e2

rpush mykey a b 在链表尾部先插入b,在插入a

rpushx mykey e   若key存在,在尾部插入e, key不存在,则无效

rpoplpush mykey mykey2    将mykey的尾部元素弹出,再插入到mykey2 的头部(原子性的操作)

 

del mykey       删除已有键

lrem mykey 2 a    从头部开始找,按先后顺序,值为a的元素,删除数量为2,若存在第3,则不删除

ltrim mykey 0 2   从头开始,索引为0,1,23个元素,其余全部删除

 

lset mykey 1 e    从头开始, 将索引为1的元素值,设置为新值 e,若索引越界,则返回错误信息

rpoplpush mykey mykey   将 mykey 中的尾部元素移到其头部

 

lrange mykey 0 -1       取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。

lrange mykey 0 2     从头开始,取索引为0,1,2的元素

lrange mykey 0 0     从头开始,取第一个元素,从第0个开始,到第0个结束

lpop mykey           获取头部元素,并且弹出头部元素,出栈

lindex mykey 6       从头开始,获取索引为6的元素 若下标越界,则返回nil

 

------------

lpush mykey a b

lrange mykey 0 100

------------

 

4.4 Set

应用场景:

案例:?在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。

Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,

你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。

 

sadd myset a b c  

key不存在,创建该键及与其关联的set,依次插入a ,b,key存在,则插入value,a myset中已经存在,则插入了 d e 两个新成员。

 

spop myset   尾部的b被移出,事实上b并不是之前插入的第一个或最后一个成员

srem myset a d f   若f不存在, 移出 ad ,并返回2

 

smove myset myset2 a     将amyset 移到 myset2

 

sismember myset a     判断 a 是否已经存在,返回值为 1 表示存在。

smembers myset     查看set中的内容

scard myset     获取Set 集合中元素的数量

srandmember myset   随机的返回某一成员

sdiff myset1 myset2 myset3   12得到一个结果,拿这个集合和3比较,获得每个独有的值

sdiffstore diffkey myset myset2 myset3   3个集和比较,获取独有的元素,并存入diffkey 关联的Set

sinter myset myset2 myset3    获得3个集合中都有的元素

sinterstore interkey myset myset2 myset3  把交集存入interkey 关联的Set

sunion myset myset2 myset3    获取3个集合中的成员的并集

sunionstore unionkey myset myset2 myset3  把并集存入unionkey 关联的Set

 

---------------------

sadd   myset a b c

sdiff  myset1  myset2    myset3

sinter myset myset2 myset3  

sunion myset myset2 myset3

smembers myset    

scard myset

---------------------------

 

 

4.5 ZADD

应用场景:

排行榜应用,取TOP N操作

这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted setscore,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。

 

zadd myzset 2 "two" 3 "three"    添加两个分数分别是 2 3 的两个成员

 

zrem myzset one two   删除多个成员变量,返回删除的数量

 

zincrby myzset 2 one   将成员 one 的分数增加 2,并返回该成员更新后的分数

 

zrange myzset 0 -1 WITHSCORES   返回所有成员和分数,不加WITHSCORES,只返回成员

zrank myzset one        获取成员oneSorted-Set中的位置索引值。0表示第一个位置

zcard myzset     获取 myzset 键中成员的数量

zcount myzset 1 2    获取分数满足表达式 1 <= score <= 2 的成员的数量

zscore myzset three   获取成员 three 的分数

zrangebyscore myzset  1 2    获取分数满足表达式 1 < score <= 2 的成员

#-inf 表示第一个成员,+inf最后一个成员

#limit限制关键字

#2  3  是索引号

zrangebyscore myzset -inf +inf limit 2 3  返回索引是23的成员

zremrangebyscore myzset 1 2    删除分数 1<= score <= 2 的成员,并返回实际删除的数量

zremrangebyrank myzset 0 1   删除位置索引满足表达式 0 <= rank <= 1 的成员

zrevrange myzset 0 -1 WITHSCORES    按位置索引从高到低,获取所有成员和分数

#原始成员:位置索引从小到大

      one  0  

      two  1

#执行顺序:把索引反转

      位置索引:从大到小

      one 1

      two 0

#输出结果: two  

       one

zrevrange myzset 1 3   获取位置索引,1,2,3的成员

#相反的顺序:从高到低的顺序

zrevrangebyscore myzset 3 0   获取分数 3>=score>=0的成员并以相反的顺序输出

zrevrangebyscore myzset 4 0 limit 1 2  获取索引是12的成员,并反转位置索引

 

-----------------------

ZADD regebang 1000 timian 2000 ssjs

 

zrange regebang 0 -1 WITHSCORES

 

ZREVRANGE regebang 0 -1 WITHSCORES

 

zincrby regebang  10000 timian

 

zincrby regebang  -10000 timian

----------------------------

 

 

 

4.6 消息模式

队列模式(queuing*

 

发布-订阅模式(publish-subscribe)  ****

 

开启两个redis连接

 

redis-cli(1)

SUBSCRIBE chn1

 

redis-cli(2)

publish chn1   hello

 

PSUBSCRIBE

---------------------

redis的事务

 

 

--------------------

***

 

Info

Clinet list

Client kill ip:port

config get *

CONFIG RESETSTAT 重置统计

CONFIG GET/SET 动态修改

Dbsize

FLUSHALL 清空所有数据

select 1

FLUSHDB 清空当前库

MONITOR 监控实时指令

 

SHUTDOWN 关闭服务器

save   将当前数据保存

---------------------------

SLAVEOF host port 主从配置

SLAVEOF NO ONE

SYNC 主从同步

ROLE返回主从角色

-----------------------

以上是关于Redis的主要内容,如果未能解决你的问题,请参考以下文章

RedisRedis 安装启动使用流程

RedisRedis 安装启动使用流程

redisredis知识点总结

redisredis知识点总结

RedisRedis高级

RedisRedis简述