redis复习草稿

183 阅读6分钟

数据结构 string 字符串 编码 int 8字节的整数 embstr 39字节以下的字符串 raw39字节以上的字符串 应用: 计数、存储召回数据正排数据等等。 项目中使用string存储召回数据。按照前缀+比如说mddID、poiId 、openudid等方式存储。value为每个itemId以逗号分割。利用的raw编码格式。39字符以上使用该编码格式。

string实现是SDS。其中包含了已占用长度。空余长度。字符数组。这样的设计会使string查询len为o1 空余长度动态调整的情况避免扩容的频繁。扩容后不缩容。留给过期时间等操作释放内存。1M以下扩2倍,1M以上扩1M

hash 哈希 底层:ziplist 512个元素以下,64个字节 hashtable 应用: 存储需要改变的json。 排序特征数据之前存放在hash结构中。key为每个itemId加前缀命名。里面的键值对是特征名称与特征值。但后续我们在做优化的时候想到用堆外缓存做排序的item离线特征的存储。现在不用hash结构了。堆外耗时较低。纳秒级别。实时特征是利用消费kafka来更新堆外缓存中。 ziplist 头部信息,实体信息,尾部信息。 头部信息:存放了整个ziplist所占用字节。实体最后一位的偏移量,实体个数。尾部信息255 实体信息存放了实体+上一个实体的字节大小,编码格式。 hashtable分为两个ht数组。数组存放每一个桶。每个桶对应key的hash的存放点。两个ht用处扩容,当扩容时,会利用ht1作为扩容后的数据进行。渐进性的将ht0的数据从新hash放到ht1中。再将ht0=ht1。ht1清理。

list 列表 底层: ziplist 512个元素,64字节 linkedlist 应用:消息队列、栈 双端ziplist

set 集合 底层: intset 512 hashtable

zset 有序集合 底层: ziplist 128 64 skiplist 用于时间区间行为数据。 利用zset存储7天内用户的行为数据。曝光。利用zrevrange查询区间。这个数据是提供给排序作为线上特征处理。 skiplist是解决快速顺序查询替代平衡树的一种数据结构,平衡树左旋右旋来进行平衡,复杂度较高。skiplist将元素随机设置层级关系。并按照顺序存储。这样我们可以利用类似二分方式查找。降低时间复杂度。

bitmap 存储小量数据。快。可以存储日活。

hyperloglog基数, 可以花费12k内存 存2^64的不同元素基数。应用: 流量统计,计算pv uv。

rdb: rdb分为两种方式。阻塞当时save 非阻塞方式bgsave。非阻塞是利用父进程fork一个子进程。子进程获取fork之前的数据进行写文件。进程没锁。时间可以配置。rdb会启用一个时间调度方式检查save 900 save 比aof恢复快,可能会少数据。 aof:利用命令直接存储。后台。aof会将数据先写到缓存中,等待刷盘。重写:当数据量较多时,有些key已经删除或过期。所以会重写aof文件。

为什么redis快:1.数据结构。编码方式。例如SDS 设计模式:Reactor。利用多路复用监听socket,将socket信息传递给命令分派器,利用分派器提交给不同的命令处理器进行执行。

单线程。避免上下文切换。和锁的操作。

基于内存。

主从复制: 建立连接阶段:

  1. 保存主节点信息。 host ip port
  2. 建立连接: socket连接建立。异步,返回ok但不是已经复制成功了。
  3. ping检测socket是否建立成功。
  4. 身份验证。
  5. 发送信息。 数据同步阶段:
  6. sync/psync 全量复制 : 主节点bgsave产生RDB文件。将RDB文件传给从节点。并建立一个复制缓冲区,将写入命令放到缓冲区。(队列)从节点接收RDB文件后,清理旧数据。写新数据。将数据库状态同步给主节点。主节点将缓冲区的数据发送给从节点。如果设置AOF会进行重写AOF文件

部分复制 : 主节点与从节点各自维护一个offset。主节点发送给从节点的字节数,如果两个offset相等。说明同步没问题。若不等。会根据差值和起始值在复制缓冲区进行部分复制。复制缓冲区是主节点维护的一个队列。用于命令传播。 网络连接失败: 重连。如果重连成功发现offset差距在缓冲区范围内。则部分复制。 否则全量复制

哨兵模式: 建立sentinel进行检测master是否下线。每10秒ping一下master,如果master超过时间,其他sentinel进行check如果大部分超时认为客观下线。

当master被认为客观下线后, sentinel集群会选举一个leader进行故障转移。raft算法选举。 故障转移:排查大于超时的从节点。剩余列表中获取从节点的offset大小。大的为master 或者id最小。

集群: redis集群模式是利用分片方式存储数据。会将数据分成16384个槽中。部分槽分到不同的master。至少3台。利用crc16将key进行分槽。

选举: 当slave发现master已经挂了。会通知其他节点master,其他节点master会反馈第一个通知到的节点。当该slave获得master的通知数量多余半数,转换为master并通知其他节点不需要选举了。

事务: 利用multi开启事务。 事务是指都执行或都不执行。利用exec提交。redis事务不支持回滚。可以利用watch监控一个key。当想回滚时将改变改key进行取消事务。

LUA

回收策略: 惰性删除 + 定期删除 查询到key发现过期时间已过。删除。 + 10 秒循环检测

内存溢出: OOM LRU淘汰不常用的key 利用lrulru设置了过期时间的key中lru 随机清理key 随机清理设置过期的key。 清理最快过期的key。

缓存穿透: 大量请求不存在的key。 设置key缓存。布隆过滤器。将key算hash。

缓存雪崩。

大量key失效。 随机失效。 热点key设置永不过时。

缓存击穿: 大量请求热点key,当热点key失效。很多请求打到db上。 互斥锁:只有一个请求打在DB上。