第1章 redis缓存技术
1.1 Redis的定义
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,php,javascript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。[1] Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。 |
1.2 数据结构
redis提供五种数据类型:string,hash,list,set及zset(sorted set)。
1.2.1 string(字符串)
string是最简单的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。 redis采用结构sdshdr和sds封装了字符串,字符串相关的操作实现在源文件sds.h/sds.c中。 数据结构定义如下: typedefchar*sds; structsdshdr{ longlen; longfree; charbuf[]; }; |
1.2.2 list(双向链表)
list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中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; dict中table为dictEntry指针的数组,数组中每个成员为hash值相同元素的单向链表。set是在dict的基础上实现的,指定了key的比较函数为dictEncObjKeyCompare,若key相等则不再插入。
|
1.2.4 zset(排序set)
zset是set的一个升级版本,他在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得到数据,序列化的操作包括SET、RPUSH、SADD、ZADD。 redis的存储分为内存存储、磁盘存储和log文件三部分,配置文件中有三个参数对其进行配置。 save seconds updates,save配置,指出在多长时间内,有多少次更新操作,就将数据同步到数据文件。这个可以多个条件配合,比如默认配置文件中的设置,就设置了三个条件。 appendonly yes/no ,appendonly配置,指出是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面的save条件来同步的,所以有的数据会在一段时间内只存在于内存中。 appendfsync no/always/everysec ,appendfsync配置,no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次。 |
1.4 redis与memcache的区别
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支持的数据类型要丰富得多。最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted 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启动脚本 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
配置6381、6382节点 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 从节点:6381、6382
开启主从: 登入6381、6382,命令行: [[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代表判断主节点失败至少需要2个Sentinel节点节点同意 // 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] 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 kill掉7000进程号 [[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和端口
从任何一个主节点里面划分部分slots给7006 [[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? 此处填写接收节点ID号 7006的槽位 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表示从老的所有节点进行重分配,凑够4096个slots给到新节点.也可以输入源节点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.我们现在来删除7006 这个节点.首先,我们要把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 从7006的slots槽位可以看出每个节点都平分槽位
|
第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 把第21和22个字节,替换为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中,key为field1 ,并设value为s ,若存在会覆盖原value hsetnx myhash field1 s 若字段field1不存在,创建该键及与其关联的Hashes, Hashes中,key为field1 ,并设value为s, 若字段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使用了常驻缓存,这是一直更新的。但是做了限制不能超过5000个ID,因此获取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,2的3个元素,其余全部删除
改 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不存在, 移出 a、d ,并返回2
改 smove myset myset2 a 将a从 myset 移到 myset2,
查 sismember myset a 判断 a 是否已经存在,返回值为 1 表示存在。 smembers myset 查看set中的内容 scard myset 获取Set 集合中元素的数量 srandmember myset 随机的返回某一成员 sdiff myset1 myset2 myset3 1和2得到一个结果,拿这个集合和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 set的score,将具体的数据设置成相应的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 获取成员one在Sorted-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 返回索引是2和3的成员 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 获取索引是1和2的成员,并反转位置索引
----------------------- 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返回主从角色 ----------------------- |