redis数据结构 :
string:
set key,value ,set key value ex time
map
所有的键值对的键和值的长度都小于等于64byte,哈希对象保存的键值对数量都小于512:ziplist,hashtable 对象
list
quicklist 消息队列
set
inset:如果元素类型都是整型,并且元素个数不小于512,hashtab,点赞,互相关注
zset
元素数量小于128,所有member的长度小于64字节使用ziplist,否则升级为skiplist,热点排序 ,有一个score
redis常用命令
list
lpush:左插入数据
lpushx:做插入数据, 前提条件是key存在并且key为列表
rpush:右插入
rpushx:右插入, 前提条件是key存在并且key为列表
rpop:右弹出
lpop:左弹出
lrange:弹出一个范围内的数据
blpop:左阻塞式的弹出
brpop:右阻塞式的弹出
set
1、set:sadd添加,spop删除,smembers 查看所有元素,sinter交集,sunion合集,sdiff差集
map
zset
string
redis热点数据:
1、客户端统计的方式
2、代理层:TwemProxy或 Codis
3、服务端统计:monitor监控,但是只能监控到一个节点
4、机器层面:抓包的形式
redis查看内存使用信息:
info memory
Redis主从复制
master node 第一次执行全量复制,通过bgsave命令在本地生成一份RDB文件,将RDB快照文件发送给slave节点,slave node 会先清空自己的旧数据,然后从RDB文件中加载数据。
在生成rdb文件中,master node 如果接收到新的写命令怎么办?
master会把所有的新的写命令缓存在内存中,在slave node 保存了RDB文件之后,再讲新的命令复制给slave node
主从复制的不足:
1、当RDB文件过大时同步非常耗时
2、在一主多从情况下,当master node 挂了后。对外服务就不可用了,单点问题并没有解决。如果每次都手动把之前的服务器切换为主服务器,这就比较费力。
可用性保证之sentinel
sentinel是一个监听,监听redis集群中的master和slave,如果master一定时间内没有给sentinel回复消息,则将master标记为下线,然后把某一个slave标记为master,应用每一次都从这个监控服务器拿到master的地址。
sentinel通过info命令来获取到redis集群中的节点的信息。
服务下线:当sentinel监听到master节点下线后,会进行故障转移
故障转移:故障转移的第一步就是在sentinel集群中选举出一个leader节点,然后让这个leader指定出一个master节点。
sentinel集群选举算法
类似raft算法。raft算法:首先会生成一个150-300ms的时间,默认最小时间的为leader,如果时间一样则再次生成时间。
1、master客观下线会触发选举,而不是过了时间才会
2、leader并不会把自己成为leader的信息发送给其他sentinel节点。其他sentinel等待leader从slave选举出master后,检测新的master节点正常运行后,就会去掉客观下线的标识,从而不需要进入故障转移流程。
sentienl根据什么来指定master节点:
1、断开连接时间:如果与哨兵连接断开时间过长,超过了某个阈值,就直接失去了选举权,
2、优先级:如果拥有了选举权,那就判断谁的优先级更高,数值越小优先级越高
3、复制数量:如果优先级也一样,就判断谁从master节点中复制的数据最多。
4、进程id:如果复制数量一样,就选择进程id最小的那个。
哨兵机制的不足:
主从切换中会丢失数据,因为只有一个master,salve节点 的数据使用RDB文件复制的。
只能单点写,没有解决扩容的问题
如果数据量过大,我们就需要多个master-slave的group
redis数据的分片
客户端实现
客户端根据key进行hash计算,来进行分片。
ShardedJedis
代理层
将分片逻辑提取出来,运行一个独立的代理服务,客户端连接到这个代理服务,代理服务做请求转发。
Twemproxy,Codis
服务层
Redis Cluster