Redis入门、安装、配置、命令、数据类型、集群模式
Redis 是一个高性能的key-value内存数据库。
1、yum安装
yum install -y gcc
tar -xvf redis-5.0.3.tar.gz
make && make install PREFIX= redis-server redis.conf
在特定端口上启动redis服务
redis-cli --cluster help
客户端带参数连接
redis-cli [command] 例如:redis-cli shutdown 或者 redis-cli info
杀死全部带有redis关键字的进程
$ pkill redis
Redis的数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(有序集合)。
1、string
string是最常用的数据类型
设置一个键值对
SET key value
获取一个键的值
GET key
使一个键的值自增1,若键不存在新增键值为1
INCR key
使一个键的值自减1,若键不存在新增键值为-1
DECR key
使一个键的值自增value,若键不存在新增键值为value
INCRBY key value
使一个键的值自减value,若键不存在新增键值为-value
DECRBY key value
设置多个键值对
MSET key1 value1 key2 value2 ...
获取多个键的值
MGET key1 key2 ...
2、hash
指令前缀H-
向哈希表中加入一个属性值
HSET key field value
获取哈希表中一个属性的值
HGET key field
向哈希表中加入多个属性值
HMSET key field1 value1 field2 value2 ...
获取哈希表中多个属性的值
HMGET key field1 field2 ...
3、 list
指令前缀L-或R-,事实上它是个阻塞双端队列
从列表的头部插入一个或多个值,批量插入时每一个都从头部插入会得到[... value2] value1
LPUSH key value1 [value2 ...]
从列表的头部插入一个或多个值
RPUSH key value1 [value2 ...]
立即从列表头部弹出一个元素,不存在则返回nil
LPOP key
立即从列表尾部弹出一个元素,不存在则返回nil
RPOP key
阻塞弹出列表头部一个元素,直到有元素可弹出或等待超时,超时设置为0则一直阻塞
BLPOP key timeout
阻塞弹出列表尾部一个元素
BRPOP key timeout
获取列表指定范围内的元素
LRANGE key start stop
裁剪列表保留指定范围的元素
LTRIM key start stop
4、set
指令前缀S-
向集合中添加一个或多个成员
SADD key member1 [menber2 ...]
返回集合中的全部成员
SMEMBERS key
从集合中移除一个或多个成员
SREM key member1 [menber2 ...]
返回两个集合的差集
SDIFF key1 key2
返回两个集合的交集
SINTER key1 key2
返回两个集合的并集
SUNION key1 key2
判断menber是否为集合中的成员
SISMEMBER key member
5、zset
指令前缀Z-
向有序集合中添加成员,若成员存在则更新score
ZADD key score1 member1 [score2 member2 ...]
按score从小到大的顺序返回score排名在[start,stop]区间集合成员[返回score]
ZRANGE key start stop [WITHSCORES]
按score从大到小的顺序返回score排名在[start,stop]区间集合成员[返回score]
ZREVRANGE key start stop [WITHSCORES]
从集合中移除一个成员
ZREM key member
使集合中一个成员score自增incrment,若成员不存在则新增成员score为increment
ZINCRBY key incrment member
EX 秒为单位的过期时间;PX毫秒为单位的过期时间;NX键不存在时;XX键存在时
Redis的应用场景
缓存
将数据库的查询结果放入redis,最常用
阻塞队列
list的BLPOP(操作简单,但ack需要自己实现)
新闻列表
list的LPUSH放入新数据,LTRIM或者RPOP将旧数据移除,LRANGE查询指定范围
计数器
string的INCR可实现计数器,加入过期时间还可以让计数定期清零
TOP N
zset的ZINCRBY可实现热点排名
Redis高可用
redis主从复制
redis.conf中写入slaveof <masterip> <masterport> 即可,redis在启动时即可作为从服务器去同步主服务器的数据
Sentinel 集群
在主从复制的基础上增加哨兵进程来监控master状态并实现主从自动切换,启动多个哨兵来监控同一个redis的master进程就构成了一个哨兵集群。
redis-sentinel.conf的配置
sentinel monitor mymaster 127.0.0.1 6379 2
master-name ip port quorum
*quorum干掉一个master需要的票数
Sentinel的工作原理
每个Sentinel以每秒钟一次的频率向它所知的Master、Slave以及其他Sentinel实例发送一个PING命令。
如果一个实例距离最后一次有效回复PING命令的时间超过down-after-milliseconds选项所指定的值,则这个实例会被Sentinel标记为主观下线。
如果一个Master被标记为主观下线,则正在监视这个Master的所有Sentinel要以每秒一次的频率确认Master的确进入了主观下线状态。
当有足够数量(quorum)的Sentinel在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线。
在一般情况下,每个Sentinel会以每10秒一次的频率向它已知的所有Master,Slave发送INFO命令。
当Master被Sentinel标记为客观下线时,Sentinel向下线的Master的所有Slave发送INFO命令的频率会从10秒一次改为每秒一次。
若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。若Master重新向Sentinel的PING命令返回有效回复,Master的主观下线状态就会被移除。
Cluster 集群
redis cluster集群启动要求至少有6个节点(3主3从)
cluster集群搭建
早期版本
$ redis-trib.rb create --replicas <num> host1:port1 ... hostN:portN
最新版本
echo "redis-server --port $1 --daemonize yes --cluster-enabled yes --cluster-config-file nodes-$1.conf" > redis-with-port
./redis-with-port 6379 && ./redis-with-port 6378 && ./redis-with-port 6377 && ./redis-with-port 6376 && ./redis-with-port 6375 && ./redis-with-port 6374
REDIS_HOME/utils/create-cluster中有一个create-cluster的脚本,这个脚本会在30001-30006端口上启动6个redis实例,并将他们创建为3主3从的集群模式。
REDIS_HOME/utils/create-cluster
$ ./create-cluster start && ./create-cluster create
当然自己动手写的话更容易理解到底执行了些什么。
集群
redis cluster采用无中心结构,节点间使用gossip协议进行通信。每个节点保存数据和所有节点和槽的映射关系。
哈希槽slot
在redis cluster中使用16834个slots来存储一定范围内的数据集。每个redis节点上有一定数量的槽。当客户端提交数据时,要先计算出数据要落到哪个虚拟槽内。
故障检测
集群中的每一个节点每经过一段时间都会向其他节点发送PING消息,如果没有在规定时间内收到回复,则将该节点标记为疑似下线。当集群中过半数的节点将某节点标记为疑似下线,则该节点会被标记为下线,做出此裁定的节点或发送一条广播,任何收到广播的节点也将此节点标记为下线。
选举机制
当从节点收到自己跟随的主节点故障的广播后,该从节点会根据rank和offset加上一个随机数来计算一个短暂延时,之后该节点会将自己的epoch+1,并发送一条广播要求其他主节点进行投票,投票者判断会比较自身与投票发起者的epoch来决定是否投票,若投票则在同一个选举周期内投票者不会在为相同的epoch投票。当发起投票的从节点收到大于master半数时,自身成为master。
故障恢复
当一个从节点升级为主节点后,接管前任管理的slots,接管前任的其他从节点,发送一条广播通知集群自己已经接管前任,将集群的epoch设置为自己的epoch。
注意:Cluster对于同时处理多个键的命令,如果所有键在同一个slot则能够执行,否则将不能执行。
网友评论