赞
踩
类型 | 数据结构 | 数据结构间转化条件 | 备注 |
string | int | 整数值 | |
embstr | 字符串(长度<=39byte) | y?底层都是SDS(simple dynamic string,简单动态字符串)实现,但raw需要分配两次内存(redisObject和sdshdr),embstr只需要一次 | |
raw | 字符串(长度>39byte) | ||
list | ziplist | 压缩列表:每个字符串元素的长度<64byte且元素数量<512 | |
linkedlist | 双端列表:不满足压缩列表条件,则使用双端列表 | ||
hash | ziplist | 压缩列表:所有键值对的字符串长度<64byte且键值对数量<512 | |
hashtable | 字典:不满足压缩列表条件,则使用字典 | ||
set | intset | 整数集合:所有元素都是整数值且元素数量<512 | |
hashtable | 字典:不满足整数集合条件,则使用字典 | ||
zset | ziplist | 压缩列表:所有元素长度<64byte且元素数量<128 | |
skiplist+ hashtable | 跳跃表+字典:不满足压缩列表条件,则使用跳跃表+字典 |
redis6.0之后开始引入多线程,可选择性使用多线程模型,Redis的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。
Redis选择使用单线程模型处理客户端的请求主要还是因为CPU不是Redis服务器瓶颈,所以使用多线程模型带来的性能提升并不能抵消他带俩的开发成本和维护成本,系统的性能瓶颈主要在网络I/O操作上;而Redis引入多线程操作也是出于性能考虑,对于一些大键值对的删除操作,通过多线程非阻塞地释放内存空间也能减少对Redis主线程阻塞的时间,提高执行效率。
过期策略 | 实现方式 | 备注 |
惰性删除策略 | 所有读写操作,在执行前都会调用expireIfNeeded函数对键进行检查,过滤掉已过期的键,避免命令接触到过期键。 | 两种策略相互配合,在合理使用CPU时间和避免浪费内存空间之间取得平衡. |
定期删除策略 | 周期性执行redis.c/serverCron,每次运行都从一定数据量的数据库中取出一定数量的随机减进行检查,并删除其中的过期键 |
淘汰策略 | 实现方式 | 备注 |
noeviction(默认策略) | 不删除策略。达到最大内存限制时,如果需要更多内存,直接返回错误信息。 | |
allkeys-lru | 所有key通用,优先删除最近最少使用(LRU:less recently used)的key。适用场景:数据分热数据与冷数据。最常用的。 | |
volatile-lru | 只限于设置了expire的部分,优先删除最近最少使用的key。 | |
allkeys-random | 所有key通用,随机删除一部分key。适用场景:所有元素的概率差不多。 | |
volatile-random | 只限于设置了expire的部分,随机删除一部分key。 | |
volatile-ttl | 只限于设置了expire的部分,优先删除剩余时间(TTL:time to live)短的key。 | |
volatile-lfu | LFU (Least frequently used) 最不经常使用,如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。 | redis4.0 |
allkeys-lfu |
如果定期删除漏掉了很多过期key,这些key也没有及时去查,也就没走惰性删除,大量key堆积在内存,导致redis内存快耗尽了,这种情况会走上面的淘汰策略。
类型 | 触发条件 | 存储方式 | 载入方式 | 对过期键的处理 | 使用场景(优缺点) | 备注 |
RDB | Save 900 1 服务器900s之内,对数据库进行了至少1次修改 Save 300 10 服务器300s之内,对数据库进行了至少10次修改 Save 60 10000 服务器60s之内,对数据库进行了至少10000次修改 | 可以简单理解为将某时刻的数据按固定的数据结构存储下来 | 解析数据结构,还原当时数据库状态 | 存储的是数据结构,存储/载入时,忽略过期键 | AOF与RDB同时开启情况下,会优先使用AOF,因为AOF更新频率高。 只有在AOF没有开启的情况下,才会使用RDB来还原数据库状态。 (RDB-AOF混合持久化格式-reidis4.0) | |
AOF | always:服务器在每次事件循环都将aof_buf缓冲区中的所有内容写入到AOF文件,并且同步AOF文件 everysc:服务器在每次事件循环都将aof_buf缓冲区中的所有内容写入到AOF文件,并且每隔一秒子线程同步AOF no:服务器在每次事件循环都将aof_buf缓冲区中的所有内容写入到AOF文件,同步时机由操作系统控制 | 通过记录所有执行的写命令 (顺序写,效率很高) | 将命令重新执行一遍 | 存储时,无影响; 载入时,显式追加删除过期键的del命令 | AOF重写机制 |
类型 | 实现方式 | 图示 | 适用场景 | 备注 |
完整重同步 | SLAVE -> MASTER : 发送SYNC命令 MASTER -> SLAVE :发送RDB文件 MASTER -> SLAVE :发送缓存区所有写命令 | 1、从服务器初始化 2、服务器断线时间较长的重连场景 | 非常耗资源 1、生成RDB文件,耗费主服务器大量CPU、内存、磁盘I/O资源 2、接受RDB文件,处理RDB文件,无法处理命令请求 | |
部分重同步 | MASTER -> SLAVE :同步数据时,同时同步复制偏移量 SLAVE -> MASTER :将从服务器的复制偏移量,传给主服务器 MASTER -> SLAVE : 将复制偏移量往后的数据,传给从服务器(复制偏移量仍然在复制积压缓冲区中-默认1MB,否则执行完整重同步) | 1、主从同步 2、服务器断线重连 | 脑裂(min-slaves-to-write 2、min-slaves-max-lag 5) |
Redis集群通信采用Gossip协议,简单讲:各个服务器平等关系无主从,集群节点信息变更会不断地发送给其他节点。
优点:元数据信息分散,更新压力小
缺点:更新延迟
meet | 某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信。 | |
ping | 每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据。 | |
pong | 返回ping和meet,包含自己的状态和其他信息,也用于信息广播和更新。 | |
fail | 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点说:某个节点宕机了。 |
其他通信协议,如: 集中式(zookeeper)
Redis采用hash slot算法:
16384个hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot。
比如3个master,每个持有5000多个hash slot,任何一台机器宕机,另外两个节点不受影响,因为key找的是hash slot,不是机器。
客户端api可以对指定的数据,让他们走同一个hash slot,通过 hash tag 来实现。
其他寻址方式,如:hash算法、一致性hash算法
集群中的每个节点都会定期地向集群中其他节点发送ping消息,来检测对方是否在线,如果接受ping消息的节点没有在规定时间内返回pong消息,则该接受ping消息的节点标记为疑似下线pfail。
如果在一个集群中,半数以上负责处理槽的主节点都将某个主节点x标记为疑似下限,那么这个主节点x将被标记为已下线,将主节点x标记为已下线的节点会向集群广播一条关于主节点x的fail消息,所有收到这条fail消息的节点都会立即将主节点x标记为已下线。
复制下线主节点的所有从节点里面,会有一个从节点被选中。
被选中的从节点会执行SLAVE OF no one命令,成为新的主节点。
新的主节点会撤销所有对已下线的主节点的槽指派,并将这些槽全部指派给自己。
新的主节点向集群广播一条PONG消息,这条PONG消息可以让集群中的其他节点立即知道这个节点已经由从节点变成了主节点,并且这个主节点已经接管了原本由已下线节点负责处理的槽。
新的主节点开始接收和自己负责处理的槽有关的命令请求,故障转移完成。
集群的配置纪元是一个自增计数器,它的初始值为0。
当集群里的某个节点开始一次故障转移操作时,集群配置纪元的值会被+1。
对于每个配置纪元,集群里每个负责处理槽的主节点都有一次投票的机会,而第一个向主节点要求投票的从节点将获得主节点投票。
当从节点发现自己正在复制的主节点进入已下线状态时,从节点会向集群广播一条CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到这条消息、并且有投票权的主节点向这个从节点投票。
如果一个主节点具有投票权(它正在负责处理槽),并且这个主节点尚未投票给其他的从节点,那么主节点将向要求投票的从节点返回一条CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点支持从节点成为新的主节点。
每个参与选举的从节点都会接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持。
如果集群里有N个具有投票权的主节点,那么当一个从节点收集到大于等于N/2+1张支持票时,这个节点就会当选为新的主节点。
因为在每一个配置纪元里面,每个具有投票权的主节点只能投一次票,所以如果有N个主节点进行投票,那么具有大于等于N/2+1张支持票的从节点只会有一个,这确保了新的主节点只会有一个。
如果在一个配置纪元里面没有从节点能收集到足够多的支持票,那么集群进入一个新的配置纪元,并再次进行选举,直到选出新的主节点为止。
复制时间靠前
offset越大
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。