数据类型:

  • 字符串(支持整型、浮点数等)
  • 列表
  • 集合
  • 散列
  • 有序集合

跳跃表

是sortset底层实现,4层链表,加速查找速度。

持久化方式:

  • 快照(一个时间的副本)
  • AOF(记录命令)

缓存穿透

  • 是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
    解决办法是缓存空对象. 将 null 变成一个值.

  • 如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。解决办法是加锁排队。

redis数据淘汰机制

  • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用 的数据淘汰
  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数 据淘汰
  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据 淘汰
  • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  • no-enviction(驱逐):禁止驱逐数据

Redis为何快速

1.纯内存访问:Redis将所有的数据放在内存中,读取不涉及磁盘,0次IO,内存的响应时间约为100纳秒,是快速存取最主要的原因。
2.单线程:Redis使用单线程避免了线程切换和加锁释放锁带来的消耗,但由此增加了阻塞的风险,因此快速执行场景的数据库适合用Redis。
3.非阻塞多路I/O复用机制:Redis使用epoll作为I/O多路复用技术的实现,而且Redis将epoll的read,write,close操作转换成事件,不在网络I/O上耗费太多时间,实现对多个FD的读写,提高性能。

常见应用:

  • 最新日志 lpush 列表
  • 常见日志 有序集合
  • 计数器 有序集合
  • IP zrevrangebyscore ip_to_score算法
  • 自动补全 list
  • 通讯录自动补全 有序集合,score=0, member根据a-z排序
  • 分布式锁 setnx
  • 计数信号量 有序集合
  • 消息拉取 群组、用户、zset

redis一致性问题

Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作:第一个原因是因为集群是用了异步复制. 写操作过程:

  • 客户端向主节点B写入一条命令.
  • 主节点B向客户端回复命令状态.
  • 主节点将写操作复制给他得从节点 B1, B2 和 B3

数据分片

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。

如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。

主从复制

为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)

选主

当有n个节点标记master为主观下线时,master被标记为客观下线,这个时候sentinel集群会发起一次领头选举,raft协议,由选出的领头进行故障转移,把一个复制偏移量最大的从节点提升为master,然后通过发布订阅的形式通知客户端切换ip。

redis主从同步

  • 分为sync, psync(部分重同步)。根据复制offset和复制积压缓冲区、服务器运行ID判断是部分复制还是完整复制。优点是提高复制效率,不用每次都全部复制。以前的不能高效地处理断线后重复制的情况。

  • 主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从一致。而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测

redis的渐进式rehash

rehash期间,每次对字典执行添加、删除、查找或者更新操作时,程序除了执行指定的操作以外,还会顺带将ht[0]哈希表在rehashidx索引上的所有键值对rehash到ht[1]